歡迎您光臨本站 登入註冊首頁

概述

 隨著嵌入式系統應用要求的不斷提高,系統資源的進一步豐富,系統的複雜程度也不斷提高。文件系統在嵌入式操作系統中佔據著越來越重要的位置,因為像數據採集、多媒體應用等這樣一類涉及大量數據的存儲、加工、轉換……

 隨著嵌入式系統應用要求的不斷提高, 系統資源的進一步豐富, 系統的複雜程度也不斷提高。文件系統在嵌入式操作系統中佔據著越來越重要的位置, 因為像數據採集、多媒體應用等這樣一類涉及大量數據的存儲、加工、轉換等, 需要文件系統的支持。
    一般來說, 嵌入式系統處理大容量臨時數據的有效方法是設計一個內存文件系統存儲這些數據。和普通磁碟文件系統相比, 內存文件系統具有存取速度快、可動態改變文件系統大小和數據掉電即丟失的優點, 因此它適用於高速的臨時數據處理。Linux 下的Tmpfs、Proc 文件系統以及Freebsd 下的MFS 都是一種內存文件系統。但是, 這些通用操作系統上的內存文件系統不能直接運用到嵌入式系統中, 因此探索了適合嵌入式大容量數據處理的嵌入式內存文件系統的實現。本文闡述了嵌入式內存文件系統的設計要點, 並分析了將其移植到uCOS II操作系統上的主要技術。

1 嵌入式文件系統的建立
    嵌入式系統一般都用大容量電子盤( Flash) 做永久存儲介質, 這種設備的特性就是數據只能被整塊(Block) 地改寫, 所以數據需要按照整塊存儲, 不同的電子盤每塊的大小也不同, 如4KB、16KB 等。
    在本文設計的系統中, 把文件作為一種無結構的位元組序列, 用戶任務可以在文件中加入任何內容, 並且以任何方式來處理它們。為了便於管理和提高訪問速度, 不設置子目錄管理; 文件以“簇” (Cluster) 為單位, 分塊存儲, 每個簇的大小根據實際系統的電子盤特性固定為整塊的大小。本文件系統對文件的主要管理方式為:
(1) 文件的各個屬性單獨存儲在文件信息表(file status table) 中;
(2) 文件數據塊用鏈表來分配和管理, 文件數據塊大小可以動態改變, 這樣可以避免在系統運行過程中產生大量的碎片;
(3) 為了提高文件的讀寫和查找速度, 設置一個全局散列表(Hash 表) 作為文件的讀寫及查找入口;每個文件根據其文件名、文件長度計算出一個Hash 值; 然後在Hash 表找到文件對應的Hash 項, 這樣就可以讀出文件的屬性和數據。圖1表示了此文件系統在內存中的組織結構。

全局Hash 表 文件狀態表 數據塊鏈表 文件數據塊

圖1 文件的組織結構
    每一個存儲於此系統中的文件在全局Hash 表都有個對應的入口項。其文件屬性和文件名、文件長度、創建時間等存入文件狀態表, 文件內容存儲在從空閑塊鏈表申請到的數據塊中。文件的Hash 表、狀態表和數據塊通過指針鏈接起來, 如圖2 所示, 下面分別介紹文件系統的Hash 表、狀態表和數據塊鏈表。
 
圖2  文件系統中的文件組織方式

1.1 Hash 表
    Hash 表是整個文件系統讀寫和查找的入口, 通過計算文件的Hash 值來找到其在Hash 表中的位置, 從而訪問文件狀態表和數據塊。因此文件系統的查找效率主要體現在如何通過文件信息計算其對應的Hash 值以及如何有效地組織Hash 表。每個文件對應8 位元組的Hash 值。其中前2 個位元組是文件名長度和文件名第一個位元組的ASC II碼值, 接下來的2 個位元組是文件名的16CRC (循環冗餘校驗編碼) , 最後4 個位元組是文件名的32CRC 編碼。為獲得較高的查找效率, 本文採用鏈地址法組織全局Hash 表, 將全局Hash 表分為兩部分: 基本表和溢出表。其基本思想為: 首先分配一個固定大小(設為K項) 的順序表作為基本表, 每個文件計算得出的Hash 值通過對K取模得到介於0 - K之間的模值。如果此模值在基本表中的對應項沒有被佔用, 那麼該項就作為此文件的Hash 項; 如果此模值在基本表中的對應項已被其它文件佔用, 那麼就溢出表中申請一個此文件的Hash 項, 並將此Hash 項鏈接到具有相同模值的鏈表中。通過這種順序表和鏈表相結合的結構, 既不會影響查找速度又不會增加額外存儲空間, 從而提高文件系統的查找效率。

1.2  文件狀態表
    文件狀態表用來存放系統中文件的各個屬性, 包括文件名稱、文件大小、讀寫標誌、創建和修改時間。同時, 為了提高內存空間的利用率, 可以對文件進行選擇性壓縮存儲, 因此文件狀態表也包括文件壓縮標誌, 壓縮前的原始大小和壓縮后的文件大小。從圖2 可以看到, 文件狀態表是和Hash 表以及數據塊鏈表連在一起的, 那麼一旦定位到文件對應的Hash 項, 就可以對文件狀態表進行讀寫。

1.3  數據塊鏈表
    在此文件系統中, 數據內容保存在內存數據塊中, 內存數據塊的大小可以在建立文件系統時動態設定。數據塊鏈表的作用是對內存塊進行管理。由於數據塊鏈表中每一項對應一個內存塊, 所以當添加文件時, 系統根據文件大小在鏈表中動態地申請一定數量的數據塊; 當刪除文件時, 系統將數據塊插入到鏈表中。

2 內存文件系統在uCOS II中的實現
    uCOS II是一個可裁減的實時多任務內核, uCOS 公開了它的實時性內核源碼, 同時提供了內存管理的介面和函數, 在其實時內核的基礎上進行少量的修改, 便可將此文件系統移植到uCOS 系統中。圖3 是文件系統在uCOS 下的初始化流程。
 
圖3  在uCOS II下的初始化流程
    為了載入的文件系統跟內核很好地配合工作, 需要在uCOS II內核中增加一些相關數據結構, 並對原來的相關數據結構進行必要的修改。
    用戶任務對文件進行讀寫操作時, 系統必須維護當前被用戶任務所打開的所有文件, 用文件控制塊來登記這些被打開的文件, 其定義如下:
typedef struct //佔用6 位元組大小
{
 OS_FCB *pNext ; //指向下一個控制塊
 OS_DIRITEM *DirItem; // 文件目錄項的內容
 INT8U LinkCount ; // 打開此文件的用戶數量
 INT8U *PathName ; // 文件的絕對路徑
} OS_FCB ;
    一個用戶任務可能同時打開幾個文件, 對文件讀寫時要記錄下文件的當前位置, 以便在掛起后重新調度運行時能從這個位置繼續進行。用打開文件數據結構來描述:
typedef struct // 佔用8 位元組
{
  OS_OPENFILE *pNext ; // 下一個打開的文件
  OS_FCB *pFCB ; //被打開的文件的文件控制塊
  INT32U Position ; //文件的當前讀寫位置
} OS_OPENFILE;
修改原有的任務控制塊OS_TCB , 增加一個指向打開文件的指針OS_FILE *pFile 。修改系統初始化OSInit () 過程, 增加初始化文件系統OSFileInit() 的調用。

3 結論
    本文提出了嵌入式系統下的一種大容量內存文件系統的實現方案, 並從文件的平均查找次數和系統內存利用率等方面對文件系統進行了測試和性能分析。測試結果表明, 此系統具有較快地查找定位速度和較高的內存利用率, 所以本系統能夠有效地應用於嵌入式系統, 尤其是那些產生較多臨時文件或處理大容量數據的嵌入式系統。


[admin via 研發互助社區 ] 初探在uCOS II上實現大容量內存文件系統已經有3075次圍觀

http://cocdig.com/docs/show-post-42193.html