您的位置 首页 ADAS

对S3C2440读取NAND Flash的总结

在网上找了一些资料,又结合自己的经历谈一下我对NANDFlash的了解。S3C2440板的NandFlash支持由两部分组成:NandFlash控制…

在网上找了一些材料,又结合自己的阅历谈一下我对NAND Flash 的了解。

S3C2440 板的Nand Flash 支撑由两部分组成:Nand Flash 操控器(集成在S3C2440 CPU)和Nand Flash 存储芯片(K9F1208U0B)两大部分组成。当要拜访Nand Flash中的数据时,有必要经过Nand Flash操控器发送指令才干完结。所以, Nand Flash相当于S3C2440的一个外设,而不坐落它的内存地址区.

NAND Flash 的数据是以bit 的办法保存在memory cell,一般来说,一个cell 中只能存储一个bit。这些cell 以8 个或许16 个为单位,连成bit line,构成所谓的byte(x8)/word(x16),这便是NAND Device 的位宽。这些Line 会再组成Page.

NandFlash有多种结构,我运用的NandFlash是K9F1208,下面内容针对三星的K9F1208U0M,数据存储容量为64MB,选用块页式存储办理。一共有4096个block(块),每个block有32个page(页),每个page有528Byte。

1block=32page,1page=528byte=512byte(MainArea)+16byte(SpareArea)

Nandflash以页为单位读写数据,而以块为单位擦除数据。

依照这样的安排办法能够构成所谓的三类地址:

–BlockAddressPageAddress–ColumnAddress

关于NANDFlash来讲,8个I/O引脚充任数据、地址、指令的复用端口。地址和指令只能在I/O[7:0]上传递,数据宽度是8位。

512byte需求9bit来表明,关于528byte系列的NAND,这512byte被分红1sthalf2ndhalf,最终16个字节(又称OOB)用于NandFlash指令履行完后设置状况用,各自的拜访由地址指针指令来挑选,A[7:0]便是所谓的columnaddress。

32个page需求5bit来表明,占用A[13:9],即该page在块内的相对地址。Block的地址是由A14以上的bit来表明,例如512Mb的NAND,共4096block,因而,需求12个bit来表明,即A[25:14],假如是1Gbit的528byte/page的NANDFlash,则blockaddress用A[26:14]表明。

NANDFlash的地址表明为:

BlockAddress|PageAddressinblock|halfpagepointer|ColumnAddress

地址传送次序是ColumnAddress,PageAddress,BlockAddress。

因为地址只能在I/O[7:0]上传递,因而,有必要传递屡次。例如,关于512Mbitx8的NANDflash,地址规模是0-0x3FFFFFF,只需是这个规模内的数值表明的地址都是有用的。以NAND_ADDR为例:第1步是传递columnaddress,便是NAND_ADDR[7:0]给相应的寄存器,即可传递到I/O[7:0]上,而halfpagepointer即bit8是由操作指令决议的,即指令决议在哪个halfpage上进行读写。而真实的bit8的值是dontcare的。第2步便是将NAND_ADDR[16:9]传到I/O[7:0]上。第3步将NAND_ADDR[24:17]放到I/O上。第4步需求将NAND_ADDR[25]放到I/O因而,整个地址传递进程需求4步才干完结,即4-stepaddressing。假如NANDFlash的容量是256Mbit以下,那么,blockadress最高位只到bit24,因而寻址只需求3步。下面,就x16(16位)的NANDflash器材略微进行一下阐明。因为一个page的mainarea的容量为256word,仍相当于512byte。可是,这个时分没有所谓的1sthalfpage和2ndhalfpage之分了,所以,bit8就变得没有意义了,也便是这个时分bit8彻底不必管,地址传递依然和x8器材相同。除了,这一点之外,x16的NAND运用办法和x8的运用办法彻底相同。

正如硬盘的盘片被分为磁道,每个磁道又分为若干扇区,一块nandflash也分为若干block,每个block分为如干page。一般来说,block、page之间的联系跟着芯片的不同而不同,典型的分配是这样的:
1block=32page
1page=512bytes(datafield)+16bytes(oob)

需求留意的是,关于flash的读写都是以一个page开端的,可是在读写之前有必要进行flash的擦写,而擦写则是以一个block为单位的。一起有必要提示的是,512bytes理论上被分为1sthalf和2sdhalf,每个half各占256个字节。

咱们评论的K9F1208U0B一共有4096个Blocks,故咱们能够知道这块flash的容量为4096*(32*528)=69206016Bytes=66MB。但事实上每个Page上的最终16Bytes是用于存贮检验码和其他信息用的,并不能寄存实践的数据,所以实践上咱们能够操作的芯片容量为4096*(32*512)=67108864Bytes=64MB。

由上图所示,1个Page一共由528Bytes组成,这528个字节按次序由上而下以列为单位进行摆放(1列代表一个Byte。第0行为第0Byte,第1行为第1Byte,以此类推,每个行又由8个位组成,每个位表明1个Byte里边的1bit)。这528Bytes按功用分为两大部分,分别是DataField和SpareField,其间SpareField占528Bytes里的16Bytes,这16Bytes是用于在读写操作的时分寄存校验码用的,一般不必做一般数据的存储区,除掉这16Bytes,剩余的512Bytes便是咱们用于寄存数据用的DataField,所以一个Page上虽然有528个Bytes,但咱们只按512Bytes进行容量的核算。

读指令有两个,分别是Read1,Read2其间Read1用于读取DataField的数据,而Read2则是用于读取SpareField的数据。关于NandFlash来说,读操作的最小操作单位为Page,也便是说当咱们给定了读取的开端方位后,读操作将从该方位开端,接连读取到本Page的最终一个Byte停止(能够包含SpareField)

NandFlash的寻址
NandFlash的地址寄存器把一个完好的NandFlash地址分解成ColumnAddress与PageAddress.进行寻址。

ColumnAddress:列地址。ColumnAddress其实便是指定Page上的某个Byte,指定这个Byte其实也便是指定此页的读写开端地址。

PaageAddress:页地址。因为页地址总是以512Bytes对齐的,所以它的低9位总是0。确认读写操作是在Flash上的哪个页进行的。

Read1指令

当咱们得到一个NandFlash地址addr时咱们能够这样分解出ColumnAddress和PageAddress
column_addr=src_addrQ2;//columnaddress
page_address=(src_addr>>9);//pageaddress

也能够这么以为,一个NandFlash地址的src_addr[7,0]是它的column_addr,addr[25,9]是它的PageAddress。(留意地址位src_addr[8]并没有呈现,也便是addr[8]被疏忽,在下面你将了解到这是什么原因)

Read1指令的操作发送完读指令00h或01h(00h与01h的差异请见下文描绘)之后将分4个Cycle发送参数,1st.Cycle是发送ColumnAddress。2nd.Cycle,3rd.Cycle和4th.Cycle则是指定PageAddress(每次向地址寄存器发送的数据只能是8位,所以17位的PageAddress有必要分红3次进行发送。

Read1的指令里边呈现了两个指令选项,分别是00h和01h。这儿呈现了两个读命是否令你意识到什么呢?是的,00h是用于读写1sthalf的指令,而01h是用于读取2ndhalf的指令。现在我能够结合上图给你阐明为什么K9F1208U0B的DataField被分为2个half了。

如上文我所提及的,Read1的1st.Cycle是发送ColumnAddress,假定我现在指定的ColumnAddress是0,那么读操作将从此页的第0号Byte开端一向读取到此页的最终一个Byte(包含SpareField),假如我指定的ColumnAddress是127,状况也与前面相同,但不知道你发现没有,用于传递ColumnAddress的数据线有8条(I/O0-I/O7,对应addr[7,0],这也是addr[8]为什么不呈现在咱们传递的地址位中),也便是说咱们能够指定的ColumnAddress规模为0-255,但不要忘了,1个Page的DataField是由512个Byte组成的,假定现在我要指定读指令从第256个字节处开端读取此页,那将会发生什么情形?我有必要把ColumnAddress设置为256,但ColumnAddress最大只能是255,这就形成数据溢出。正是因为这个原因咱们才把DataField分为两个半区,当要读取的开端地址(ColumnAddress)在0-255内时咱们用00h指令,当读取的开端地址是在256-511时,则运用01h指令.假定现在我要指定从第256个byte开端读取此页,那么我将这样发送指令串。
column_addr=256;
NF_CMD=0x01;从2ndhalf开端读取
NF_ADDR=column_addr&0xff;1stCycle
NF_ADDR=page_address&0xff;2nd.Cycle
NF_ADDR=(page_address>>8)&0xff;3rd.Cycle
NF_ADDR=(page_address>>16)&0xff;4th.Cycle

NF_CMD=0x30;

事实上,当NF_CMD=0x01时,NANDFlash地址寄存器中的第8位(A8)将被设置为1(如上文剖析,A8位不在咱们传递的地址中,这个位其实便是硬件电路依据01h或是00h这两个指令来置高位或是置低位),这样咱们传递column_addr的值256随然因为数据溢出变为1,但A8位现已因为NF_CMD=0x01的联系被置为1了。这8个位所表明的正好是256,这样读操作将从此页的第256号byte(2ndhalf的第0号byte)开端读取数据。

在对NANDFlash进行任何操作之前,NANDFlash有必要被初始化。向NandFlash的指令寄存器和地址寄存器发送完以上指令和参数之后,咱们就能够从rNFDATA寄存器(NandFlash数据寄存器)读取数据了.
我用下面的代码进行数据的读取.
for(i=column_addr;i<512;i++)
{
*buf++=NF_RDDATA();
}

每逢读取完一个Page之后,数据指针会落在下一个Page的0号Column(0号Byte).

存储操作特色:
1.擦除操作的最小单位是块。
2.NandFlash芯片每一位(bit)只能从1变为0,而不能从0变为1,所以在对其进行写入操作之前要一定将相应块擦除(擦除便是将相应块得位悉数变为1).
3.OOB部分的第六字节(即517字节)标志是否是坏块,假如不是坏块该值为FF,否则为坏块。
4.除OOB第六字节外,一般至少把OOB的前3个字节寄存NandFlash硬件ECC码(关于硬件ECC码请参看Nandflash操控器一节).

重要芯片引脚功用
I/O0-I/O7:复用引脚。能够经过它向nandflash芯片输入数据、地址、nandflash指令以及输出数据和操作状况信息。
CLE(CommandLatchEnable):指令锁存答应
ALE(AddressLactchEnable):地址锁存答应
-CE:芯片挑选
-RE:读答应
-WE:写答应
-WP:在写或擦除期间,供给写保护
R/-B:读/忙输出


NandFlash操控器中的硬件ECC介绍

ECC发生办法

ECC是用于对存储器之间传送数据正确进行校验的一种算法,分硬件ECC和软件ECC算法两种,在S3C2440的NandFlash操控器中完结了由硬件电路(ECC生成器)完结的硬件ECC

ECC生成器作业进程
当写入数据到Nandflash存储空间时,ECC生成器会在写入数据结束后主动生成ECC码,将其放入到ECC0-ECC2。当读出数据时NandFlash同样会在读数据结束后,主动生成ECC码将其放到ECC0-ECC2傍边。

ECC的运用

当写入数据时,能够在每页写完数据后将发生的ECC码放入到OOB指定的方位(Byte6)去,这样就完结了ECC码的存储。这样当读出该页数据时,将所需数据以及整个OOB读出,然后将指定方位的ECC码与读出数据后在ECC0-ECC1的实践发生的ECC码进行比照,假如持平则读出正确,若不持平则读取过错需求进行重读。

  操作指令字介绍

操作NAND FLASH时,先传输指令,接着输出地址,最终读/写数据,期间还要检查FLASH的状况。详细的指令字见下表。


  1、Read指令字为00h,30h。

  如上图,当宣布00h指令后,接着4个字节的地址序列,然后再宣布30h指令,接着,就能够读出数据了,当发送完30h后,能够检测R/B引脚看是否预备好了,假如预备好,就能够读出数据。

  2、Reset

  指令字:FFh

  当向芯片发送FFh指令时,能够复位芯片,假如芯片正在处于读、写、擦除状况,复位指令会停止这些指令。

3、Page Program

  指令字:80h,10h.

  NAND FLASH的写操作一般是以页为单位进行的,因而才会叫Page Program,可是也支撑一个字以上的(包含一个字)接连写操作。开端宣布80h指令,接着发送5个字节的地址序列,然后向FLASH发送数据,最大为一页巨细,最终发送10h指令发动烧写,此刻FLASH内部会主动完结写、校验操作。发送10h后,能够经过读状况指令70h(见下文)获悉写操作是否完结,是否成功。

4、Copy-Back Program

  指令字:00h、8Ah、10h.

  此指令用于将一页复制到同一层的别的一页,它省去了读出数据、将数据从头载入FLASH的进程,使得功率大大提高。

  关于层:NAND FLASH有层的概念,K9F2G08分为两层,每层包含了1024个块,如下图,因而上面的指令表中才会有two-plane的指令,这些指令能够使得在两个层间完结操作,这样程序员就很便利的运用一个指令完结更多的操作,其指令格局和单层操作的相似,详见手册。但K9F2G08R0A不支撑两层指令。

  上图明晰的告知咱们,开端发送00h和源地址,当发送35h之后,芯片将一页巨细的数据读入到内部寄存器,接着,咱们发送85h和意图地址序列,最终发送10h发动。最终,咱们能够运用70h/7Bh检测是否完结,是否成功。

  5、Block Erase

  指令字:60h、D0h

  擦除操作是以块为单位的,也便是128K。开端宣布60h,然后宣布3个地址序列仅行地址,最好宣布D0h。详细操作,如下图。

  6、Read Status

   指令字:70h

   读状况指令能够读出芯片的状况寄存器,检查是否读、写操作是否完结、是否成功。详细的状况见下图。

  S3C2440的NAND FLASH操控器介绍

  看了上面的指令时序图,咱们必定以为对NAND FLASH的操作比较复杂,因而S3C2440为了简化操作,为咱们供给了几个寄存器,比方NFCMD寄存器,便是NAND FLASH指令寄存器,假如咱们需求读指令,直接向此寄存器写00h、30h即可。

  根本操作过程:

  1.设置NFCONF和NFCONT寄存器,装备NAND FLASH;

  2.向NFCMD寄存器写入指令;

  3.向NFADDR寄存器写入地址;

  4.读/写数据,经过NFSTAT检测NAND FLASH的状况,读R/nB信号以确认是否完结操作,是否成功。

  首要寄存器:

  (NFCONF)

  装备寄存器,设置NAND FLASH的时序参阅TACLS、TWRPH0、TWRPH1,这三个参数见下面时序图;设置位宽度;还包含一些只读位,用来指示是否支撑其它巨细的页。

  TACLS:表明CLT/ALE的树立时刻(setup time)。

  TWRPH0:表明CLE/ALE的持续时刻。

  TWRPH1:表明CLE/ALE的保持时刻(hold time)。

NFCONT

  用来使能/制止NAND FLASH操控器、使能/制止操控引脚信号nFCE、初始化ECC。

  NFCMD

  指令寄存器,用来向其写入指令。

  NFADDR

  地址寄存器,用来向其写入地址。

  NFDATA

  数据寄存器,用来读、写数据运用,只用到8位。

  NFSTAT

  状况寄存器,只用到一位,0:busy;1:ready。

   NFECC

  校验寄存器,ECC 校验寄存器

  NAND FLASH的操作(以读为例)

  

  1、设置NFCONF和NFCONT

  NFCONF首要是设置TACLS、TWRPH0、TWRPH1三个时刻参数。依据手册的参数表,见下图:

  三个参数只需最小值 MIN,没有最大值,因而,只需参数大于表格中的数即可,这儿触及时钟的一些概念,这儿直接将参数告知咱们:

  TACLS=1;TWRPH0=4;TWRPH1=0。

  NFCONT设置为:NFCONT=(1<<4)|(1<<1)|(1<<0) 表明使能NAND FLASH操控器、制止操控引脚信号nFCE、初始化ECC。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/adas/276529.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部