基于Flash存儲器的嵌入式文件系統(tǒng)設(shè)計(jì)
首先,將未保存于隊(duì)列中的節(jié)點(diǎn)保存,清未保存隊(duì)列。 然后將塊隊(duì)列中的所有文件節(jié)點(diǎn)轉(zhuǎn)移到空簇中,同時將文件路徑上的各級目錄加入到未存盤隊(duì)列中。對于塊隊(duì)列中的目錄節(jié)點(diǎn),則將它和其路徑上的各級目錄加入未存盤隊(duì)列中,按照未保存隊(duì)列的順序,依次將各個目錄寫入Flash 中,最后寫入最新的索引節(jié)點(diǎn)。因?yàn)槟夸浌?jié)點(diǎn)加入未存盤隊(duì)列時,按照目錄層數(shù)的大小排列,所以按照未保存隊(duì)列的順序?qū)懭霑r,可以保證當(dāng)一個目錄要被寫入Flash 時,它的所有下級目錄已被寫入Flash 中。 所有下級目錄在Flash 中的存儲地址都已確定。當(dāng)該文件系統(tǒng)的空間將達(dá)到存儲上限時,可能會出現(xiàn)特殊情況,即廢簇回收時,空簇的空間不足,無法將所有干凈簇重寫。文件系統(tǒng)為此建立了應(yīng)急機(jī)制,先將文件節(jié)點(diǎn)內(nèi)容存在內(nèi)存中,這時新建一個臨時未保存隊(duì)列,專門保存文件節(jié)點(diǎn),在塊擦寫完成后,將剩余的文件節(jié)點(diǎn)寫入新的空簇中,其算法與圖7 所示流程大致相同。 但是,一旦在擦寫時斷電,會導(dǎo)致該塊上的所有數(shù)據(jù)丟失。
斷電錯誤處理機(jī)制
當(dāng)系統(tǒng)遭遇斷電重新啟動后,索引節(jié)點(diǎn)中的信息會與系統(tǒng)中的狀態(tài)不符,這時便需要錯誤處理機(jī)制。 錯誤一般是索引節(jié)點(diǎn)中標(biāo)注的空簇已被寫入了數(shù)據(jù),錯誤處理就是將此簇標(biāo)志為臟簇,并查找下一個空簇重新寫入。
多任務(wù)處理機(jī)制
該文件系統(tǒng)允許同時打開多個文件,在多任務(wù)操作系統(tǒng)下,為了避免沖突建立了多任務(wù)處理機(jī)制。系統(tǒng)允許打開的多個文件在內(nèi)存中同時被編輯修改,但是對Flash 寫入操作有限制。 處理方法是設(shè)立Flash 寫入保護(hù)區(qū),在此區(qū)中只允許當(dāng)前正在執(zhí)行的任務(wù)執(zhí)行Flash 寫入操作。 實(shí)現(xiàn)Flash 寫入保護(hù)區(qū)的方法是建立一個初始值為1 的信號量,當(dāng)一個節(jié)點(diǎn)需要Flash 寫入時,首先申請信號量,完成后再釋放信號量。 Flash 寫入保護(hù)區(qū)見圖6 、圖7。在圖6 中,空操作語句是用來對多個文件的保存進(jìn)行同步。 例如,有文件1 和文件2 需要保存,先將文件1 的內(nèi)容寫入Flash 中,文件1 路徑下的目錄節(jié)點(diǎn)被添加到未保存隊(duì)列中,再將文件2 的內(nèi)容寫入Flash 中,文件2 路徑下的目錄節(jié)點(diǎn)也被添加到未保存隊(duì)列中,最后將未保存隊(duì)列中的所有節(jié)點(diǎn)都寫入Flash 中。這樣,如果同一路徑下的兩個文件同時存盤,可避免路徑下的相同目錄節(jié)點(diǎn)被寫入兩次,從而提高了效率。不足之處在于,如果很多文件同時存盤,會導(dǎo)致索引節(jié)點(diǎn)在一段時間內(nèi)都無法寫入Flash 存儲器,有斷電丟失的危險(xiǎn)。但對于一般嵌入式系統(tǒng)來說,很少會碰到這種情況。當(dāng)進(jìn)行Flash存儲器擦寫時,在取塊隊(duì)列首節(jié)點(diǎn)至索引節(jié)點(diǎn)寫入完成這段時間內(nèi)都不允許進(jìn)行其他Flash 存儲器的寫入操作,這是為了保證數(shù)據(jù)的完整性,同時也提高了文件系統(tǒng)的穩(wěn)定性。
無目錄文件系統(tǒng)的優(yōu)化
許多嵌入式系統(tǒng)設(shè)計(jì)中雖沒有目錄管理的要求,但是對執(zhí)行效率和資源消耗的要求較高。 對于不要求有目錄管理的精簡文件系統(tǒng),在設(shè)計(jì)時也進(jìn)行了優(yōu)化。精簡文件系統(tǒng)在Flash 中的存儲格式與上述設(shè)計(jì)相同,文件系統(tǒng)中的所有文件信息都保存在索引節(jié)點(diǎn)的根目錄信息表中。精簡文件系統(tǒng)在內(nèi)存中的映象則要簡單很多,只包含索引節(jié)點(diǎn)中的信息,包括簇狀態(tài)表、下一個擦除塊、下一個新節(jié)點(diǎn)的標(biāo)號和根目錄信息,而不用為每個文件都建立內(nèi)存中的映象,節(jié)省大量的內(nèi)存空間。 文件的編輯存盤過程簡化為:打開文件、編輯、將文件寫入Flash 存儲器、將修改后的索引節(jié)點(diǎn)寫入Flash 存儲器。擦寫則只需通過查詢根目錄信息表中的各個目錄項(xiàng),將塊中的所有文件節(jié)點(diǎn)寫入空簇即可。在無目錄管理的情況下,精簡文件系統(tǒng)占用的內(nèi)存資源可以減少,操作也可便捷,提高了效率。 對于大量只需要按名存取的簡單文件管理的小型嵌入式系統(tǒng)而言,針對Flash 存儲器的簡單文件系統(tǒng)將占用資源少,執(zhí)行效率高,有很大的應(yīng)用價(jià)值。
嵌入式文件系統(tǒng)實(shí)現(xiàn)及性能分析
該文件系統(tǒng)的實(shí)現(xiàn)采用了分層方法,分為3 層4 個部分:應(yīng)用程序接口、文件系統(tǒng)核心、操作系統(tǒng)調(diào)用接口、Flash 存儲器驅(qū)動,實(shí)現(xiàn)結(jié)構(gòu)見圖8。
實(shí)現(xiàn)平臺中RTOS 為μC/OSOII 實(shí)時操作系統(tǒng),CPU 使用三星S4510B作為處理器,F(xiàn)lash 存儲器芯片為FUJ ITSU 的29LV160 TE。 針對不同的實(shí)時操作系統(tǒng)和Flash 存儲器芯片需要實(shí)現(xiàn)不同的操作系統(tǒng)接口和Flash 存儲器驅(qū)動。
針對μC/ OSOII 編寫操作系統(tǒng)調(diào)用接口,包括5個函數(shù): ①系統(tǒng)調(diào)用接口初始化FS_Sys_Interface_Init ( ) ,創(chuàng)建互斥信號量和內(nèi)存分區(qū); ② Flash 寫入關(guān)閉FS_Sys_Write_Lock ( ) ,禁止Flash 寫入操作,調(diào)用μC/OS-II 中OSMutePend ( ) ; ③ Flash寫入打開FS_Sys_Write_Unlock ( ) ,重新允許Flash 寫入操作,調(diào)用μC/OS-II 中OSMutePost() ; ④內(nèi)存空間申請F(tuán)S_Sys_Mem_Alloc( ) 和內(nèi)存空間添加FS_Sys_Mem_Add ( ) , 都調(diào)用OSMemGet ( ) 來完成; ⑤內(nèi)存空間釋放FS_Sys_Mem_Free ( ) ,調(diào)用OSMemPut ( ) 完成,將申請的內(nèi)存塊全部釋放。針對29LV160 TE 這款Flash 存儲器芯片,定義一個FlashDef 結(jié)構(gòu)體的全局變量, 用于存儲Flash 器件信息,并且編寫針對此款Flash 的塊擦寫函數(shù)FS_Device_Sector_Erase ( ) 和數(shù)據(jù)寫入函數(shù)FJ FS_Device_Write ( ) 。
完成這兩部分的實(shí)現(xiàn)后,該系統(tǒng)就可運(yùn)行調(diào)試。 測試應(yīng)用程序接口(API) 。應(yīng)該提供的各部分功能,并在突然斷電情況下,測試文件系統(tǒng)的恢復(fù)情況。無目錄管理的精簡文件系統(tǒng)的載入,可在2μs內(nèi)完成,文件寫入耗時主要為閃存的等待時間,系統(tǒng)本身只占用不到200 個字節(jié)的內(nèi)存,產(chǎn)生的代碼段大小為7 K。完整的文件系統(tǒng)載入時,需要建立內(nèi)存中映象,耗時根據(jù)文件數(shù)量的多少而不同,一般為10μs ,產(chǎn)生的代碼段大小為11 K。系統(tǒng)寫入效率較高,在無目錄管理的配置下尤其明顯。試驗(yàn)中系統(tǒng)在多次斷電的情況下,系統(tǒng)仍能恢復(fù)至上次存盤的狀態(tài),雖會導(dǎo)致個別文件未更新,但不會導(dǎo)致文件系統(tǒng)崩潰。
結(jié) 語
針對Flash 存儲器的固有缺陷設(shè)計(jì)了一種基于Flash 存儲器的嵌入式文件系統(tǒng)。 在文件讀寫時,極大減少了Flash 存儲器擦寫的次數(shù),提高了效率。 此系統(tǒng)代碼精簡,運(yùn)行時占用內(nèi)存資源少,運(yùn)行效率高,而且有斷電保護(hù),有較高的安全性。
評論