加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

NAND Flash结构与驱动分析

发布时间:2020-12-15 18:26:02 所属栏目:百科 来源:网络整理
导读:NAND Flash 结构与驱动分析 一、 NAND flash 的物理组成 NAND Flash 的数据是以 bit 的方式保存在 memory cell ,一般来说,一个 cell 中只能存储一个 bit 。这些 cell 以 8 个或者 16 个为单位,连成 bit line ,形成所谓的 byte(x8)/word(x16) ,这就是 NA

NAND Flash结构与驱动分析

一、NAND flash的物理组成


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)),每32page形成一个Block(32*528B)。具体一片flash上有多少个Block视需要所定。我所使用的三星 k9f1208U0M具有4096block,故总容量为4096*32*528B=66MB,但是其中的2MB是用来保存ECC校验码等额外数据的,故实际中可使用的为64MB
NAND flash
以页为单位读写数据,而以块为单位擦除数据。按照这样的组织方式可以形成所谓的三类地址:
Column Address
Starting Address of the Register. 翻成中文为列地址,地址的低8
Page Address
:页地址
Block Address
:块地址
对于NAND Flash来讲,地址和命令只能在I/O[7:0]上传递,数据宽度是8位。

?

二、NAND Flash地址的表示


512byte
需要9bit来表示,对于528byte系列的NAND,这512byte被分成1st half Page Register2nd half Page Register,各自的访问由地址指针命令来选择,A[7:0]就是所谓的column address(列地址),在进行擦除操作时不需要它,why?因为以块为单位擦除。32page需要5bit来表示,占用A[13:9]即该page在块内的相对地址。A8这一位地址被用来设置512byte1st half page还是2nd half page0表示1st1表示2ndBlock的地址是由A14以上的bit来表示。
例如64MB512Mb)的NAND flash(实际中由于存在spare area,故都大于这个值),共4096block,因此,需要12bit来表示,即A[25:14],如果是128MB(1Gbit) 528byte/pageNAND Flash,则block addressA[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


由于地址只能在I/O[7:0]上传递,因此,必须采用移位的方式进行。例如,对于512Mbit x8NAND flash,地址范围是0~0x3FF_FFFF,只要是这个范围内的数值表示的地址都是有效的。以NAND_ADDR 为例:

1 步是传递column address,就是NAND_ADDR[7:0],不需移位即可传递到I/O[7:0]上,而halfpage pointerA8 是由操作指令决定的,即指令决定在哪个halfpage 上进行读
写,而真正的A8 的值是不需程序员关心的
2 步就是将NAND_ADDR 右移9,将NAND_ADDR[16:9]传到I/O[7:0]上;
3 步将NAND_ADDR[24:17]放到I/O上;
4步需要将NAND_ADDR[25]放到I/O上;
因此,整个地址传递过程需要4 步才能完成,即4-step addressing。如果NAND Flash 的容量是32MB256Mbit)以下,那么,block adress最高位只到bit24,因此寻址只需要3步。
下面,就x16 NAND flash器件稍微进行一下说明。由于一个page main area 的容量为256word,仍相当于512byte。但是,这个时候没有所谓的1st halfpage 2nd halfpage 之分了,所以,bit8就变得没有意义了,也就是这个时候 A8 完全不用管,地址传递仍然和x8 器件相同。除了,这一点之外,x16 NAND使用方法和 x8 的使用方法完全相同。

三、NAND flash驱动解读


以前由于做移植多一些,那些工作很简单(现在看来),从来都不用去关心驱动里面到底怎么实现的,这几次面试才发现真的是学的太浅了,似乎我还在学习仰泳而那些牛人基本都属于潜水级的了,潜的不知有多深。我对照着开发板所带的NAND flash驱动和k9f1208的芯片资料把这些代码通读了一遍,终于明白了NAND flash的读写过程是如何实现的了。我所参考的驱动是mizi公司为三星芯片所写的,我看看了,大概和官方2.4.18内核的nand.c差不多。
s3c2410处理器中有专门的NAND flash控制器,他们位于SFR区,具体可以参看s3c2410用户手册。以下的这些代码均可以在vivi或者kernel里面找到,文中会标明程序出自何处。在vivi中,有关NAND flash的驱动都在driver/mtd/nand/下,该目录中包含的源文件:smc_core.cNAND flash的主要驱动。
NAND flash
芯片定义了一个很长的结构,这个结构中包含了操作NAND flash的函数和一些必要的变量(include/mtd/nand.h)。
struct nand_chip {
#ifdef CONFIG_MTD_NANDY???? /* =y */
??? void (*hwcontrol)(int cmd);
??? void (*write_cmd)(u_char val);
??? void (*write_addr)(u_char val);
??? u_char (*read_data)(void);
??? void (*write_data)(u_char val);
??? void (*wait_for_ready)(void);
??? int page_shift;
??? u_char *data_buf;
??? u_char *data_cache;
??? int??? cache_page;
??? struct nand_smc_dev *dev;
??? u_char spare[SMC_OOB_SIZE];
#else??? /* CONFIG_MTD_NANDY */
??? ……
#ifdef CONFIG_MTD_NAND_ECC
??? u_char ecc_code_buf[6];
??? u_char reserved[2];
#endif
#endif??? /* CONFIG_MTD_NANDY */
};
纵观对NAND flash的各种操作(readwriteerase),无外乎如下几种操作:
1
.选择flash??? nand_select()
2
.发送命令???? nand_command()
3
.进行相应操作 readwrite……
4
.反选NAND flash?? nand_deselect()

下面是以上四步的实现代码:
1
、选择NAND flash
#define nand_select()?? this->hwcontrol(NAND_CTL_SETNCE);
??????????????? nand_command(mtd,NAND_CMD_RESET,-1,-1);
??????????????? udelay (10);
hwcontrol(NAND_CTL_SETNCE)
的作用是设置2410NAND FLASH CONFIGURATION (NFCONF) REGISTERNAND Flash Memory chip enable位为0,这位寄存器在自动重启后就被系统自动清零。如果要访问NAND flash的内存,这位必须置1
nand_command(mtd,-1)
;向flash发送命令,此命令为reset,即为重置NAND flash
然后是10us的延迟,给flash个反应时间。
2
、发送命令
Nand_command()
同样在smc_core.c中实现。NAND flash的命令有如下几种:

??? 命令???????????????????????? 命令值??????????????? 描述
NAND_CMD_READ0??????????????????? 0???????????????
读操作
NAND_CMD_READ1??????????????????? 1???????????????
读操作
NAND_CMD_PAGEPROG??????????????? 0x10???????????
页编程操作
NAND_CMD_READOOB??????????????? 0x50???????????
读写OOB
NAND_CMD_ERASE1???????????????? 0x60???????????
读写操作
NAND_CMD_STATUS??????????????????? 0x70???????????
读取状态
NAND_CMD_STATUS_MULTI??????????? 0x71???????????
读取状态
NAND_CMD_SEQIN??????????????????? 0x80???????????
写操作
NAND_CMD_READID??????????????????? 0x90???????????
Flash ID
NAND_CMD_ERASE2???????????????? 0xd0???????????
擦写操作
NAND_CMD_RESET??????????????????? oxff???????????????
复位操作

按照程序的注释,可以将该函数的实现分为如下几步:
1
Begin command latch cycle
实现代码:
this->hwcontrol(NAND_CTL_SETCLE);
this->hwcontrol(NAND_CTL_DAT_OUT);
找到第二条语句的定义,发现什么都么做,不解!!希望达人解答。我猜想可能是一个数据读出的使能操作,允许数据读出。
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)发送命令的。
2
Write out the command to the device
这部分对于不同的命令来说,操作的步骤也不太相同,如果为写操作,那么还有根据flash不同的容量决定操作步骤,具体可以参看代码。如果为其他命令,那么就是简单的一行:
this->write_cmd (command);
将命令直接想到命令寄存器(NFCMD[7:0])中。
3
Set ALE and clear CLE to start address cycle & Serially input address
1
中已经提到了ALECLE的作用,现在开始发送地址。
实现代码:
this->hwcontrol(NAND_CTL_CLRCLE); // clear the command latch enable
this->hwcontrol(NAND_CTL_SETALE); // set the address latch enable
然后按位操作,是用函数write_addr()将地址写到NAND FLASH ADDRESS SET (NFADDR) REGISTER中。
4
Latch in address
实现代码:
this->hwcontrol(NAND_CTL_CLRALE);
this->hwcontrol(NAND_CTL_DAT_IN);
地址发送完毕,清楚ALE
5
Pause for 15us
我使用的VIVI中,使用udelay (15)延时15us,但这个时间会因NAND Flash的不同而不同。
三、Operation
根据函数的不同,操作部分会不一样,但是主要的是对NAND FLASH DATA (NFDATA) REGISTER的操作,或写(编程)或者读。通过读或写函数的参数来返回或传递读出的值或写入的值。写得操作通常比较麻烦,他要将写到flash的内容重新读出后进行ECC校验,如果数据正确则在重新真正的写(编程),如果错误,则将数据写入flash的另一个块。读和写都是以页为单位进行操作。而擦除则以块为单位,三个周期发送完地址。擦除完毕后同样需要进行检察以确定是否擦除成功。
四、De-select the NAND device
实现代码:
#define nand_deselect() this->hwcontrol(NAND_CTL_CLRNCE);
反选flash吧,不知这样叫正确与否,跟select the NAND device相反,亦即使用完后将使能flash位清0,代码是NFCONF位于0x4e00_0000的位置(NFCONF |= NFCONF_nFCE_HIGH;),有兴趣的可以读读代码,看看这是怎么实现的,我的感觉就是关于寄存器的清置读起来都比较晕。

?

http://blog.chinaunix.net/uid-26739173-id-3158739.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读