――Block address――page address――column address
对于NANDFLASH来说,地址,命令和数据都只能在I/O[7:0]上传递,数据宽度为8bits或16bits。
下面解释一下块地址,列地址,行地址,还有页寄存器(page Register)的含义:
在擦除数据的时候块地址会被用到。
对Nand flash的访问中,地址由列地址和行地址两部分组成。
列地址(column address):列地址表示在页内以byte(如果是X16,则以word)为单元的页内偏移量;
行地址(页地址)(row address):指page在整个nand芯片中的索引。
以下列举3个不同大小型号的nand flash进行说明:
SAMSUNG_K9F5608X0D(512Bytes(没有包括16Bytes spare)*32pages*2048blocks=32Mbytes)需要3个地址周期
列地址:A[7:0]第一个地址周期发出,对于X8的nandflash来说,如果要把A[8]也编进列地址里面去,那么整个地址传输需要4个周期完成,所以为了节省一个周期,K9F5608X0D把页内分为A(1 half array)区,B(2 half array)区。A区0-255字节,B区256-511字节。访问某页时必须通过A[8]选定特定的区,A[8]则由操作指令决定的,00h,在A区;01h在B区。所以传输地址时A[8]不需要传输。对于X16的nand flash来说,由于一个page的main area的容量为256word,仍相当于512byte。但是,这个时候没有所谓的1st halfpage 和2nd halfpage之分了,所以,bit8就变得没有意义了,也就是这个时候 A8 完全不用管,地址传递仍然和x8器件相同。除了这一点之外,x16的NAND使用方法和 x8 的使用方法完全相同。
行地址:A[24:9]由第2,3个地址周期发出;
SAMSUNG_K9F1208(512Bytes(不包括16Bytes spare)*32pages*4096blocks=64MBytes)需要4个地址周期
列地址:A[7:0]第一个地址周期发出,同上;
行地址:A[25:9]由第2,3,4个地址周期发出,A[25]以上的各位必须被设置为L;
SAMSUNG_K9F1G08U0B(2048Bytes(不包括64Bytes spare)*64pages*1024blocks=128MBytes)需要4个地址周期
这里有个问题2048不是用11bits就可以表示了吗?为什么还要用到A[11:0]这12bits?????此处求解
解:在后面写代码才发现,其实列地址就用到了A[10:0]才对的,也就是说下面datasheet出错了,
A[26:11]是用来表示页地址的,对于A[27]其实是不存在的,只在跟大容量时才会有的.
列地址:A[10:0]第1,2个地址周期发出,如图*L位要置为low;
行地址:A[26:11]由第3,4个地址周期发出;
④页寄存器:由于对nand flash读取和编程操作,一般最小单位是page。所以nand在硬件设计时候,对每一片都有一个对应的区域用于存放将要写入到物理存储单元中区的或者刚从存储单元中读取出来的一页的数据,这个数据缓存区就是页缓存,也叫页寄存器。所以实际上写数据只是写到这个页缓存中,只有等你发了对应的编程第二阶段的确认命令0x10之后,实际的编程动作才开始把页缓存一点点的写到物理存储单元中去,这也就是为什么发完0x10之后需要等待一段时间的原因。
I/O0~I/O7: 用于输入命令/地址/数据,输出数据
CE# : 片选管脚
CLE : command latch enable ,命令锁存使能,在输入命令之前必须使其有效
ALE : Address latch enable ,地址锁存使能,在输入地址前必须使其有效
RE# : read enable,读使能,在读数据之前要先使其有效
WR# : Write enable,写使能,在写数据之前要先使其有效
WP# :write Protect,写保护
R/B# :Ready/Busy Output ,就绪/忙,主要用于在发送完编程/擦除后,检测这些操作是否完成。
Vcc :Power,电源
Vss :Ground,接地
N.C :Non-Connection,未定义,未连接
以下是关SAMSUNG_K9F5608X0D(注意:其它型号命令与时序图可能会有所不同,具体区别可以查阅相关芯片的datasheet)命令设置表:
Read status:读取状态寄存器命令;
ReadID:读芯片ID命令;ECh是制造厂商代码,Device code 是设备号
Read1 :读data field命令,(00h->1stfield,01h->2nd field)从写入地址开始读,读到此页最后一个byte(包括了sparefield);
以下是针对连续row read的时序图,连续row read不会被中止直到CE管脚被拉高(sequential row read 只对于K9F5608U0D_P,F orK9F5608B0D_P有效):
Read2:读sparefield命令;
Reset : 复位命令,当nand flash还在忙状态(随机读取,写数据或者擦除期间)的时候,如果接收到复位命令则会中止当前这些操作,并且这些正在被改变的存储单元里面的内容不再有效。之后命令寄存器会被清除用于等待下一个命令。
Page program:写命令,从写入地址开始写,写到此页最后一个byte(包括了sparefield);(这里需要注意:发写命令之前要先写入页内区域选择命令;00h->A区(默认),01h->B区)
Copy-Back program: 从源地址某个区开始处把数据快速有效地拷贝到目标地址的同一个区域直到页的最后一个byte而不需要通过外部memory。
Block Erase:块擦除,从A[9](因为页内只有512个byte故列地址占用A[8:0])以上的地址发出,但是A[13:9]将不被理睬,应该块地址是从A[14]以上位才有效的。
Nand Flash中,一个块中含有1个或多个位是坏的,就成为其为坏块。
坏块的稳定性是无法保证的,也就是说,不能保证你写入的数据是对的,或者写入对了,读出来也不一定对的。而正常的块,肯定是写入读出都是正常的。
坏块有两种:
(1)一种是出厂的时候,也就是,你买到的新的,还没用过的Nand Flash,就可以包含了坏块。此类出厂时就有的坏块,被称作factory (masked)bad block或initial bad/invalid block,在出厂之前,就会做对应的标记,标为坏块。
具体标记的地方是,对于现在常见的页大小为2K的NandFlash,是块中第一个页列地址为2048的位置(旧的小页面,pagesize是512B甚至256B的nandflash,坏块标记是spare area的第6个字节),如果不是0xFF,就说明是坏块。相对应的是,所有正常的块,好的块,里面所有数据都是0xFF的。
(2)第二类叫做在使用过程中产生的,由于使用过程时间长了,在擦块除的时候,出错了,说明此块坏了,也要在程序运行过程中,发现,并且标记成坏块的。具体标记的位置,和上面一样。这类块叫做worn-out bad block。
对于坏块的管理,在Linux系统中,叫做坏块管理(BBM,Bad Block Managment),对应的会有一个表去记录好块,坏块的信息,以及坏块是出厂就有的,还是后来使用产生的,这个表叫做坏块表(BBT,Bad Block Table)。在Linux内核MTD架构下的Nand Flash驱动,和Uboot中Nand Flash驱动中,在加载完驱动之后,如果你没有加入参数主动要求跳过坏块扫描的话,那么都会去主动扫描坏块,建立必要的BBT的,以备后面坏块管理所使用。(这样每次使用之之前,都会自动扫描一下,建立BBT,这样就可以跳过怀块进行别的方面的处理了)
在一个块内,对每一个页进行编程的话,必须是顺序的,而不能是随机的。比如,一个块中有128个页,那么你只能先对page0编程,再对page1编程,。。。。,而不能随机的,比如先对page3,再page1,page2.,page0,page4,.。。。
【片选无关(CEdon’t-care)技术】
没明白什么意思?很多Nand flash支持一个叫做CE don’t-care的技术,字面意思就是,不关心是否片选,那有人会问了,如果不片选,那还能对其操作吗?答案就是,这个技术,主要用在当时是不需要选中芯片却还可以继续操作的这些情况:在某些应用,比如录音,音频播放等应用中,外部使用的微秒(us)级的时钟周期,此处假设是比较少的2us,在进行读取一页或者对页编程时,是对Nand Flash操作,这样的串行(SerialAccess)访问的周期都是20/30/50ns,都是纳秒(ns)级的,此处假设是50ns,当你已经发了对应的读或写的命令之后,接下来只是需要Nand Flash内部去自己操作,将数据读取或写入进去到内部的数据寄存器中而已,此处,如果可以把片选取消,CE#是低电平有效,取消片选就是拉高电平,这样会在下一个外部命令发送过来之前,即微秒量级的时间里面,即2us-50ns≈2us,这段时间的取消片选,可以降低很少的系统功耗,但是多次的操作,就可以在很大程度上降低整体的功耗了。
总结起来简单解释就是:由于某些外部应用的频率比较低。