nand flash 原理简介

<div id="sina_keyword_ad_area2" class="articalContent  ">
<p>Fisrt part :<br>
NAND flash和NOR flash的不同</p>
<p>NOR flash采用位读写,因为它具有sram的接口,有足够的引脚来寻址,可以很容易的存取其内部的每一个字节。NAND
flash使用复杂的I/O口来穿行地存取数据。8个引脚用来传送控制、地址和数据信息。NAND的读和写单位为512Byte的页,擦写单位为32页的
块。<br>
● NOR的读速度比NAND稍快一些。<br>
  ● NAND的写入速度比NOR快很多。<br>
  ● NAND的4ms擦除速度远比NOR的5s快。<br>
  ● 大多数写入操作需要先进行擦除操作。<br>
  ● NAND的擦除单元更小,相应的擦除电路更少。<br>
在NOR器件上运行代码不需要任何的软件支持,在NAND器件上进行同样操作时,通常需要驱动程序,也就是内存技术驱动程序(MTD),NAND和NOR器件在进行写入和擦除操作时都需要MTD。<br>

---------摘抄自网上流传很广的《NAND 和 NOR flash的区别》</p>
<p>Second part:<br>
NAND Flash结构与驱动分析</p>
<p>一、NAND flash的物理组成<br>
NAND Flash 的数据是以bit的方式保存在memory cell,一般来说,一个cell 中只能存储一个bit。这些cell
以8个或者16个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND
Device的位宽。这些Line会再组成Page,(NAND Flash 有多种结构,我使用的NAND Flash
是K9F1208,下面内容针对三星的K9F1208U0M),每页528Bytes(512byte(Main
Area)+16byte(Spare
Area)),每32个page形成一个Block(32*528B)。具体一片flash上有多少个Block视需要所定。我所使用的三星
k9f1208U0M具有4096个block,故总容量为4096*(32*528B)=66MB,但是其中的2MB是用来保存ECC校验码等额外数据
的,故实际中可使用的为64MB。<br>
NAND flash以页为单位读写数据,而以块为单位擦除数据。按照这样的组织方式可以形成所谓的三类地址:<br>
Column Address:Starting Address of the Register.
翻成中文为列地址,地址的低8位<br>
Page Address :页地址<br>
Block Address :块地址<br>
对于NAND Flash来讲,地址和命令只能在I/O[7:0]上传递,数据宽度是8位。</p>
<p>二、NAND Flash地址的表示<br>
512byte 需要9bit来表示,对于528byte系列的NAND,这512byte被分成1st half Page
Register和2nd half Page Register,各自的访问由地址指针命令来选择,A[7:0]就是所谓的column
address(列地址),在进行擦除操作时不需要它,why?因为以块为单位擦除。32个page需要5bit来表示,占用A[13:9],即该
page在块内的相对地址。A8这一位地址被用来设置512byte的1st half page还是2nd half
page,0表示1st,1表示2nd。Block的地址是由A14以上的bit来表示。<br>
例如64MB(512Mb)的NAND flash(实际中由于存在spare
area,故都大于这个值),共4096block,因此,需要12个bit来表示,即A[25:14],如果是128MB(1Gbit)
的528byte/page的NAND Flash,则block address用A[26:14]表示。而page
address就是blcok address|page address in block NAND Flash 的地址表示为:
Block Address|Page Address in block|halfpage pointer|Column Address
地址传送顺序是Column Address,Page Address,Block Address。<br>
由于地址只能在I/O[7:0]上传递,因此,必须采用移位的方式进行。 例如,对于512Mbit x8的NAND
flash,地址范围是0~0x3FF_FFFF,只要是这个范围内的数值表示的地址都是有效的。 以NAND_ADDR 为例:<br>
第1 步是传递column address,就是NAND_ADDR[7:0],不需移位即可传递到I/O[7:0]上,而halfpage
pointer即A8 是由操作指令决定的,即指令决定在哪个halfpage 上进行读<br>
写,而真正的A8 的值是不需程序员关心的。<br>
第2 步就是将NAND_ADDR 右移9位,将NAND_ADDR[16:9]传到I/O[7:0]上;<br>
第3 步将NAND_ADDR[24:17]放到I/O上;<br>
第4步需要将NAND_ADDR[25]放到I/O上;<br>
因此,整个地址传递过程需要4 步才能完成,即4-step addressing。 如果NAND Flash
的容量是32MB(256Mbit)以下,那么,block adress最高位只到bit24,因此寻址只需要3步。<br>
下 面,就x16 的NAND flash 器件稍微进行一下说明。 由于一个page 的main area
的容量为256word,仍相当于512byte。但是,这个时候没有所谓的1st halfpage 和2nd halfpage
之分了,所以,bit8就变得没有意义了,也就是这个时候 A8 完全不用管,地址传递仍然和x8 器件相同。除了,这一点之外,x16
的NAND使用方法和 x8 的使用方法完全相同。</p>
<p>三、NAND flash驱动解读<br>
以前由于做移植多一些,那些工作很简单(现在
看来),从来都不用去关心驱动里面到底怎么实现的,这几次面试才发现真的是学的太浅了,似乎我还在学习仰泳而那些牛人基本都属于潜水级的了,潜的不知有多
深。我对照着开发板所带的NAND flash驱动和k9f1208的芯片资料把这些代码通读了一遍,终于明白了NAND
flash的读写过程是如何实现的了。我所参考的驱动是mizi公司为三星芯片所写的,我看看了,大概和官方2.4.18内核的nand.c差不多。<br>

在 s3c2410处理器中有专门的NAND
flash控制器,他们位于SFR区,具体可以参看s3c2410用户手册。以下的这些代码均可以在vivi或者kernel里面找到,文中会标明程序出
自何处。在vivi中,有关NAND
flash的驱动都在driver/mtd/nand/下,该目录中包含的源文件:smc_core.c是NAND
flash的主要驱动。<br>
NAND flash 芯片定义了一个很长的结构,这个结构中包含了操作NAND
flash的函数和一些必要的变量(include/mtd/nand.h)。<br>
struct nand_chip {<br>
#ifdef
CONFIG_MTD_NANDY<br>

void
(*hwcontrol)(int cmd);<br>
void
(*write_cmd)(u_char val);<br>
void
(*write_addr)(u_char val);<br>
u_char
(*read_data)(void);<br>
void
(*write_data)(u_char val);<br>
void
(*wait_for_ready)(void);<br>
int
page_shift;<br>
u_char
*data_buf;<br>
u_char
*data_cache;<br>

int
cache_page;<br>
struct
nand_smc_dev *dev;<br>
u_char
spare[SMC_OOB_SIZE];<br>
#else<br>
……<br>
#ifdef CONFIG_MTD_NAND_ECC<br>
u_char
ecc_code_buf[6];<br>
u_char
reserved[2];<br>
#endif<br>
#endif<br>
};<br>
纵观对NAND flash的各种操作(read、write、erase),无外乎如下几种操作:<br>
1.选择flash
nand_select()<br>
2.发送命令
nand_command()<br>
3.进行相应操作 read,write……<br>
4.反选NAND flash
nand_deselect()</p>
<p>下面是以上四步的实现代码:<br>
1、选择NAND flash<br>
#define nand_select()
this-&gt;hwcontrol(NAND_CTL_SETNCE); /<br>

nand_command(mtd, NAND_CMD_RESET, -1, -1); /<br>

udelay (10);<br>
hwcontrol(NAND_CTL_SETNCE) 的作用是设置2410的NAND FLASH CONFIGURATION
(NFCONF) REGISTER的NAND Flash Memory chip
enable位为0,这位寄存器在自动重启后就被系统自动清零。如果要访问NAND flash的内存,这位必须置1。<br>
nand_command(mtd, NAND_CMD_RESET, -1,
-1);向flash发送命令,此命令为reset,即为重置NAND flash。<br>
然后是10us的延迟,给flash个反应时间。<br>
2、发送命令<br>
Nand_command()同样在smc_core.c中实现。NAND flash的命令有如下几种:</p>
<p>
命令
命令值
描述<br>
NAND_CMD_READ0
0
读操作<br>
NAND_CMD_READ1
1
读操作<br>
NAND_CMD_PAGEPROG
0x10
页编程操作<br>
NAND_CMD_READOOB
0x50
读写OOB<br>
NAND_CMD_ERASE1
0x60
读写操作<br>
NAND_CMD_STATUS
0x70
读取状态<br>
NAND_CMD_STATUS_MULTI
0x71
读取状态<br>
NAND_CMD_SEQIN
0x80
写操作<br>
NAND_CMD_READID
0x90
读Flash ID号<br>
NAND_CMD_ERASE2
0xd0
擦写操作<br>
NAND_CMD_RESET
oxff
复位操作</p>
<p>按照程序的注释,可以将该函数的实现分为如下几步:<br>
1、Begin command latch cycle<br>
实现代码:<br>
this-&gt;hwcontrol(NAND_CTL_SETCLE);<br>
this-&gt;hwcontrol(NAND_CTL_DAT_OUT);<br>
找到第二条语句的定义,发现什么都么做,不解!!希望达人解答。我猜想可能是一个数据读出的使能操作,允许数据读出。<br>
Command Latch Enable(CLE) and Address Latch Enable(ALE) are used to
multiplex command and address respectively, via the I/O pins. The
CLE input controls the path activation for commands sent to the
command register. When active high, commands are latched into the
command register through the I/O ports on the rising edge of the
nWE signal. 看了这段英文相信对第一条语句的作用已经十分清楚了,他就是用来控制向命令寄存(COMMAND SET
(NFCMD) REGISTER)发送命令的。<br>
2、 Write out the command to the device<br>
这部分对于不同的命令来说,操作的步骤也不太相同,如果为写操作,那么还有根据flash不同的容量决定操作步骤,具体可以参看代码。如果为其他命令,那么就是简单的一行:<br>

this-&gt;write_cmd (command);<br>
将命令直接想到命令寄存器(NFCMD[7:0])中。<br>
3、 Set ALE and clear CLE to start address cycle &amp;
Serially input address<br>
1中已经提到了ALE和CLE的作用,现在开始发送地址。<br>
实现代码:<br>
this-&gt;hwcontrol(NAND_CTL_CLRCLE); // clear the
command latch enable<br>
this-&gt;hwcontrol(NAND_CTL_SETALE); // set the address
latch enable<br>
然后按位操作,是用函数write_addr()将地址写到NAND FLASH ADDRESS SET (NFADDR)
REGISTER中。<br>
4、 Latch in address<br>
实现代码:<br>
this-&gt;hwcontrol(NAND_CTL_CLRALE);<br>
this-&gt;hwcontrol(NAND_CTL_DAT_IN);<br>
地址发送完毕,清楚ALE。<br>
5、 Pause for 15us<br>
我使用的VIVI中,使用udelay (15)延时15us,但这个时间会因NAND Flash的不同而不同。<br>
三、Operation<br>
根据函数的不同,操作部分会不一样,但是主要的是对NAND FLASH DATA (NFDATA)
REGISTER的操作,或写(编程)或者读。通过读或写函数的参数来返回或传递读出的值或写入的值。写得操作通常比较麻烦,他要将写到flash的内容
重新读出后进行ECC校验,如果数据正确则在重新真正的写(编程),如果错误,则将数据写入flash的另一个块。读和写都是以页为单位进行操作。而擦除
则以块为单位,三个周期发送完地址。擦除完毕后同样需要进行检察以确定是否擦除成功。<br>
四、De-select the NAND device<br>
实现代码:<br>
#define nand_deselect()
this-&gt;hwcontrol(NAND_CTL_CLRNCE);<br>
反 选flash吧,不知这样叫正确与否,跟select the NAND
device相反,亦即使用完后将使能flash位清0,代码是NFCONF位于0x4e00_0000的位置(NFCONF |=
NFCONF_nFCE_HIGH;),有兴趣的可以读读代码,看看这是怎么实现的,我的感觉就是关于寄存器的清置读起来都比较晕。</p>
<p>好了,到此flash操作的框架基本完成。</p>
</div>

你可能感兴趣的:(Flash)