Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15478
  • 博文数量: 3
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 55
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-12 16:59
文章分类
文章存档

2013年(3)

我的朋友

分类: LINUX

2013-04-27 12:25:10

原文:http://fpcfjf.blog.163.com/blog/static/5546979320111130102556128/
MTD子系统学习1—MTD子系统的系统流程


从开始看这个MTD就费了很多的心思,先声明一下,使用的LINUX的内核是linux2.6.32,不同的内核,其的一些流程还是有一些细节的不同的(比如nand_read函数调用的过程-----有些版本是调用nand_do_read_ecc()),在这上面因为是看网上的资料所以走了不少的弯路。所以在下面的系列学习中会不断的进行说明,希望引起大家的注意。

另外一个需要澄清的是在高版本的内核里,MTD中NAND使用的是mtd_info
nand_chip两个结构体来配合,
而NORFALSH使用 mtd_info
mtd_table两个结构体配合,初学者一定要注意,很多的网上的老版本的这方面说得不是很清楚,容易引起大家的误解。

先从宏观上把握一下MTD系统,重点讲一下整个系统的流程和函数相互调用的过程以及相互依存的状况,以及这些函数赋值给相应的函数指针的位置和顺序。其实一直想弄明白的就是这个过程,真正的写驱动时,只要按着DATASHEET和别人的例程以及SPEC就可以把程序写得中规中矩了,简要说明一下这三大法宝:

SPEC:协议或者标准的规范,也就是前面另外一种说法协议,当然那样说不太准确,比如我们写USB驱动就要明白USB的协议规范。
DATASHEET:这个不用细说吧,写硬件没有这个,你怎么写。
EXAMPLE或者说LINUX内核源码:这个很具有借鉴和参考意义。


扯回来,从一开始说,兵分两路,一路是书写驱动一路是驱动的实际运行过程。先说前者。

   写驱动:

1、完成硬件的操作函数,也可以说是nand_chip这个结构体中的读写等函数。用术语说:这个是硬件驱动层级的函数。
2、完成上层接口开放的操作函数,也可以说是mtd_info这个结构体中的读写函数。这个是原始设备层的函数。
3、完成注册、PROBE等函数。
上面说得简单,以后会一步步的细化。


   驱动的运行流程:
1、s3c24xx_nand_probe函数中调用s3c2410_nand_init_chip、nand_scan_ident、s3c2410_nand_update_chip、nand_scan_tail等函数对nand_chip和mtd_info的成员进行赋值,特别注意在nand_scan_ident函数中的nand_set_defaults函数,这个里面对相当多的函数进行了初始化和再赋值,下面会详细的说明。

简单的流向:
struct
mtd_info----------->struct nand_ecc_ctrl
        
|                              |
  |                              |
 
|-------->struct
nand_chip<-----

2、mtd_info中的读写函数,如read,write_oob等,这是MTD原始设备层与FLASH硬件层之间的接口;
nand_ecc_ctrl中的读写函数,如read_page_raw,write_page等,主要用来做一些与ecc有关的操作;
nand_chip中的读写函数,如read_buf,cmdfunc等,与具体的NAND
controller相关,就是这部分函数与硬件交互,通常需要我们自己来实现。值得一提的是,struct nand_chip中的读写函数虽然与具体的NAND
controller相关,但是MTD也为我们提供了default的读写函数,如果你的NAND
controller比较通用(使用PIO模式),对NAND芯片的读写与MTD提供的这些函数一致,就不必自己实现这些函数了

3、
设备OPEN调用原始设备层中的mtd_info中相应的函数,然后再调用nand_chip中相应的函数,接着nand_read(mtd\nand\nand_base.c)函数会调用struct
nand_chip中cmdfunc函数,这个cmdfunc函数与具体的NAND controller相关,它的作用是使NAND controller向NAND
芯片发出读命令,NAND芯片收到命令后,就会做好准备等待NAND controller下一步的读取。然后跳到read_buf再跳到这个函数指针(或者说重载)指向的函数s3c2410_nand_read_buf中,再调用类似于readsb之类的最基础的函数来实现硬件的读写。(这段粉红的有问题,目前正在考虑中)
也可能nand_read函数调用struct
nand_ecc_ctrl中的read_page函数,而read_page函数又会调用struct
nand_chip中read_buf函数,从而真正把NAND芯片中的数据读取到buffer中(所以这个read_buf的意思其实应该是read
into buffer,另外,这个buffer是struct mtd_info中的nand_read函数传下来的)。

4、然后就是一些ECC的校验,数据的处理(比如错误判断和纠错),然后返回读取的实际数据。
5、其它 的如写等过程也是如此。
在下面的一节里开始详细的写上面说的过程。

阅读(1702) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~