基于Flash存儲器的嵌入式文件系統設計

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