Nand Flash原理分析與編程

NAND Flash 在嵌入式系統中的地位與PC機上的硬盤是類似的。用於保存系統運行所必需的操作系統,應用程序,用戶數據,運行過程中產生的各類數據,系統掉電後數據不會護丟失.本文主要介紹關於NAND Flash的組織結構和編寫程序的方法。
       在三星的NAND Flash 中,當CPU從NAND Flash開始啓動時,CPU會通過內部的硬件將NAND Flash開始的4KB數據複製到稱爲“Steppingstone”的4KB的內部RAM中,起始地址爲0,然後跳到地址0處開始執行。這也就是我們爲什麼可以把小於4KB的程序燒到NAND Flash中,可以運行,而當大於4KB時,卻沒有辦法運行,必須藉助於NAND Flash的讀操作,讀取4KB以後的程序到內存中。
NAND Flash的尋址方式和NAND Flash的memory組織方式緊密相關。NAND Flash的數據是以bit的方式保存在 memory cell(存儲單元)。一般情況下,一個cell中只能存儲一個bit。這些cell以8個或者16個爲單位,連成 bit line ,形成所謂的byte(x8)/word(x16),這就是NAND Flash的位寬。
這些Line會再組成Pape(頁)。然後是每32個page形成一個Block,所以一個Block(塊)大小是16k.Block是NAND Flash中最大的操作單元,其中的擦除操作是以Block爲單位進行擦除的,而讀寫和編程是以page爲單位進行操作的,並且讀寫之前必須進行flash的擦寫。我們這裏以三星K9F1208U0M的NAND Flash 爲例,它的大小是64MB的。
1block = 32page
1page = 512bytes(datafield) + 16bytes(oob)
K9F1208U0B總共有4096 個Blocks,故我們可以知道這塊flash的容量爲4096 *(32 *528)= 69206016 Bytes = 66 MB
但事實上每個Page上的最後16Bytes是用於存貯檢驗碼用的,並不能存放實際的數據,所以實際上我們可以操作的芯片容量爲
4096 *(32 *512) = 67108864 Bytes = 64 MB
Nand Flash 物理結構圖
在NAND Flash中有8個I/O引腳(IO0—IO7)、5個全能信號(nWE ALE CLE nCE nRE)、一個引腳,1個寫保護引腳。操作NAND Flash時,先傳輸命令,然後傳輸地址,最後讀寫數據。對於64MB的NAND Flash,需要一個26位的地址。只能8個I/O引腳充當地址、數據、命令的複用端口,所以每次傳地址只能傳8位。這樣就需要4個地址序列。因此讀寫一次nand flash需要傳送4次(A[7:0] A[16:9] A[24:17] A[25])。64M的NAND Flash的地址範圍爲0x00000000—0x03FFFFFF。
一頁有528個字節,而在前512B中存放着用戶的數據。在後面的16字節中(OOB)中存放着執行命令後的狀態信息。主要是ECC校驗的標識。列地址A0-A7可以尋址的範圍是256個字節,要尋址528字節的話,將一頁分爲了A.(1half array)B(2 half array) C(spare array)。A區0—255字節,B區 256-511 字節C區512—527字節。訪問某頁時必須選定特定的區。這可以使地址指針指向特定的區實現。
在NAND Flash 中存在三類地址,分別爲Block Address 、Column Address Page Address.。
Column Address 用來選擇是在上半頁尋址還是在下半頁尋址A[0]—A[7].也就相當於頁內的偏移地址。在進行擦除時不需要列地址,因爲擦除是以塊爲單位擦除。32個Page需要5bit來表示。也就是A[13:9];也就是頁在塊內的相對地址。A8這一位用來設置512字節的上半頁,還是下半頁,1表示是在上半頁,而2表示是在下半頁。Block的地址有A[25:14]組成。
存儲操作特點:
1.擦除操作的最小單位是塊
2.Nand Flash芯片每一位只能從1變爲0,而不能從0變爲1,所以在對其進行寫入操作之前一定要將相應塊擦除(擦除就是將相應塊的位全部變爲1
3 OOB部分的第六字節(即517字節)標誌是否壞塊,如果不是壞塊該值爲FF,否則爲壞塊
4 除OOB第六字節外,通常至少把OOB前3字節存放Nand Flash硬件ECC碼
一個容量爲64M(512Mbit)的NAND Flash,分爲131072頁,528列。(實際中由於存在spare area,故都大於這個值),有4096塊,需要12bit來表示即A[25:14].如果是128M(1Gbit)的話,blodk Address爲A[26:14].由於地址只能在IO0—IO7上傳送。編程時通常通過移位來實現地址的傳送。傳送過程如下:
第1個地址序列:傳遞column address,也就是NAND Flash[7:0],這一週期不需要移位即可傳遞到I/O[7:0]上,而half page pointer 即A8是由操作指令決定,00h,在A區,01h在B區,指令決定在哪個half page上進行讀寫,而真正A8的值是不需要程序員關心的;
第2個地址序列:就是將NAND_ADDR 右移9位,而不是8位,將NAND_ADDR[16:9]傳遞到I/O[7:0]上;
第3個地址序列:將NAND_ADDR[24:17] 傳遞到I/O[7:0]上;
第4個地址序列:將NAND_ADDR[25]傳送到I/O上。
整個地址的傳送過程需要4步才能完成。如果NAND Flash 的大小是32MB的以下的話,那麼block address 最高位只到bit24,因此尋址只需要3步,就可以完成。
在進行擦除操作時由於是以塊進行擦除,所以只需要3個地址序列,也就是隻傳遞塊的地址,即A[14:25]。
NAND Flash地址的計算:
Column Address 翻譯過來是列地址,也就是在一頁裏的偏移地址。其實是指定Page上的某個Byte,指定這個Byte,其實也就是指定此頁的讀寫起始地址。
Page Address:頁地址。頁的地址總是以512Bytes對齊的,所以它的低9位問題0,確定讀寫操作在NAND Flash中的哪個頁進行。
當我們得到一個Nand Flash地址addr時,我們可以這樣分解出Column Address和Page Address。
Columnaddr = addr % 512 // column address
Pageaddr = addr>>9 // page address
也就是一個Nand Flash地址的A0-A7是它的column address ,A9—A25是它的Page Address,地址A8被忽略。

      現在假設我要從Nand Flash中的第5000字節處開始讀取1024個字節到內存的0x30000000處,我們這樣調用read函數
NF_Read(5000, 0x30000000,1024);
我們來分析5000這個src_addr.
根據
column_addr=src_addr%512;
page_address=(src_addr>>9);
我們可得出column_addr=5000%512=392
page_address=(5000>>9)=9
於是我們可以知道5000這個地址是在第9頁的第392個字節處,於是我們的NF_read函數將這樣發送命令和參數
column_addr=5000%512;
page_address=(5000>>9);
NF_CMD=0x01; //要從2nd half開始讀取 所以要發送命令0x01
NF_ADDR= column_addr &0xff; //1st Cycle A[7:0]
NF_ADDR=page_address& 0xff NF_ADDR=(page_address>>8)&0xff; //3rd.Cycle A[24:17] NF_ADDR=(page_address>>16)&0xff; //4th.Cycle A[25] 向NandFlash的命令寄存器和地址寄存器發送完以上命令和參數之後,我們就可以從rNFDATA寄存器(NandFlash數據寄存器)讀取數據了.
我用下面的代碼進行數據的讀取.
for(i=column_addr;i<512;i++)
{
*buf++=NF_RDDATA();
}
每當讀取完一個Page之後,數據指針會落在下一個Page的0號Column(0號Byte).

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章