嵌入式平臺上NAND FLASH的驅(qū)動實現(xiàn)
摘要:本文簡明闡述了NAND 驅(qū)動在嵌入式ARM平臺的實現(xiàn)。分析了NAND 的數(shù)據(jù)存儲結構,并從物理層,邏輯層和文件系統(tǒng)驅(qū)動接口層三個方面具體分析了NAND 驅(qū)動程序的實現(xiàn)。本文重點討論了在驅(qū)動邏輯層中為了實現(xiàn)磨損均衡如何創(chuàng)建壞塊處理表,并對基于uC/FS文件系統(tǒng)的驅(qū)動接口進行了分析。該嵌入式NAND FLASH驅(qū)動具有存取數(shù)據(jù)快,數(shù)據(jù)準確度高等特點。
1 引言
隨著U盤、數(shù)碼相機、mp3音樂播放器等移動設備的廣泛應用,F(xiàn)LASH存儲器已經(jīng)逐步取代其它半導體存儲元件,成為嵌入式系統(tǒng)中主要數(shù)據(jù)和程序的載體。NAND FLASH是一種可在線多次擦除的非易失性存儲器,其結構提供了極高的單元密度,可以達到數(shù)據(jù)的高密度存儲,并且寫入和擦除的速度也很快,所以 NAND FLASH是高密度數(shù)據(jù)存儲的理想[2] 。本文主要從物理層,邏輯層和驅(qū)動文件系統(tǒng)接口層三個方面具體分析NAND FLASH驅(qū)動程序的實現(xiàn)。
2 物理層驅(qū)動實現(xiàn)
NAND芯片的存儲空間是按照塊和頁的概念來組織的。現(xiàn)在市面上的NAND主要按大頁和小頁兩種存儲類型來進行數(shù)據(jù)管理。本文采用的NAND型號是K9F1G08X0A,該NAND為大頁結構,即芯片每塊()有64頁(Page),每頁有2K 的數(shù)據(jù)存儲區(qū)和64的冗余數(shù)據(jù)區(qū)(用來存放ECC校驗碼)。2K 的數(shù)據(jù)存儲區(qū)作為數(shù)據(jù)緩沖單元,用來實現(xiàn)I/0緩沖和存儲器之間的數(shù)據(jù)傳輸。芯片的存儲陣列組織如圖1所示。
圖1 128M X NAND 的存儲空間結構
NAND FLASH的物理層驅(qū)動主要涉及到:NAND的初始化(ID以及相關屬性信息的讀取)、擦除(以塊作為單位),數(shù)據(jù)讀寫(以頁作為基本單位)。在這一系列的過程中,會涉及到NAND命令的發(fā)送以及NAND地址的發(fā)送。其中地址的發(fā)送會因NAND型號的不同而有所區(qū)別。一般來說,小頁的NAND其地址周期通常為4個:1個列地址(Column Address)和3個行地址(Row Address),而對大頁的NAND來說,列地址至少是2個周期,行地址會因芯片的容量大小而有所區(qū)別。本文采用的三星NAND芯片是2個列地址和2個行地址。對于NAND FLASH 來講,地址和命令只能在I/O[7:0]上并行傳遞。NAND FLASH 以頁為單位讀寫數(shù)據(jù),而以塊為單位擦除數(shù)據(jù)。NAND的數(shù)據(jù)傳輸方式有基本的I/O傳輸方式,即在I/O[7:0]數(shù)據(jù)線上進行的數(shù)據(jù)傳輸。這種操作的缺點是系統(tǒng)CPU要頻繁參與控制數(shù)據(jù)的傳輸,會影響到數(shù)據(jù)傳輸速度。本文采用DMA傳輸方式,數(shù)據(jù)寬度是8/16/32bit,通過中斷的形式通知CPU數(shù)據(jù)的傳輸情況,DMA傳輸主要涉及DMA 控制器的配置以及通道的選擇。
3 邏輯層驅(qū)動實現(xiàn)以及壞塊管理機制
3.1 邏輯基本讀寫操作
驅(qū)動邏輯層的主要任務是整合物理層的驅(qū)動,并為文件系統(tǒng)驅(qū)動層提供接口。在該層中主要涉及的操作包括NAND 的邏輯讀、寫以及擦除。邏輯層對NAND 的操作都是以塊()作為單位來進行操作的。因此須在邏輯層中構建一個塊緩存( Buffer)來臨時存放讀出/寫入NAND 的數(shù)據(jù)。這樣,NAND 的讀取機制分為兩種:頁讀取(Page )和塊讀取(Block)。在頁讀取時,通過壞塊表進行索引指定塊(Block)和頁(Page)來進行數(shù)據(jù)讀操作,而塊讀取時則是通過整合頁讀取時的緩存數(shù)據(jù),把NAND 的數(shù)據(jù)以塊的形式進行緩存(BlockBuffer)。NAND 的寫入機制不像其它的FLASH 器件,NAND 要求在寫入數(shù)據(jù)時,首先必須進行數(shù)據(jù)的擦除。因此我們在寫數(shù)據(jù)的時候,先把將要被寫入的數(shù)據(jù)塊的內(nèi)容讀出到塊緩存,然后再把要寫入NAND 的數(shù)據(jù)以頁為單位的形式寫入塊緩存(Block Buffer)中的對應地址。接著把以前存放數(shù)據(jù)的塊進行擦除操作,最后把更新的數(shù)據(jù)寫到NAND 去。經(jīng)過這一系列的操作,實現(xiàn)了NAND 數(shù)據(jù)的邏輯寫入。圖2 說明了一次寫操作的具體流程。
圖 2 NAND 塊寫數(shù)據(jù)的示意圖
3.2 壞塊管理機制的原理及實現(xiàn)
NAND 由于采用了高密集的存儲單元,在使用過程中難免會損壞一些存儲單元,這就是我們所說的壞塊[3]。數(shù)據(jù)操作時應該避免對這些壞塊進行操作,否則會引起數(shù)據(jù)的錯誤。
一般而言,NAND 的第0 塊常被用來作為程序的引導區(qū),因此NAND 芯片廠商會保證第0塊不會成為壞區(qū)。而作為0 塊以后的數(shù)據(jù)存儲塊,當壞塊產(chǎn)生時,系統(tǒng)級的設計必須能夠用地址映射把這些壞塊屏蔽掉。芯片在出廠時,除保存壞塊信息的區(qū)域外,部分一律被擦除(值為0xFF),對壞塊的讀操作是允許的,但不推薦進行寫和擦除操作,以免由于結構方面的原因使鄰近的塊也失效。系統(tǒng)設計時必須根據(jù)初始的壞塊信息識別出壞塊,并建立壞塊列表。進行寫或擦除操作時將欲操作塊的地址與壞塊地址表的地址相比較,若是壞塊則應跳過。芯片在使用過程中,可能有新壞塊的產(chǎn)生,為了系統(tǒng)的可靠性,必須對此情況加以考慮。
在數(shù)據(jù)寫入或塊擦除操作后,如果讀狀態(tài)寄存器出現(xiàn)錯誤,則表示塊內(nèi)有壞頁存在,也即表明此塊已壞,因為塊內(nèi)壞頁的存在并不影響頁的讀寫,這時可采用塊操作來把頁內(nèi)有用數(shù)據(jù)轉(zhuǎn)移到空閑塊內(nèi),并把壞塊信息存入壞塊表中。因此,當我們在格式化NAND的時候,要給出一定的區(qū)域用來存放壞塊索引表和壞塊表??紤]到一個塊(Block)的大小為128KB,而現(xiàn)在市面上的一般的NAND的容量大小為128MB-2GB不等。故分配10 個塊(Block)來進行存儲。由于第0 塊為用戶不可見塊,實際要求為1-11 塊作為存儲空間。圖 3 表明了如何建立壞塊索引表和壞塊表的流程。
圖 3 壞塊索引和壞塊表建立流程
其中,在壞塊索引(BBTINDEX)中,整型變量bitIsBadBlock 中的每一個bit,標記一個塊的狀態(tài)(1 表示壞塊,0 表示好塊),在ARM 體系中,可以標記32 個塊。該區(qū)域被稱為一個索引區(qū)域。整型變量mPosInBBT 表示如果有壞塊,則表示索引區(qū)域在壞塊表中的偏移。
這樣通過定義一個索引tableTopPos 變量,來指示下一個壞塊在數(shù)組中的位置。同樣在壞塊表(BBTENTRY)中,整型變量mBadBlock 標志塊是壞塊,而mReplaceBlock 變量則表示該壞塊在備份區(qū)中對應的可以的好塊。這樣通過定義一個索引bakupTopPos 變量,來指示下一個壞塊在備用區(qū)的位置。通過結合壞塊索引和壞塊表,可以對數(shù)據(jù)進行準確的操作,而每次對NAND 操作完成后,及時地更新壞塊索引和壞塊表。
4 文件系統(tǒng)層的接口實現(xiàn)
現(xiàn)在一般對NAND 支持的文件系統(tǒng)用的最多的是YAFFS 文件系統(tǒng)。本文由于基于的操作系統(tǒng)平臺是uC/OS,故采用了uC/FS 文件系統(tǒng)作為NAND 的文件驅(qū)動接口,uC/FS 文件系統(tǒng)進行的操作都是基于FAT 文件格式的。對用戶來說,所用對NAND 的操作,都是通過文件接口層來完成的。文件接口層對數(shù)據(jù)的操作都是以扇區(qū)(Sector)來進行的。因此,文件接口層的主要任務是把從邏輯層的邏輯操作轉(zhuǎn)化為以扇區(qū)(Sector)為單位的操作,文件系統(tǒng)的接口函數(shù)主要通過一個結構體 (FS___)來進行描述[4],該結構體包含了驅(qū)動設備的名稱以及4 個基本的驅(qū)動設備掛接函數(shù)的函數(shù)指針。
在這幾個函數(shù)中,dev_status()函數(shù)主要實現(xiàn)FAT 表狀態(tài)信息的讀取,并表明該NAND 設備可以使用;dev_()函數(shù)實現(xiàn)對NAND 進行文件系統(tǒng)塊數(shù)據(jù)的讀??;dev_write()函數(shù)實現(xiàn)對NAND 進行文件系統(tǒng)塊數(shù)據(jù)的寫入;dev_()函數(shù)則主要實現(xiàn)文件操作的相關指令,包括文件格式化,數(shù)據(jù)cache 回寫等操作。通過這幾個文件接口函數(shù),用戶可以實現(xiàn)對NAND 進行的數(shù)據(jù)基本操作。
其中,mCache 數(shù)組大小為數(shù)據(jù)讀取時的存儲大小,由NAND 的文件系統(tǒng)遵循 標準決定,大小為512Byte;mTimes 表示被Cache 的塊(Sector)的命中次數(shù),反映了數(shù)據(jù)塊的存取幾率;mSectorId 表示被Cache 塊(Sector)的序號,通過該序號來對Cache 的數(shù)據(jù)塊進行索引。
5 總結
對大容量的 NAND FLASH 進行數(shù)據(jù)操作,壞塊處理機制是很重要的,通過建立壞塊處理表,避免了對無效塊進行的操作,提高了數(shù)據(jù)的準確性。另外,ECC 作為NAND 糾錯機制,在NAND 驅(qū)動中也廣泛運用,本文的NAND 驅(qū)動中也加入了ECC 機制,由于篇幅有限,不對其進行深入探討。