<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 對S3C2440讀取NAND Flash的總結

對S3C2440讀取NAND Flash的總結

作者: 時(shí)間:2016-11-09 來(lái)源:網(wǎng)絡(luò ) 收藏
在網(wǎng)上找了一些資料,又結合自己的經(jīng)歷談一下我對NAND Flash 的了解。

S3C2440 板的Nand Flash 支持由兩部分組成:Nand Flash 控制器(集成在S3C2440 CPU)和Nand Flash 存儲芯片(K9F1208U0B)兩大部分組成。當要訪(fǎng)問(wèn)Nand Flash中的數據時(shí),必須通過(guò)Nand Flash控制器發(fā)送命令才能完成。所以, Nand Flash相當于S3C2440的一個(gè)外設,而不位于它的內存地址區.

本文引用地址:http://dyxdggzs.com/article/201611/317616.htm

NAND Flash 的數據是以bit 的方式保存在memory cell,一般來(lái)說(shuō),一個(gè)cell 中只能存儲一個(gè)bit。這些cell 以8 個(gè)或者16 個(gè)為單位,連成bit line,形成所謂的byte(x8)/word(x16),這就是NAND Device 的位寬。這些Line 會(huì )再組成Page.

NandFlash有多種結構,我使用的NandFlash是K9F1208,下面內容針對三星的K9F1208U0M,數據存儲容量為64MB,采用塊頁(yè)式存儲管理。一共有4096個(gè)block(塊),每個(gè)block有32個(gè)page(頁(yè)),每個(gè)page有528Byte。

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

Nandflash以頁(yè)為單位讀寫(xiě)數據,而以塊為單位擦除數據。

按照這樣的組織方式可以形成所謂的三類(lèi)地址:

--BlockAddress--PageAddress--ColumnAddress

對于NANDFlash來(lái)講,8個(gè)I/O引腳充當數據、地址、命令的復用端口。地址和命令只能在I/O[7:0]上傳遞,數據寬度是8位。

512byte需要9bit來(lái)表示,對于528byte系列的NAND,這512byte被分成1sthalf2ndhalf,最后16個(gè)字節(又稱(chēng)OOB)用于NandFlash命令執行完后設置狀態(tài)用,各自的訪(fǎng)問(wèn)由地址指針命令來(lái)選擇,A[7:0]就是所謂的columnaddress。

32個(gè)page需要5bit來(lái)表示,占用A[13:9],即該page在塊內的相對地址。Block的地址是由A14以上的bit來(lái)表示,例如512Mb的NAND,共4096block,因此,需要12個(gè)bit來(lái)表示,即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,只要是這個(gè)范圍內的數值表示的地址都是有效的。以NAND_ADDR為例:第1步是傳遞columnaddress,就是NAND_ADDR[7:0]給相應的寄存器,即可傳遞到I/O[7:0]上,而halfpagepointer即bit8是由操作指令決定的,即指令決定在哪個(gè)halfpage上進(jìn)行讀寫(xiě)。而真正的bit8的值是dontcare的。第2步就是將NAND_ADDR[16:9]傳到I/O[7:0]上。第3步將NAND_ADDR[24:17]放到I/O上。第4步需要將NAND_ADDR[25]放到I/O因此,整個(gè)地址傳遞過(guò)程需要4步才能完成,即4-stepaddressing。如果NANDFlash的容量是256Mbit以下,那么,blockadress最高位只到bit24,因此尋址只需要3步。下面,就x16(16位)的NANDflash器件稍微進(jìn)行一下說(shuō)明。由于一個(gè)page的mainarea的容量為256word,仍相當于512byte。但是,這個(gè)時(shí)候沒(méi)有所謂的1sthalfpage和2ndhalfpage之分了,所以,bit8就變得沒(méi)有意義了,也就是這個(gè)時(shí)候bit8完全不用管,地址傳遞仍然和x8器件相同。除了,這一點(diǎn)之外,x16的NAND使用方法和x8的使用方法完全相同。

正如硬盤(pán)的盤(pán)片被分為磁道,每個(gè)磁道又分為若干扇區,一塊nandflash也分為若干block,每個(gè)block分為如干page。一般而言,block、page之間的關(guān)系隨著(zhù)芯片的不同而不同,典型的分配是這樣的:
1block=32page
1page=512bytes(datafield)+16bytes(oob)

需要注意的是,對于flash的讀寫(xiě)都是以一個(gè)page開(kāi)始的,但是在讀寫(xiě)之前必須進(jìn)行flash的擦寫(xiě),而擦寫(xiě)則是以一個(gè)block為單位的。同時(shí)必須提醒的是,512bytes理論上被分為1sthalf和2sdhalf,每個(gè)half各占256個(gè)字節。

我們討論的K9F1208U0B總共有4096個(gè)Blocks,故我們可以知道這塊flash的容量為4096*(32*528)=69206016Bytes=66MB。但事實(shí)上每個(gè)Page上的最后16Bytes是用于存貯檢驗碼和其他信息用的,并不能存放實(shí)際的數據,所以實(shí)際上我們可以操作的芯片容量為4096*(32*512)=67108864Bytes=64MB。

由上圖所示,1個(gè)Page總共由528Bytes組成,這528個(gè)字節按順序由上而下以列為單位進(jìn)行排列(1列代表一個(gè)Byte。第0行為第0Byte,第1行為第1Byte,以此類(lèi)推,每個(gè)行又由8個(gè)位組成,每個(gè)位表示1個(gè)Byte里面的1bit)。這528Bytes按功能分為兩大部分,分別是DataField和SpareField,其中SpareField占528Bytes里的16Bytes,這16Bytes是用于在讀寫(xiě)操作的時(shí)候存放校驗碼用的,一般不用做普通數據的存儲區,除去這16Bytes,剩下的512Bytes便是我們用于存放數據用的DataField,所以一個(gè)Page上雖然有528個(gè)Bytes,但我們只按512Bytes進(jìn)行容量的計算。

讀命令有兩個(gè),分別是Read1,Read2其中Read1用于讀取DataField的數據,而Read2則是用于讀取SpareField的數據。對于NandFlash來(lái)說(shuō),讀操作的最小操作單位為Page,也就是說(shuō)當我們給定了讀取的起始位置后,讀操作將從該位置開(kāi)始,連續讀取到本Page的最后一個(gè)Byte為止(可以包括SpareField)

NandFlash的尋址
NandFlash的地址寄存器把一個(gè)完整的NandFlash地址分解成ColumnAddress與PageAddress.進(jìn)行尋址。

ColumnAddress:列地址。ColumnAddress其實(shí)就是指定Page上的某個(gè)Byte,指定這個(gè)Byte其實(shí)也就是指定此頁(yè)的讀寫(xiě)起始地址。

PaageAddress:頁(yè)地址。由于頁(yè)地址總是以512Bytes對齊的,所以它的低9位總是0。確定讀寫(xiě)操作是在Flash上的哪個(gè)頁(yè)進(jìn)行的。

Read1命令

當我們得到一個(gè)NandFlash地址addr時(shí)我們可以這樣分解出ColumnAddress和PageAddress
column_addr=src_addrQ2;//columnaddress
page_address=(src_addr>>9);//pageaddress

也可以這么認為,一個(gè)NandFlash地址的src_addr[7,0]是它的column_addr,addr[25,9]是它的PageAddress。(注意地址位src_addr[8]并沒(méi)有出現,也就是addr[8]被忽略,在下面你將了解到這是什么原因)

Read1命令的操作發(fā)送完讀命令00h或01h(00h與01h的區別請見(jiàn)下文描述)之后將分4個(gè)Cycle發(fā)送參數,1st.Cycle是發(fā)送ColumnAddress。2nd.Cycle,3rd.Cycle和4th.Cycle則是指定PageAddress(每次向地址寄存器發(fā)送的數據只能是8位,所以17位的PageAddress必須分成3次進(jìn)行發(fā)送。

Read1的命令里面出現了兩個(gè)命令選項,分別是00h和01h。這里出現了兩個(gè)讀命是否令你意識到什么呢?是的,00h是用于讀寫(xiě)1sthalf的命令,而01h是用于讀取2ndhalf的命令?,F在我可以結合上圖給你說(shuō)明為什么K9F1208U0B的DataField被分為2個(gè)half了。

如上文我所提及的,Read1的1st.Cycle是發(fā)送ColumnAddress,假設我現在指定的ColumnAddress是0,那么讀操作將從此頁(yè)的第0號Byte開(kāi)始一直讀取到此頁(yè)的最后一個(gè)Byte(包括SpareField),如果我指定的ColumnAddress是127,情況也與前面一樣,但不知道你發(fā)現沒(méi)有,用于傳遞ColumnAddress的數據線(xiàn)有8條(I/O0-I/O7,對應addr[7,0],這也是addr[8]為什么不出現在我們傳遞的地址位中),也就是說(shuō)我們能夠指定的ColumnAddress范圍為0-255,但不要忘了,1個(gè)Page的DataField是由512個(gè)Byte組成的,假設現在我要指定讀命令從第256個(gè)字節處開(kāi)始讀取此頁(yè),那將會(huì )發(fā)生什么情景?我必須把ColumnAddress設置為256,但ColumnAddress最大只能是255,這就造成數據溢出。正是因為這個(gè)原因我們才把DataField分為兩個(gè)半區,當要讀取的起始地址(ColumnAddress)在0-255內時(shí)我們用00h命令,當讀取的起始地址是在256-511時(shí),則使用01h命令.假設現在我要指定從第256個(gè)byte開(kāi)始讀取此頁(yè),那么我將這樣發(fā)送命令串。
column_addr=256;
NF_CMD=0x01;從2ndhalf開(kāi)始讀取
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;

事實(shí)上,當NF_CMD=0x01時(shí),NANDFlash地址寄存器中的第8位(A8)將被設置為1(如上文分析,A8位不在我們傳遞的地址中,這個(gè)位其實(shí)就是硬件電路根據01h或是00h這兩個(gè)命令來(lái)置高位或是置低位),這樣我們傳遞column_addr的值256隨然由于數據溢出變?yōu)?,但A8位已經(jīng)由于NF_CMD=0x01的關(guān)系被置為1了。這8個(gè)位所表示的正好是256,這樣讀操作將從此頁(yè)的第256號byte(2ndhalf的第0號byte)開(kāi)始讀取數據。

在對NANDFlash進(jìn)行任何操作之前,NANDFlash必須被初始化。向NandFlash的命令寄存器和地址寄存器發(fā)送完以上命令和參數之后,我們就可以從rNFDATA寄存器(NandFlash數據寄存器)讀取數據了.
我用下面的代碼進(jìn)行數據的讀取.
for(i=column_addr;i<512;i++)
{
*buf++=NF_RDDATA();
}

每當讀取完一個(gè)Page之后,數據指針會(huì )落在下一個(gè)Page的0號Column(0號Byte).

存儲操作特點(diǎn):
1.擦除操作的最小單位是塊。
2.NandFlash芯片每一位(bit)只能從1變?yōu)?,而不能從0變?yōu)?wbr />1,所以在對其進(jìn)行寫(xiě)入操作之前要一定將相應塊擦除(擦除即是將相應塊得位全部變?yōu)?wbr />1).
3.OOB部分的第六字節(即517字節)標志是否是壞塊,如果不是壞塊該值為FF,否則為壞塊。
4.除OOB第六字節外,通常至少把OOB的前3個(gè)字節存放NandFlash硬件ECC碼(關(guān)于硬件ECC碼請參看Nandflash控制器一節).

重要芯片引腳功能
I/O0-I/O7:復用引腳??梢酝ㄟ^(guò)它向nandflash芯片輸入數據、地址、nandflash命令以及輸出數據和操作狀態(tài)信息。
CLE(CommandLatchEnable):命令鎖存允許
ALE(AddressLactchEnable):地址鎖存允許
-CE:芯片選擇
-RE:讀允許
-WE:寫(xiě)允許
-WP:在寫(xiě)或擦除期間,提供寫(xiě)保護
R/-B:讀/忙輸出


NandFlash控制器中的硬件ECC介紹

ECC產(chǎn)生方法

ECC是用于對存儲器之間傳送數據正確進(jìn)行校驗的一種算法,分硬件ECC和軟件ECC算法兩種,在S3C2440的NandFlash控制器中實(shí)現了由硬件電路(ECC生成器)實(shí)現的硬件ECC。

ECC生成器工作過(guò)程
當寫(xiě)入數據到Nandflash存儲空間時(shí),ECC生成器會(huì )在寫(xiě)入數據完畢后自動(dòng)生成ECC碼,將其放入到ECC0-ECC2。當讀出數據時(shí)NandFlash同樣會(huì )在讀數據完畢后,自動(dòng)生成ECC碼將其放到ECC0-ECC2當中。

ECC的運用

當寫(xiě)入數據時(shí),可以在每頁(yè)寫(xiě)完數據后將產(chǎn)生的ECC碼放入到OOB指定的位置(Byte6)去,這樣就完成了ECC碼的存儲。這樣當讀出該頁(yè)數據時(shí),將所需數據以及整個(gè)OOB讀出,然后將指定位置的ECC碼與讀出數據后在ECC0-ECC1的實(shí)際產(chǎn)生的ECC碼進(jìn)行對比,如果相等則讀出正確,若不相等則讀取錯誤需要進(jìn)行重讀。

  操作命令字介紹

操作NAND FLASH時(shí),先傳輸命令,接著(zhù)輸出地址,最后讀/寫(xiě)數據,期間還要檢查FLASH的狀態(tài)。具體的命令字見(jiàn)下表。


  1、Read命令字為00h,30h。

  如上圖,當發(fā)出00h命令后,接著(zhù)4個(gè)字節的地址序列,然后再發(fā)出30h命令,接著(zhù),就可以讀出數據了,當發(fā)送完30h后,可以檢測R/B引腳看是否準備好了,如果準備好,就可以讀出數據。

  2、Reset

  命令字:FFh

  當向芯片發(fā)送FFh命令時(shí),可以復位芯片,如果芯片正在處于讀、寫(xiě)、擦除狀態(tài),復位命令會(huì )終止這些命令。

3、Page Program

  命令字:80h,10h.

  NAND FLASH的寫(xiě)操作一般是以頁(yè)為單位進(jìn)行的,因此才會(huì )叫Page Program,但是也支持一個(gè)字以上的(包括一個(gè)字)連續寫(xiě)操作。開(kāi)始發(fā)出80h命令,接著(zhù)發(fā)送5個(gè)字節的地址序列,然后向FLASH發(fā)送數據,最大為一頁(yè)大小,最后發(fā)送10h命令啟動(dòng)燒寫(xiě),此時(shí)FLASH內部會(huì )自動(dòng)完成寫(xiě)、校驗操作。發(fā)送10h后,可以通過(guò)讀狀態(tài)命令70h(見(jiàn)下文)獲知寫(xiě)操作是否完成,是否成功。

4、Copy-Back Program

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

  此命令用于將一頁(yè)復制到同一層的另外一頁(yè),它省去了讀出數據、將數據重新載入FLASH的過(guò)程,使得效率大大提高。

  關(guān)于層:NAND FLASH有層的概念,K9F2G08分為兩層,每層包括了1024個(gè)塊,如下圖,因此上面的命令表中才會(huì )有two-plane的命令,這些命令可以使得在兩個(gè)層間完成操作,這樣程序員就很方便的使用一個(gè)命令完成更多的操作,其命令格式和單層操作的類(lèi)似,詳見(jiàn)手冊。但K9F2G08R0A不支持兩層命令。




  上圖清晰的告訴我們,開(kāi)始發(fā)送00h和源地址,當發(fā)送35h之后,芯片將一頁(yè)大小的數據讀入到內部寄存器,接著(zhù),我們發(fā)送85h和目的地址序列,最后發(fā)送10h啟動(dòng)。最后,我們可以使用70h/7Bh檢測是否完成,是否成功。

  5、Block Erase

  命令字:60h、D0h

  擦除操作是以塊為單位的,也就是128K。開(kāi)始發(fā)出60h,然后發(fā)出3個(gè)地址序列僅行地址,最好發(fā)出D0h。具體操作,如下圖。


  6、Read Status

   命令字:70h

   讀狀態(tài)命令可以讀出芯片的狀態(tài)寄存器,查看是否讀、寫(xiě)操作是否完成、是否成功。具體的狀態(tài)見(jiàn)下圖。


  S3C2440的NAND FLASH控制器介紹

  看了上面的命令時(shí)序圖,大家肯定認為對NAND FLASH的操作比較復雜,因此S3C2440為了簡(jiǎn)化操作,為我們提供了幾個(gè)寄存器,比如NFCMD寄存器,就是NAND FLASH命令寄存器,如果我們需要讀命令,直接向此寄存器寫(xiě)00h、30h即可。

  基本操作步驟:

  1.設置NFCONF和NFCONT寄存器,配置NAND FLASH;

  2.向NFCMD寄存器寫(xiě)入命令;

  3.向NFADDR寄存器寫(xiě)入地址;

  4.讀/寫(xiě)數據,通過(guò)NFSTAT檢測NAND FLASH的狀態(tài),讀R/nB信號以確定是否完成操作,是否成功。

  主要寄存器:

  (NFCONF)

  配置寄存器,設置NAND FLASH的時(shí)序參考TACLS、TWRPH0、TWRPH1,這三個(gè)參數見(jiàn)下面時(shí)序圖;設置位寬度;還包括一些只讀位,用來(lái)批示是否支持其它大小的頁(yè)。

  TACLS:表示CLT/ALE的建立時(shí)間(setup time)。

  TWRPH0:表示CLE/ALE的持續時(shí)間。

  TWRPH1:表示CLE/ALE的維持時(shí)間(hold time)。




NFCONT

  用來(lái)使能/禁止NAND FLASH控制器、使能/禁止控制引腳信號nFCE、初始化ECC。

  NFCMD

  命令寄存器,用來(lái)向其寫(xiě)入命令。

  NFADDR

  地址寄存器,用來(lái)向其寫(xiě)入地址。

  NFDATA

  數據寄存器,用來(lái)讀、寫(xiě)數據使用,只用到8位。

  NFSTAT

  狀態(tài)寄存器,只用到一位,0:busy;1:ready。

   NFECC

  校驗寄存器,ECC 校驗寄存器

  NAND FLASH的操作(以讀為例)

  

  1、設置NFCONF和NFCONT

  NFCONF主要是設置TACLS、TWRPH0、TWRPH1三個(gè)時(shí)間參數。根據手冊的參數表,見(jiàn)下圖:


  三個(gè)參數只有最小值 MIN,沒(méi)有最大值,因此,只要參數大于表格中的數即可,這里涉及時(shí)鐘的一些概念,這里直接將參數告訴大家:

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

  NFCONT設置為:NFCONT=(1<<4)|(1<<1)|(1<<0) 表示使能NAND FLASH控制器、禁止控制引腳信號nFCE、初始化ECC。



關(guān)鍵詞: S3C2440NANDFLAS

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>