TrueFFS原理及其在CF卡上的實(shí)現
摘要:CF卡是一種基于Flash技術(shù)的容量大、攜帶方便的存儲介質(zhì),已在嵌入式系統等領(lǐng)域得到廣泛的應用;但是,有限的擦寫(xiě)次數極大地限制了CF卡的使用壽命。TrueFFS通過(guò)一系列算法,能夠延長(cháng)CF卡的使用壽命,提高CF卡的使用效率。文章介紹了TrueFFS的原理,在CF卡上實(shí)現TrueFFS的方法,并對TrueFFS的性能進(jìn)行了分析。
關(guān)鍵詞:TrueFFS 損耗均衡 閃速存儲器 CF卡
閃速存儲器最大的一個(gè)缺點(diǎn)就是壽命有限??刹脸拇螖狄蛐酒瑥S(chǎng)商而有所不同,一般都在1萬(wàn)~10萬(wàn)次左右。為了延長(cháng)閃速存儲器的壽命,提高使用效率,Msystems公司推出了TrueFFS系統。它為種類(lèi)繁多的閃速存儲器提供了統一的塊設備接口,并且具有可重入、線(xiàn)程安全的特點(diǎn);支持大多數流行的CPU架構,如PowerPC、MIPS、ARM、X86、68K等。
由于個(gè)性鮮明的閃速存儲器越來(lái)越受到嵌入式系統工程師的青睞,業(yè)界流行的嵌入式實(shí)時(shí)操作系統VxWorks已將TrueFFS作為自身的一個(gè)可裁減的模塊。目前該模塊的版本為2.0,支持Intel、AMD、Toshiba、Fujitsu等廠(chǎng)家生產(chǎn)的大多數型號的閃速存儲器和Flash卡,用戶(hù)只需要更改少量代碼,甚至可直接調用;但是,該模塊對如今風(fēng)靡的CF卡缺乏支持。
CF卡采用了Flash技術(shù)。形象地說(shuō),CF卡就是由若干片閃速存儲器外加一個(gè)管理器組成;但是,CF卡具有攜帶方便、易于升級、存儲量大、抗震性好、兼容性佳等優(yōu)點(diǎn)。目前,CF卡標準已經(jīng)達到1.4版本,容量從最早的2MB到現今的1GB。然而,有限的擦寫(xiě)閃數是閃速存儲器遺傳給CF卡的先天缺陷。本文介紹如何在CF上實(shí)現TrueFFS系統,硬件平臺以PowerPC處理器(MPC8250,Motorola公司)為CPU,嵌入式操作系統是VxWorks。
1 TrueFFS的結構
TrueFFS本身并不是一個(gè)文件系統,需要在TrueFFS之上加載DOS文件系統才能使用,否則毫無(wú)意義。TrueFFS屏蔽了下層存儲介質(zhì)的差異,為開(kāi)發(fā)者提供了統一的接口方式。應用程序對存儲設備的讀寫(xiě)就對像對擁有DOS文件系統的磁碟設備的操作一樣。
如圖1所示,TrueFFS由1個(gè)核心層和3個(gè)功能層組成:編譯層、MTD層(Memory Technoilogy Driver)、Socket層。
翻譯層主要實(shí)現TrueFFS和DOS文件系統之間的高級交互功能,管理文件系統和Flash中各物理可擦塊的關(guān)系,以及TrueFFS中各種智能化處理功能,例如塊映射、損耗均衡(wear-leveling)等。目前有三種不同的翻譯層模塊可供選擇。選擇哪一種模塊要根據使用的Flash介質(zhì)采用NOR技術(shù)、還是NAND技術(shù),或者SSFDC技術(shù)而定。
MTD層實(shí)現對具體的Flash進(jìn)行讀、寫(xiě)、擦、ID識別、映射等驅動(dòng),并設置與Flash密碼相關(guān)的一些參數。VxWorks的TrueFFS已經(jīng)包括了支持Intel、AMD、Toshiba等廠(chǎng)商的大多數Flash芯片的MTD層驅動(dòng)。新的器件需要編寫(xiě)新的MTD層驅動(dòng)。
Socket層提供了TrueFFS和硬件之間的接口服務(wù),負責電源管理、檢測設備插拔、硬件寫(xiě)保護、窗口管理和向系統注冊Socket等。
核心層將其它三層有機結合起來(lái),處理全局問(wèn)題,例如信息量、計時(shí)器、碎片回收和其它系統資源等。
我們最關(guān)心的是MTD層和Socket層。VxWorks只提供了編譯后的二進(jìn)制形式的核心層和翻譯層驅動(dòng)。在實(shí)現TrueFFS應用之間,先介紹一下TrueFFS的原理。
2 TrueFFS原理
2.1 損耗均衡
閃速存儲器不能無(wú)限次重復使用。它的每個(gè)扇區的擦除次數雖然很大,但卻有限;因此,隨著(zhù)使用次數的加長(cháng),它最終會(huì )變成只讀狀態(tài),所以應該盡最大 可能延長(cháng)它的壽命。行之有效的方法就是平衡使用所有的存儲單元,而不讓某一單元過(guò)度使用。這種技術(shù)被稱(chēng)之為損耗均衡。TrueFFS使用一種基于一張動(dòng)態(tài)維護表的存儲器――塊映射的翻譯系統來(lái)實(shí)現損耗均衡技術(shù)。當塊數據被修改、移動(dòng)或碎片回收后,這張維護表會(huì )自動(dòng)調整。
然而,如果存儲在Flash上的一些數據本質(zhì)上是靜態(tài)的,就會(huì )產(chǎn)生靜態(tài)文件鎖定問(wèn)題。存儲這些靜態(tài)數據的區域根據不會(huì )被輪循使用,其它區域就會(huì )被更頻繁地使用,這將降低Flash期望的生命值。TrueFFS通過(guò)強制轉移靜態(tài)區域的方法成功克服了靜態(tài)文件鎖定問(wèn)題。因為映射表是動(dòng)態(tài)的,TrueFFS能夠以對文件系統不可見(jiàn)的方式轉移這些靜態(tài)數據區域。由于絕對強制損耗均衡方式會(huì )對性能產(chǎn)生一些負面影響,所以TrueFFS采取了一種非絕對損耗均衡算法。它保證了所有空間的使用近似平等而不影響性能。
2.2 碎片回收
塊數據的修改使得Flash的一些塊區域中的數據不再有效,并且這些區域在擦除之前變得不可寫(xiě)。如果沒(méi)有機制來(lái)回收這些區域,Flash很快就會(huì )變成只讀的狀態(tài)了。不幸的是由于這些塊不可能單獨擦除,回收這些塊就有些復雜了。單次擦除被限制在一個(gè)叫作擦除單元的較大范圍內,如對于A(yíng)MD的Am29LV065D芯片來(lái)說(shuō)是64KB。
TrueFFS使用一種被稱(chēng)為碎片回收的機制來(lái)回收那些不再包含有效數據的塊。該機制從一個(gè)預擦除單元內復制所有的有效數據塊到另一個(gè)新的被稱(chēng)為轉移單元的擦除單元。然后,TrueFFS更新映射表,再擦除這個(gè)廢舊的預擦除單元。這樣,原來(lái)的塊出現在外界時(shí)仍然包含了原來(lái)的數據,雖然這些數據現在已經(jīng)存放在Flash存儲器的其它空間。
碎片回收算法會(huì )找到并回收與下面標準最吻合的擦除單元:
①廢塊最多;
②擦除次數最少;
③最靜態(tài)的區域。
2.3 塊分配和關(guān)聯(lián)數據集結
為了提高數據的讀取效率,TrueFFS使用一種靈活的空間分配策略:將關(guān)聯(lián)的數據(如由同一個(gè)文件的內容組成的多個(gè)塊)集結到同一個(gè)單獨擦除單元內的一段連續的區域中。為此,TrueFFS盡量在同一個(gè)擦除單元內維持一個(gè)由多個(gè)物理上連續的自由塊組成的存儲池。如果這樣連續的存儲池無(wú)法實(shí)現,TrueFFS分盡量保證池中的所有塊是在同一個(gè)擦除單元內。如果連這樣的情況也不可能的話(huà),TrueFFS會(huì )盡量把塊池分配到一個(gè)擁有最多可用空間的擦除單元內。
這種集結關(guān)聯(lián)數據的途徑有幾個(gè)好處。首先,如果TrueFFS必須從一個(gè)小的存儲窗口來(lái)訪(fǎng)問(wèn)Flash,那么這樣集結了的關(guān)聯(lián)數據可以減少調用映射物理塊到該窗口的次數,加快了文件繼續訪(fǎng)問(wèn)速度。其次,這種策略可以減少碎片的產(chǎn)生。這是因為刪除一個(gè)文件可以釋放掉更容易回收的完整塊,意味著(zhù)碎片回收會(huì )變得更快。另外,它可以使屬于靜態(tài)文件的多個(gè)塊存放在同一地址,這樣當損耗均稀算法決定移動(dòng)靜態(tài)區域時(shí),轉移這些塊就變得更加容易了。
2.4 錯誤恢復
向Flash寫(xiě)數據有時(shí)可能會(huì )出錯,比如在響應文件系統寫(xiě)請求時(shí)、碎片回收期間甚至在TrueFFS格式化或擦除Flash時(shí)。在這些情況下,TrueFFS能夠從錯誤中恢復過(guò)來(lái);但在新數據第一次寫(xiě)入Flash時(shí)如果出錯就會(huì )丟失這些數據。然而,TrueFFS非常仔細地保證所有已經(jīng)存放在Flash上的數據是可恢復的,甚至能夠避免用戶(hù)由于不耐煩或好奇而猛地拔出Flash卡而可能造成的災難性后果。
TrueFFS健壯的關(guān)鍵是它使用了一種“先寫(xiě)后擦”的策略。當更新Flash一個(gè)扇區的數據時(shí),只有在更新操作完成并且新存儲的數據校驗成功后,先前的數據才會(huì )被允許擦掉。這樣的結果是數據扇區不能處于部分寫(xiě)狀態(tài)。操作成功的話(huà)新扇區的數據有效,否則老扇區的數據有效。很明顯,這樣有利于用戶(hù)已經(jīng)寫(xiě)到Flash上的數據的穩定性。
3 編程
TrueFFS的編程主要在MTD層和Socket層。首先必須在當前VxWorks生成目錄的配置文件(config.h)中定義:INCLUDE_TFFS(包含TrueFFS系統)、和INCLUDE_TFFS_SHOW(包含TrueFFS系統的顯示函數)。
3.1 翻譯層
翻譯層根據Flash的實(shí)現技術(shù)來(lái)選擇。設計中選用了SST公司的型號為SST49CF064的CF卡,64MB容量。它是基于NAND的Flash技術(shù),所以在文件中定義INCLUDE_TL_NFTL;如果是NOR技術(shù),則定義INCLUDE_TL_FTL。
3.2 MTD層
文件cfCardMTD.c實(shí)現了MTD層的功能。在本設計中,MTD層主要實(shí)現4個(gè)函數:讀、寫(xiě)、擦除和ID識別。
ID識別函數根據讀取設備的ID號來(lái)選擇與當前設備匹配的MTD驅動(dòng)。識別函數中指定了針對當前設備的一些參數以及基本操作函數,并賦給一個(gè)叫FLFlash的數據結構。
FLStatus cfMTDIdentify(FLFlash*pVol);
數據結構中的主要參數賦值如下:
pVol->type=CF_ID; /*器件ID號*/
pVol->erasableBlockSize=512;/*可擦除的最小單元是512B*/
pVol->chipSize=0x4000000;/*器件容量為64MB*/
pVol-write=cfWriteRoutine;/*寫(xiě)函數*/
pVol->read=cfReadRoutine;/*讀函數*/
pVol->rease=cfEraseRoutine;/*擦函數*/
pVol->map=cfMap;/*將CF卡的一段區域映射到內存空間*/
CF卡的讀函數比Flash的讀函數繁瑣。它和寫(xiě)一樣,必須根據一定的算法來(lái)讀取數據,而Flash只需要直接從地址中讀數據。但是,CF卡的擦函數非常簡(jiǎn)單,直接返回就可以了。因為CF卡可以直接調用寫(xiě)命令寫(xiě)入數據,CF卡本身能夠自動(dòng)完成擦除操作。CfMap函數將CF卡的一段區域映射到存儲空間,一般為4KB。因為CF卡的40MB地址空間并不映射到系統的存儲空間中,映射可以加快系統訪(fǎng)問(wèn)CF卡的速度,而Flash的地址空間,所以Flash的MTD驅動(dòng)中的該函數可以為空。
最后,識別函數必須在MTD驅動(dòng)表單mtdTable[]中注冊:
#ifdef INCLUDE_MTD_CFCARD
cfMTDIdentify,
#endif
并增加函數聲明:extern FLStatus cfMTDIdentify (FLFlash vol).
3.3 Socket層
文件sysTffs.c實(shí)現了Socket層的功能。sysTffsInit()函數是主函數,調用Socket注冊函數cfSocketRegister(),初始化Socket數據結構FLSocket。
LOCAL void cfSocketRegister (void){
FLSocket vol=flSocketOf(noOfDrives);
tffsSocket[noOfDrives]=“F”/*Socket名稱(chēng)*/
vol.window.baseAddress=CF_BASE_ADRS>>12;/*窗口的基地址*/
vol.cardDetected=cfCardDetected;/*檢測CF卡是否存在的函數*/
vol.VccOn=cfVccOn;/*CF卡上電函數*/
vol.VccOff=cfVccOff;/*CF卡繼電函數*/
vol.initSocket=cfInifSocket;/*CF卡初始化函數*/
vol.setMappingContext=cfSetMappingContext;/*CF卡映射函數*/
vol.getAndClearCardChangeIndicator=cfGetAndClearCard ChangeIndicator;/*設置改變函數*/
vol.writeProtected=cfWriteProtected;/*CF卡寫(xiě)保護判斷函數*/
noOfDrives++;
}
其中,映射窗口的基地址以4KB為單位。TrueFFS系統每100ms調用CF卡檢測函數,判斷CF卡是否存在。CF卡上電函數和斷電函數主要用于節省系統功耗,當CF卡出于閑置狀態(tài)時(shí),TrueFFS就關(guān)閉CF卡的電源。CF卡初始化函數負責訪(fǎng)問(wèn)CF卡之前的所有前期工作。如果插入CF卡型號改變了,cfGetAndClearCard ChangeIndicator函數就會(huì )及時(shí)向TrueFFS系統報告。sysTffs.c中需要實(shí)現上述的所有函數。大部分情況下,開(kāi)發(fā)人員不必關(guān)心FLSocket數據結構,只關(guān)心它的成員函數。一旦這些成員函數實(shí)現了,開(kāi)發(fā)人員不能直接調用它們,它們被TrueFFS系統自動(dòng)調用。
4 實(shí)現與性能分析
完成TrueFFS的編寫(xiě)之后,經(jīng)過(guò)編譯鏈接,如果一切正確,VxWorks運行時(shí)會(huì )調用tffsDrv()函數自動(dòng)初始化TrueFFS系統,包括建立互斥信號量、全局變量和用來(lái)管理TrueFFS的數據結構,注冊Socket驅動(dòng)程序。當TrueFFS需要和底層具體硬件打交道時(shí),它使用設備號(0~4)作為索引來(lái)查找它的FLSocket結構,然后用相應結構中的函數來(lái)控制它的硬件接口。成功完成Socket注冊之后,用戶(hù)就可以調用tffsDevCreate()創(chuàng )建一個(gè)TrueFFS塊設備,調用tffsDevFormat格式化設備,再調用dosFsDevInit()函數加載DOS文件系統。之后,用戶(hù)就可以像使用磁碟設備一樣使用了CF卡了,如調用open、read、write、close、creat等文件操作函數。
TrueFFS的簡(jiǎn)單測試方法可以從主機復制一個(gè)文件到CF卡,再將這個(gè)文件從CF卡復制到主機,然后比較原文件和最后文件的區別。用戶(hù)也可以調用tffsShow()或tffsShowAll()來(lái)查看TrueFFS的創(chuàng )建情況。
TrueFFS可以極大地延長(cháng)Flash設備的壽命。一般CF卡可以擦寫(xiě)10萬(wàn)次,如果不使用TrueFFS系統,壽命就非常短。例如,在CF卡上實(shí)現一個(gè)FAT16格式的DOS文件系統,簇的大小是2KB,如果要向CF卡中寫(xiě)入一個(gè)8MB的文件,共占用4K個(gè)簇,出于可靠性考慮,每寫(xiě)一個(gè)簇,FAT表就更新一次,寫(xiě)一個(gè)8MB的文件,FAT表需要更新4096次;而FAT表一直位于某個(gè)固定扇區中,所以8MB的文件最多只能更新25次,一個(gè)每天需要備份的文件,那么CF卡的壽命只有25天。這種應用方式使CF卡壽命與其容量無(wú)關(guān),其它絕大部分可用扇區白白浪費。
采用了TrueFFS系統之后 ,因為損耗均衡算法不允許FAT表固定在某個(gè)扇區中,損耗平均分配給所有物理扇區。期望的CF卡壽命可以用下列公式計算:
期望壽命=(容量總擦寫(xiě)次數0.75)/每天寫(xiě)入字節數
其中,0.75表示文件系統和TrueFFS管理結構的額外消耗系數。如果同樣每天備份一個(gè)8MB文件,那么期望壽命=(64MB100 0000.75)/8MB=600000(天)(約1643年)。
可見(jiàn),TrueFFS驚人地延長(cháng)了Flash器件的壽命。VxWorks自帶的TrueFFS驅動(dòng)器覆蓋了業(yè)界大部分主流Flash芯片,考慮了各種芯片的不同擦寫(xiě)算法,效率較低。對于產(chǎn)時(shí)性要求苛刻的系統,開(kāi)發(fā)人員應該按照所用的Flash器件有針對性地制作了TrueFFS驅動(dòng)器。目前某些CF卡本身實(shí)現了一定程度的損耗均衡算法,但是沒(méi)有TrueFFS那么高效。
評論