NandFlash读写过程.doc_第1页
NandFlash读写过程.doc_第2页
NandFlash读写过程.doc_第3页
NandFlash读写过程.doc_第4页
NandFlash读写过程.doc_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

NandFlash读写过程一、结构分析 目前市场上常见的8位NandFlash有三星公司的k9f1208、k9f1g08、k9f2g08等。k9f1208、k9f1g08、k9f2g08的数据页大小分别为512Byte、2kByte、2kByte。它们在寻址方式上有一定差异,所以程序代码并不通用。本文以S3C2410处理器和k9f1208系统为例,讲述NandFlash的读写方法。NandFlash的数据是以bit的方式保存在memory cell里的,一般来说,一个cell 中只能存储一个bit,这些cell 以8 个或者16 个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND Device 的位宽。这些Line 组成Page, page 再组织形成一个Block。k9f1208的相关数据如下:1block=32page;1page=528byte=512byte(Main Area)+16byte(Spare Area)。总容量为=4096(block数量)*32(page/block)*512(byte/page)=64MbyteNandFlash以页为单位读写数据,而以块为单位擦除数据。按照k9f1208的组织方式可以分四类地址: Column Address、halfpage pointer、Page Address 、Block Address。A0:25表示数据在64M空间中的地址。Column Address表示数据在半页中的地址,大小范围0255,用A0:7表示;halfpage pointer表示半页在整页中的位置,即在0255空间还是在256511空间,用A8表示;Page Address表示页在块中的地址,大小范围031,用A13:9表示;Block Address表示块在flash中的位置,大小范围04095,A25:14 表示;二、读操作过程K9f1208的寻址分为4个cycle。分别是:A0:7、A9:16、A17:24、A25。 读操作的过程为: 1、发送读取指令;2、发送第1个cycle地址;3、发送第2个cycle地址;4、发送第3个cycle地址;5、发送第4个cycle地址;6、读取数据至页末。K9f1208提供了两个读指令,0x00、0x01。这两个指令区别在于0x00可以将A8置为0,选中上半页;而0x01可以将A8置为1,选中下半页。虽然读写过程可以不从页边界开始,但在正式场合下还是建议从页边界开始读写至页结束。下面通过分析读取页的代码,阐述读过程。static void ReadPage(U32 addr, U8 *buf) /addr表示flash中的第几页,即flash地址9U16 i;NFChipEn(); /使能NandFlashWrNFCmd(READCMD0); /发送读指令0x00,由于是整页读取,所以选用指令0x00WrNFAddr(0); /写地址的第1个cycle,即Column Address,由于是整页读取所以取0WrNFAddr(addr); /写地址的第2个cycle,即A9:16WrNFAddr(addr8); /写地址的第3个cycle,即A17:24WrNFAddr(addr16); /写地址的第4个cycle,即A25。WaitNFBusy(); /等待系统不忙for(i=0; i9U32 i;NFChipEn(); /使能NandFlashWrNFCmd(PROGCMD0); /发送写开始指令0x80WrNFAddr(0); /写地址的第1个cycle WrNFAddr(addr); /写地址的第2个cycleWrNFAddr(addr8); /写地址的第3个cycleWrNFAddr(addr16); 写地址的第4个cycleWaitNFBusy(); /等待系统不忙for(i=0; i9); / page address也可以这么认为,一个Nand Flash地址的A0A7是它的column_addr,A9A25是它的Page Address。(注意地址位A8并没有出现,也就是A8被忽略,在下面你将了解到这是什么原因)Read1命令的操作分为4个Cycle,发送完读命令00h或01h(00h与01h的区别请见下文描述)之后将分4个Cycle发送参数,1st.Cycle是发送Column Address。2nd.Cycle ,3rd.Cycle和4th.Cycle则是指定Page Address(每次向地址寄存器发送的数据只能是8位,所以17位的Page Address必须分成3次进行发送)。4个Cycle你是否还记得我上文提到过的Data Field被分为1st half 和2end half两个部分?而从上面的命令集我们看到Read1的命令里面出现了两个命令选项,分别是00h和01h。这里出现了两个读命是否令你意识到什么呢?是的,00h是用于读写1st half的命令,而01h是用于读取2nd half的命令。现在我可以结合上图给你说明为什么K9F1208U0B的DataField被分为2个half了。如上文我所提及的,Read1的1st.Cycle是发送Column Address,假设我现在指定的Column Address是0,那么读操作将从此页的第0号Byte开始一直读取到此页的最后一个Byte(包括Spare Field),如果我指定的Column Address是127,情况也与前面一样,但不知道你发现没有,用于传递Column Address的数据线有8条(I/O0I/O7,对应A0A7,这也是A8为什么不出现在我们传递的地址位中),也就是说我们能够指定的Column Address范围为0255,但不要忘了,1个Page的DataField是由512个Byte组成的,假设现在我要指定读命令从第256个字节处开始读取此页,那将会发生什么情景?我必须把Column Address设置为256,但Column Address最大只能是255,这就造成数据溢出。正是因为这个原因我们才把Data Field分为两个半区,当要读取的起始地址(Column Address)在0255内时我们用00h命令,当读取的起始地址是在256511时,则使用01h命令.假设现在我要指定从第256个byte开始读取此页,那么我将这样发送命令串column_addr=256;NF_CMD=0x01; 从2nd half开始读取NF_ADDR=column_addr&0xff; 1st CycleNF_ADDR=page_address&0xff; 2nd.CycleNF_ADDR=(page_address8)&0xff; 3rd.CycleNF_ADDR=(page_address16)&0xff; 4th.Cycle其中NF_CMD和NF_ADDR分别是NandFlash的命令寄存器和地址寄存器的地址解引用,我一般这样定义它们,#define rNFCMD (*(volatile unsigned char *)0x4e000004) /NADD Flash command#define rNFADDR (*(volatile unsigned char *)0x4e000008) /NAND Flash address事实上,当NF_CMD=0x01时,地址寄存器中的第8位(A8)将被设置为1(如上文分析,A8位不在我们传递的地址中,这个位其实就是硬件电路根据01h或是00h这两个命令来置高位或是置低位),这样我们传递column_addr的值256随然由于数据溢出变为1,但A8位已经由于NF_CMD=0x01的关系被置为1了,所以我们传到地址寄存器里的值变成了A0 A1 A2 A3 A4 A5 A6 A7 A81 0 0 0 0 0 0 0 1 这8个位所表示的正好是256,这样读操作将从此页的第256号byte(2nd half的第0号byte)开始读取数据。Read2Read2则是指定读取Spare Field的内容其实Read1和Read2都是读命令,他们的区别相当于对一个读指针进行不同区域的定位。nand_flash.c中包含3个函数void nf_reset(void);void nf_init(void);void nf_read(unsigned int src_addr,unsigned char *desc_addr,int size);nf_reset()将被nf_init()调用。nf_init()是nand_flash的初始化函数,在对nand flash进行任何操作之前,nf_init()必须被调用。nf_read(unsigned int src_addr,unsigned char *desc_addr,int size);为读函数,src_addr是nand flash上的地址,desc_addr是内存地址,size是读取文件的长度。在nf_reset和nf_read函数中存在两个宏NF_nFCE_L();NF_nFCE_H();你可以看到当每次对Nand Flash进行操作之前NF_nFCE_L()必定被调用,操作结束之时NF_nFCE_H()必定被调用。这两个宏用于启动和关闭Flash芯片的工作(片选/取消片选)。至于nf_reset()中的rNFCONF=(115)|(114)|(113)|(112)|(111)|(TACLS8)|(TWRPH04)|(TWRPH19); 我们可得出column_addr=5000%512=392page_address=(50009)=9于是我们可以知道5000这个地址是在第9页的第392个字节处,于是我们的nf_read函数将这样发送命令和参数column_addr=5000%512;page_address=(50009);NF_CMD=0x01; 从2nd half开始读取NF_ADDR= column_addr &0xff; 1st CycleNF_ADDR=page_address&0xff; 2nd.CycleNF_ADDR=(page_address8)&0xff; 3rd.CycleNF_ADDR=(page_address16)&0xff; 4th.Cycle向NandFlash的命令寄存器和地址寄存器发送完以上命令和参数之后,我们就可以从rNFDATA寄存器(NandFlash数据寄存器)读取数据了.我用下面的代码进行数据的读取.for(i=column_addr;ihwcontrol(NAND_CTL_SETNCE); nand_command(mtd, NAND_CMD_RESET, -1, -1); udelay (10);hwcontrol(NAND_CTL_SETNCE)的作用是设置2410的NAND FLASH CONFIGURATION (NFCONF) REGISTER的NAND Flash Memory chip enable位为0,这位寄存器在自动重启后就被系统自动清零。如果要访问NAND flash的内存,这位必须置1。nand_command(mtd, NAND_CMD_RESET, -1, -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 读写OOBNAND_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); 将命令直接想到命令寄存器(NFCMD7:0)中。3、 Set ALE and clear CLE to start address cycle & Serially input address1中已经提到了ALE和CLE的作用,现在开始发送地址。实现代码:this-hwcontrol(NAND_CTL_CLRCLE); / clear the command latch enablethis-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);地址发送完毕,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论