Linux内核MTD驱动程序与SD卡驱动程序(6)

2019-03-29 16:54

if (mtdblk->cache_state != STATE_DIRTY) return 0;

ret = erase_write (mtd, mtdblk->cache_offset, mtdblk->cache_size, mtdblk->cache_data);

if (ret)

return ret;

mtdblk->cache_state = STATE_EMPTY; return 0; }

函数erase_write写一扇区数据到设备中,写的方法是:先擦除对应扇区,擦除完成后,再写数据。函数erase_write分析如下:

static int erase_write (struct mtd_info *mtd, unsigned long pos, int len, const char *buf) {

struct erase_info erase;

DECLARE_WAITQUEUE(wait, current); wait_queue_head_t wait_q; size_t retlen; int ret;

//首先,擦除flash闪存块

init_waitqueue_head(&wait_q); erase.mtd = mtd;

erase.callback = erase_callback; erase.addr = pos; erase.len = len;

erase.priv = (u_long)&wait_q;

set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&wait_q, &wait);

ret = MTD_ERASE(mtd, &erase); if (ret) {//如果擦除完成

set_current_state(TASK_RUNNING);//运行当前进程 remove_wait_queue(&wait_q, &wait);//清除等待队列 return ret; }

schedule(); //调度来等待擦除工作的完成

remove_wait_queue(&wait_q, &wait); //清除等待队列 //第二步,写数据到flash设备 ret = MTD_WRITE (mtd, pos, len, &retlen, buf);

if (ret)

return ret; if (retlen != len) return -EIO; return 0; }

函数mtdblock_readsect调用了函数do_cached_read,从flash设备中读数据到指定位置的buf中,如果数据在设备的缓存中,就直接从缓存中拷贝到buf中,如果不在,就从flash中读出到buf中。函数do_cached_read说明如下: static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, int len, char *buf)

其中参数mtdblk是指定的MTD块设备,pos是MTD设备中指定的位置,len是长度,buf是被写入的地址,调用成功时返回0,失败时返回错误码。函数从指定的MTD块设备中缓冲读到指定位置buf中。

MTD核心初始化

MTD核心主要工作是进行电源管理及在/proc文件系统中输出MTD设备的信息。函数init_mtd初始化proc文件系统函数、注册电源管理函数、初始化mtd设备函数,清除模块函数做相反的一些清除工作。

函数init_mtd分析如下(在linux/drivers/mtd/mtd_core.c中): int __init init_mtd(void) {

if ((proc_mtd = create_proc_entry( “mtd”, 0, 0 ))) proc_mtd->read_proc = mtd_read_proc;

mtd_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, mtd_pm_callback); return 0; }

static void __exit cleanup_mtd(void) {

if (mtd_pm_dev) {

pm_unregister(mtd_pm_dev); mtd_pm_dev = NULL; }

if (proc_mtd)

remove_proc_entry( “mtd”, 0); }

mtd_read_proc函数是proc系统调用到的最终读函数,它以字符形式读出结构struct mtd_info相关信息。

mtd_pm_callback函数通过各个设备的MTD设备结构mtd_info将电源管理请求传给具体的设备驱动程序。mtd_pm_callback函数列出如下:

static int mtd_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) {

int ret = 0, i;

if (down_trylock(&mtd_table_mutex)) return -EAGAIN;

if (rqst == PM_SUSPEND) {//电源挂起状态

for (i = 0; ret == 0 && i < MAX_MTD_DEVICES; i++) { if (mtd_table[i] && mtd_table[i]->suspend)

ret = mtd_table[i]->suspend(mtd_table[i]); }

} else i = MAX_MTD_DEVICES-1;

if (rqst == PM_RESUME || ret) {//电源恢复

for ( ; i >= 0; i--) {

if (mtd_table[i] && mtd_table[i]->resume) mtd_table[i]->resume(mtd_table[i]); } }

up(&mtd_table_mutex); return ret; }

MTD字符设备

当系统打开flash设备上的文件,它建立好了文件的操作函数集实例,当对文件操作时,就调用了这个文件操作函数集实例中的函数。当flash设备当作字符设备时,这些操作函数通过MTD设备的操作函数把数据直接读入/写出flash设备。 函数init_mtdchar注册了一个字符设备,列出如下(在drivers/mtd/mtdchar.c中):

static int __init init_mtdchar(void) {

if (register_chrdev(MTD_CHAR_MAJOR, “mtd”, &mtd_fops)) { printk(KERN_NOTICE “Can’t allocate major number %d for Memory Technology Devices.\\n”, MTD_CHAR_MAJOR); return -EAGAIN; }

mtdchar_devfs_init(); return 0; }

MTD字符设备的操作函数结构mtd_fops列出如下: static struct file_operations mtd_fops = {

.owner .llseek

= THIS_MODULE, = mtd_lseek,

};

.read .write .ioctl .open .release

= mtd_read, = mtd_write, = mtd_ioctl, = mtd_open, = mtd_close,

这里只分析了mtd_write函数,函数mtd_write完成此函数是对MTD字符设备的写操作。其中参数file是系统给MTD字符设备驱动程序用于传递参数的file结构,函数mtd_write通过file得到下层的MTD设备结构,参数buf是用户空间的指针,用于存放将要写入的数据,参数count是被写数据的长度,参数ppos是数据被写入MTD设备中的位置。当调用成功时返回返回实际读取数据的长度,若失败时返回错误码。 函数mtd_write分析如下:

static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos) {

struct mtd_info *mtd = file->private_data; //得到MTD设备结构 char *kbuf; size_t retlen;

size_t total_retlen=0; int ret=0; int len;

DEBUG(MTD_DEBUG_LEVEL0,”MTD_write\\n”); if (*ppos == mtd->size) return -ENOSPC;

if (*ppos + count > mtd->size) count = mtd->size - *ppos;

if (!count) return 0; while (count) {


Linux内核MTD驱动程序与SD卡驱动程序(6).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:出色的主持

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: