您的位置:首页 > 其它

基于MTD的NANDFLASH设备驱动底层实现原理分析(二)

2011-11-12 11:14 691 查看
四、常见的NANDFLASH的操作

1、要实现对 Nand Flash 的操作,比如读取一页的数据,写入一页的数据等,都要发送对应的命令,而且要符合硬件的规定,如图:



比如说要实现读一页的数据,就要发送Read命令,而且分两个周期发送,即分两次发送对应的命令,第一次是 0x00h,第二次是 0x30h,而两次命令中间,需要发送对应的你所要读取的页的地址,对应地,其他常见的一些操作,比如写一个页的数据(Page Program),就是先发送 0x80h,然后发送要写入的地址,再发送0x10h。

2、读(Read)nandflash操作过程分析



1)红色竖线穿过的第一行,是 CLE。前面介绍命令所存使能(CLE)的那个引脚将CLE 置 1,就说明你将要通过 I/O 复用端口发送进入Nand Flash的,是命令,而不是地址或者其他类型的数据。只有这样将 CLE 置 1,使其有效,才能去通知了内部硬件逻辑,你接下来将收到的是命令,内部硬件逻辑才会直到收到的是命令,放到命令寄存器中,才能实现后面正确的操作,否则,不去将 CLE 置 1使其有效硬件会无所适从,不知道你传入的到底是数据还是命令了。

2)而第二行,是 CE,那一刻的值是 0。这个道理很简单,你既然要向Nand Flash发命令,那么先要选中它,所以,要保证 CE为低电平,使其有效,也就是片选有效。

3)第三行是 WE,意思是写使能。因为接下来是往 Nand Flash里面写命令,所以,要使得 WE有效所以设为低电平。

4)第四行,是 ALE 是低电平,而 ALE 是高电平有效,此时意思就是使其无效。而对应地,前面介绍的使 CLE 有效,因为将要数据的是命令(此时是发送图示所示的读命令第二周期的 0x30) ,而不是地址。如果在其他某些场合,比如接下来的要输入地址的时候,就要使其有效,而使 CLE 无效了。

5)第五行,RE,此时是高电平,无效。可以看到,知道后面低 6 阶段,才变成低电平,才有效,因为那时候要发生读取命令,去读取数据。

6)第六行,就是我们重点要介绍的,复用的输入输出 I/O 端口了,此刻,还没有输入数据,接下来,在不同的阶段,会输入或输出不同的数据/地址。

7)第七行,R/B,高电平,表示 R(Ready)/就绪,因为到了后面的第 5阶段,硬件内部,在第四阶段,接受了外界的读取命令后,把该页的数据一点点送到页寄存器中,这段时间,属于系统在忙着干活,属于忙的阶段所以,R/B才变成低,表示 Busy忙的状态的。 其他的时序的就类似的理解。

3、计算我们要读取或者写入的行地址和例地址

以mini2440开发板上的K9F2G08为例,此Nand Flash,一共有 2048 个块,每个块内有 64 页,每个页是 2K+64 Bytes。

假设,我们要访问其中的第 1000个块中的第 25 页中的 1208字节处的地址,此时,我们就要先把具体的地址算出来:

物理地址

=块大小*块号 + 页大小*页号 + 页内地址



从上图可以看出,该FLASH的地址周期一共有5个,2个列地址(Column)周期,3个行地址(Row)周期

a)对应的列地址就是页内地址,该flash一个页的大小是2K即2048个字节,所以它的地址范围是0~2047,对应的上图的列地址A0-A10就是页内地址。你可能会发现多出了一个A11,从A0-A11,这样一共就有了12位,那它的地址范围就是0~2^12,即0~4096了,实际上,由于我们访问页内地址,可能会访问到
oob 的位置,即 2048-2111 这 64 个字节的范围内,所以,此处实际上只用到了 2048~2111,用于表示页内的 oob 区域,其大小是 64字节。

b)对应地,A12~A28,称作页号,页的号码,可以定位到具体是哪一个页,该FLASH一共是64页一共需要6位即A12~A17,而其中A18~A28表示对应的块号,即属于哪个块。

这里有一个很重要的地方就是我们要传入的地址的每一位,就是对应着上表中的 A0 到 A28 ,实际上上表中的 A11是比较特殊的,只有当我们访问页内地址处于 oob的位置,即属于 2048~2111 的时候,A11才会其效果,才会用 A0-A11用来表示对应的某个属于 2048~2111 的某个值,属于 oob 的某个位置,而我们此处的页内地址为 1208,还没有超过
2047 呢,所以 A11肯定是 0

然后我们再来算上面我们要访问的地址:第 1000个块中的第 25 页中的 1208字节处的地址

第 1000个块中的第 25 页中的 1208字节处的地址它对应着的页内地址为:

页内地址 =1208Bytes

=0x4B8

页 号 =块数*每块多少页 + 块内的页号

=1000*64 + 25

=0xFA19

也就是我们要访问0xFA19页内的0x4B8地址,再把这个地址转换成列和行地址

A0~A10是用来表示页内地址的所以把0x4B8拆分成两列

列地址1=0xB8,列地址2=0x04;

再把页号0xFA19拆分成3行

行地址1=0x19,行地址2=0xFA,行地址3=0x0;

对应的看看linux2.6.35/driver/mtd/nand/nand_base.c中地址的发送



上面的column即对应着页内地址,通常情况是0,如果不是0则通过传入进来的地址除于页地址就可得到相应的列地址了。而 page_addr 即页号,就是通过要访问的地址,除于页大小,即可得到。

对于其他操作还正在研究中。。。。。。虽然说上面这些东东大部分都是来自别人的东西,但是我相信现在它已经变成我自己的东西了。。我不记得那个大帅的博客了,因为我是直接把它的博客给保存到本地了。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: