NAND Flash 在嵌入式系统中的地位与PC机上的硬盘是类似的。用于保存系统运行所必需的操作系统,应用程序,用户数据,运行过程中产生的各类数 据,系统掉电后数据不会护丢失。现在的Flash主要有两咱,一种是NAND Flash 一种是Nor Flash。NOR Flash是由Intel公司于1988年发明的,用以代替EERPOM,NAND Flash由Toshiba 公司在1989年发明的。
网上有很多介绍两者区别的文章,在此就不做介绍了,主要介绍关于NAND Flash的组织结构和编写程序的方法。(二者区别文章,可以参考http://blog.chinaunix.net/uid-22731254-id-1761885.html)
在三星的NAND Flash 中,当CPU从NAND Flash开始启动时,CPU会通过内部的硬件将NAND Flash开始的4KB数据复制到称为“Steppingstone”的4KB的内部RAM中,起始地址为0,然后跳到地址0处开始执行。这也就是我们为 什么可以把小于4KB的程序烧到NAND Flash中,可以运行,而当大于4KB时,却没有办法运行,必须借助于NAND Flash的读操作,读取4KB以后的程序到内存中。
NAND Flash的寻址方式和NAND Flash的memory组织方式紧密相关。NAND Flash的数据是以bit的方式保存在 memory cell(存储单元)。一般情况下,一个cell中只能存储一个bit。这些cell以8个或者16个为单位,连成 bit line ,形成所谓的byte(x8)/word(x16),这就是NAND Flash的位宽。
这些Line会再组成 Pape(页)。然后是每32个page形成一个Block,所以一个Block(块)大小是16k.Block是NAND Flash中最大的操作单元,其中的擦除操作是以Block为单位进行擦除的,而读写和编程是以page为单位进行操作的,并且读写之前必须进行 flash的擦写。我们这里以三星K9F1208U0M的NAND Flash为例,它的大小是64MB的。
1block = 32page
1page = 512bytes(datafield) + 16bytes(oob);(oob=out of band)
K9F1208U0B总共有4096 个Blocks,故我们可以知道这块flash的容量为4096 *(32 *528)= 69206016 Bytes = 66 MB
但事实上每个Page上的最后16Bytes是用于存贮检验码用的,并不能存放实际的数据,所以实际上我们可以操作的芯片容量为
4096 *(32 *512) = 67108864 Bytes = 64 MB
在NAND Flash中有8个I/O引脚(IO0—IO7)、5个全能信号(nWE ALE CLE nCE nRE)、一个引脚,1个写保护引脚。操作NAND Flash时,先传输命令,然后传输地址,最后读写数据。对于64MB的NAND Flash,需要一个26位的地址。只能8个I/O引脚充当地址、数据、命令的复用端口,所以每次传地址只能传8位。这样就需要4个地址序列。因此读写一 次nand flash需要传送4次(A[7:0] A[16:9] A[24:17] A[25])。64M的NAND Flash的地址范围为0x00000000—0x03FFFFFF。128M的NAND Flash的地址范围为0x00000000---0x07FFFFFF。1KB = 0x000-0x3FF.128字节=0x00H--7FH。
一页有528个字节,而在前512B中存放着用户的数据。在后面的16字节中(OOB)中存放着执行命令后的状态信息。主要是ECC校验的标识。列地址 A0-A7可以寻址的范围是256个字节,要寻址528字节的话,将一页分为了A.(1 half array)B(2 half array) C(spare array)。A区0—255字节,B区 256-511 字节C区512—527字节。访问某页时必须选定特定的区。这可以使地址指针指向特定的区实现。
在NAND Flash 中存在三类地址,分别为Block Address 、Column Address Page Address.。
Column Address 用来选择是在上半页寻址还是在下半页寻址A[0]—A[7].也就相当于页内的偏移地址。在进行擦除时不需要列地址,因为擦除 是以块为单位擦除。32个Page需要5bit来表示。也就是A[13:9];也就是页在块内的相对地址。A8这一位用来设置512字节的上半页,还是下 半页,1表示是在上半页,而2表示是在下半页。Block的地址有A[25:14]组成。
存储操作特点:
1.擦除操作的最小单位是块
2.Nand Flash芯片每一位只能从1变为0,而不能从0变为1,所以在对其进行写入操作之前一定要将相应块擦除(擦除就是将相应块的位全部变为1
3 OOB部分的第六字节(即517字节)标志是否坏块,如果不是坏块该值为FF,否则为坏块
4 除OOB第六字节外,通常至少把OOB前3字节存放Nand Flash硬件ECC码
一个容量为 64M(512Mbit)的NAND Flash,分为131072页,528列。(实际中由于存在spare area,故都大于这个值),有4096块,需要12bit来表示即A[25:14].如果是128M(1Gbit)的话,blodk Address为A[26:14].由于地址只能在IO0—IO7上传送。编程时通常通过移位来实现地址的传送。传送过程如下:
第1个地址序列:传递column address,也就是NAND Flash[7:0],这一周期不需要移位即可传递到I/O[7:0]上,而half page pointer 即A8是由操作指令决定,00h,在A区,01h在B区,指令决定在哪个half page上进行读写,而真正A8的值是不需要程序员关心的;
第2个地址序列:就是将NAND_ADDR 右移9位,而不是8位,将NAND_ADDR[16:9]传递到I/O[7:0]上;
第3个地址序列:将NAND_ADDR[24:17] 传递到I/O[7:0]上;
第4个地址序列:将NAND_ADDR[25]传送到I/O上。
整个地址的传送过程需要4步才能完成。如果NAND Flash 的大小是32MB的以下的话,那么block address 最高位只到bit24,因此寻址只需要3步,就可以完成。
在进行擦除操作时由于是以块进行擦除,所以只需要3个地址序列,也就是只传递块的地址,即A[14:25]。
NAND Flash地址的计算:
Column Address 翻译过来是列地址,也就是在一页里的偏移地址。其实是指定Page上的某个Byte,指定这个Byte,其实也就是指定此页的 读写起始地址。
Page Address:页地址。页的地址总是以512Bytes对齐的,所以它的低9位问题0,确定读写操作在NAND Flash中的哪个页进行。
当我们得到一个Nand Flash地址addr时,我们可以这样分解出Column Address和Page Address。
Columnaddr = addr % 512 // column address
Pageaddr = addr>>9 // page address
也就是一个Nand Flash地址的A0-A7是它的column address ,A9—A25是它的Page Address,地址A8被忽略。
现在假设我要从Nand Flash中的第5000字节处开始读取1024个字节到内存的0x30000000处,我们这样调用read函数
NF_Read(5000, 0x30000000,1024);
我们来分析5000这个src_addr.
根据
column_addr=src_addr%512;
page_address=(src_addr>>9);
我们可得出column_addr=5000%512=392
page_address=(5000>>9)=9
于是我们可以知道5000这个地址是在第9页的第392个字节处,于是我们的NF_read函数将这样发送命令和参数
column_addr=5000%512;
page_address=(5000>>9);
NF_CMD=0x01; & nbsp; // 要从2nd half开始读取 所以要发送命令0x01
NF_ADDR= column_addr &0xff; //1st Cycle A[7:0]
NF_ADDR=page_address& 0xff
NF_ADDR=(page_address>>8)&0xff; //3rd.Cycle A[24:17]
NF_ADDR=(page_address>>16)&0xff; //4th.Cycle A[25]
向NandFlash的命令寄存器和地址寄存器发送完以上命令和参数之后,我们就可以从rNFDATA寄存器(NandFlash数据寄存器)读取数据了.
我用下面的代码进行数据的读取.
for(i=column_addr;i<512;i++)
{
*buf++=NF_RDDATA();
}
每当读取完一个Page之后,数据指针会落在下一个Page的0号Column(0号Byte).
==================
注意:原博文只介绍一个page为512bytes,一个block为32pages的情况。实际上page跟block有多种规格,分别是:
page典型值有512bytes,2048bytes以及4096bytes;而负责ECC校验区域大小一般为page的1/32。
block典型值有32pages,64pages以及128bytes
(参考wiki:http://en.wikipedia.org/wiki/Flash_memory)
Nand flash种类:
目前有SLC、MLC以及TLC nand flash
SLC = single-level-cell
MLC = multi-level-cell
TLC= triple-level-cell
按照目前的资料推测,上文介绍的Nand flash就是SLC类,一个cell中存储一个bit信息,而后面更先进的工艺可以让一个cell中存储多个bit信息,分别是2bits per cell跟3bits per cell。
使得nand flash的容量密度倍增,成本相应会降低。但这样子,虽然容量增加,flash的擦除次数会减少以及性能可靠性会降低。
市场上一些公司推出自己特色的Nand flash,例如micron的serial nand flash,Managed Nand
Serial Nand Flash,具体不清楚,兼容SPI接口。按照micron的说法是:low-density SLC devices with a NOR-like serial interface 。
Managed Nand flash,主要是在nand flash中集成控制器,主要用于各种嵌入式设备或者便携式存储。
Bus Width:
flash的bus width指的是数据总线,实际情况得看具体数据IO口与CPU连接的数量,有些flash支持16bits,同时也可以配置成8bits。
有些公司在block的基础上,再划分plane以及bank。plane在实际应用中不会怎么提及到。bank号由外部的片选信号确定,可以参考下篇关于bank的文章。
CFI(Common Flash Memory Interface):
自从Intel公司于1988年推出了可快速擦写的非易失性存储器Flash Memory以来,快速擦写存储器FlashMemory技术就得到了非常迅速的发展。这主要是由于Flash Memory具有不需要存储电容器、集成度更高、制造成本低于DRAM、使用方便,读写灵活、访问速度快、断电后不丢失信息等特点。 虽然Flash Memory应用越来越广泛,但由于生产Flash Memory的半导体制造商众多,不同厂商Flash Memory产品的操作命令集和电气参数又千差万别,这给Flash Memory的开发设计人员和OEM制造商带来许多不便。为了对现有的Flash Memory的产品进行升级或使用其它公司的FlashMemory产品替换,必须对原有的程序代码和硬件结构进行修改。为解决上述原因所引发的问题,迫 切需要Flash Memory制造商提出一个公共的标准解决方案,在这样的背景下,公共闪存接口(Common Flash Interface),简称CFI 诞生了(由AMD, Intel, Sharp and Fujitsu共同开发),CFI是一个公开的标准的从Flash Memory器件中读取数据的接口。它可以使系统软件查询已安装的Flash Memory器件的各种参数,包括器件阵列结构参数、电气和时间参数以及器件支持的功能等。利用CFI可以不用修改系统软件就可以用新型的和改进的产品代替旧版本的产品。例如:如果新型的Flash Memory的擦除时间只有旧版本的一半,系统软件只要通过CFI读取新器件的擦除时间等参数,修改一下定时器的时间参数即可.
只要多种flash产品支持CFI接口,就可以使用同一个驱动即可进行识别。
Sector:
http://www.segger.com/emfile_driver_nor_flash.html
http://www.segger.com/emfile_driver_nand_flash.html
参考了部分资料,有些资料上说sector跟block是一样的(wiki:memory flash),有些则表示block下有多个sector(上面segger网站),有多种表述,让人困惑。具体视datasheet而定。
有些公司引入die的概念,这跟bank有些相似。
因此,暂时还是以本文章上面描述为主,以cell-page-block的次序进行认识整理。
logical sector与physical sector:
physical sector,存储设备的实际扇区,例如硬盘。
logical sector,基于文件系统的扇区,这部分普通用户可以查看的到。物理扇区里面的保留扇区是不包括到逻辑扇区中的。
可以参考segger网站的以下内容:
Differentiating between "logical sectors" or "blocks" and "physical sectors" is very essential to understand this section. A logical sector/block is the base unit of any file system, its usual size is 512 bytes. A physical sector is an array of bytes on the flash chip that are erased together (typically between 2 Kbytes - 128 Kbytes). The flash chip driver is an abstraction layer between these two types of sectors. Every time a logical sector is being updated, it is marked as invalid and the new content of this sector is written into another area of the flash. The physical address and the order of physical sectors can change with every write access. Hence, there cannot exist a direct relation between the sector number and its physical location. The flash driver manages the logical sector numbers by writing it into special headers. It does not matter to the upper layer were the logical sector is stored or how much flash memory is used as a buffer. All logical sectors (starting with Sector #0) do always exist and are always available for user access. Using the same