摘要:介紹了面向閃存類設備的嵌入式文件系統。提出了一種不依靠任何操作系統,以單片機和閃存類設備為硬件基礎的,依照FAT類型文件系統所構建的嵌入式主機文件系統的設計思路,詳細地、分模塊地對該系統進行了分析,并在實際開發和應用中已經得到了驗證。
關鍵詞:嵌入式文件系統; 單片機; 閃存類設備; 文件分配表
中圖分類號:U463.211文獻標志碼:A
文章編號:1001-3695(2008)03-0814-02
數據采集儀作為故障診斷的前端采集器,廣泛地應用在工業生產的各個領域中。其中,數據存儲技術是數據采集儀的關鍵技術之一。考慮到數據采集儀的現場工作環境惡劣,對數據存儲介質的要求有如下幾個特點:體積小、可靠性高、存取速度快、通用性好。閃存類存儲設備在單片機系統中得到了廣泛的應用,常見的有USB電子盤、閃存卡等。其中閃存卡包括MMC卡、CF卡、SD卡,還有SONY的Memory Stick。
為了能在數據采集儀與PC之間進行交互,必須按照一定的標準來組織數據。通常采用的方法就是在其中嵌入文件系統。目前,市場上存在多種商用的嵌入式操作系統可以支持文件系統,如XPE等。但與之對應的是,上述的操作系統對硬件的要求很高,而且價格昂貴,并且對存儲空間也有一定的額外要求。但目前數據采集儀中有很多采用的是8位或者16位的MCU,較少使用操作系統,即使采用操作系統往往也并不支持文件系統。所以,很有必要開發一種面向移動存儲介質,而且不依賴于操作系統的標準文件系統。
1系統概述
本文所討論的文件系統是依照集中索引文件系統所建立的。集中索引文件系統是目前最常用的基于磁盤存儲器的文件系統,包括Windows的FAT系列和基于Linux的Ext系列。所謂的集中索引文件系統,是將存儲器的使用信息和文件的索引信息集中存放在存儲區的固定位置。
閃存設備可以通過使用閃存轉譯層(FTL)驅動而模擬成與磁盤相似的塊設備,所以該類設備均可以通過調用相應的驅動程序,從而按照集中索引文件系統來管理數據。考慮到數據轉換和使用方便,本文件系統主要實現的是基于FAT16類文件系統格式化的閃存類設備的數據文件的讀寫。
文件系統是一個獨立的整體,并且有明確的模塊劃分,能夠使該文件系統在對文件系統格式支持收納該具有很好的擴展性,對文件系統的設備管理上也實現了設備無關性。
本文件系統模塊如圖1所示。
用戶接口(文件系統API)模塊:對文件系統進行最后的封裝,對用戶提供文件系統的API接口,用戶可以直接調用該模塊的函數進行文件級的操作;文件系統模塊:主要實現FAT文件系統中間級函數;
設備驅動管理模塊:主要實現對文件設備驅動程序的管理,最終實現文件系統的設備無關性,通過通用的函數接口來實現對各種閃存類設備底層物理意義的讀寫。
2設備驅動管理模塊
閃存類設備可以通過閃存轉譯層(FTL)驅動而模擬成塊設備,所以本文件系統的設備驅動管理模塊作為整個文件系統最底層的模塊可以被上兩層的模塊直接調用。物理上來看,閃存類設備均可以由扇區組成,每扇區512 Byte,均采用邏輯塊尋址方式LBA(logical block addressing)。
2.1控制器驅動層
塊設備控制器驅動是設備驅動層最底層的函數,是MCU與塊設備的通信接口,通過數據線、讀寫控制線、片選線完成對塊設備或塊設備控制器的I/O讀寫等操作,可為上層驅動提供對塊設備的訪問接口。不同的閃存類設備依照自身的硬件特點,接口電路也不盡相同。例如MMC卡、CF卡可直接與MCU通信,而USB電子盤則必須通過接口芯片與MCU進行通信。用戶可根據所選用的閃存設備以及自身硬件電路的特點來選擇這部分的驅動程序。
例如在本實驗室自主開發的基于C8051F124的與MMC卡和USB電子盤的存儲模塊中,塊設備的控制器驅動層如下:
a)C8051F124與MMC卡通過SPI通信的驅動程序
INT8U MMCdatachange(uchar Bdata)
{
SPIODAT=Bdata;
while(!SPIF);
SPIF=0:
return SPIODAT;
}
b)C8051F124通過USB主機接口芯片CH375與USB電子盤通信的驅動程序
CH375命令端口的I/O地址:INT8U volatilexdataCH375_CMD_PORT _at_ 0xBDF1;
CH375數據端口的I/O地址:INT8U volatilexdataCH375_DAT_PORT _at_ 0xBCF0;
寫入一個命令字節:void CH375_WR_CMD_PORT(INT8U cmd);
寫入一個數據字節: void CH375_WR_DAT_PORT(INT8U dat);
讀出一個命令或數據字節: INT8U CH375_RD_DAT_PORT(void)。
2.2塊設備驅動層
無論什么樣的閃存類設備,由于閃存類設備特有的物理結構,對閃存類設備進行數據的讀寫均是以扇區為單位進行的。通過調用底層的控制器驅動程序,從而實現對物理扇區的讀寫。直接以物理扇區為單位讀寫的函數如下:
a)從塊設備中讀取多個扇區的數據塊到緩沖區
INT8U RBC_Read(INT32U iLbaStart, INT8U iSectorCount, INT8U *mBufferPoint);
b)將緩沖區中的多個扇區的數據塊寫入到塊設備
INT8U RBC_Write( INT32U iLbaStart, INT8U iSectorCount, INT8U *mBufferPoint );
參數說明:
iLbaStart讀取的線性起始扇區號;
iSectorCount讀取的扇區數;
*mBufferPoint指向數據緩沖區的指針。
3文件系統應用程序模塊
3.1文件系統邏輯結構劃分
主引導區(MBR)從塊設備的物理第一個扇區開始,存放了塊設備的邏輯結構信息和介質標志等,系統每次訪問該設備時,都要對引導區內的信息進行識別。該數據結構中包含了對文件分區描述的基本信息,非常重要的有每扇區的字節數、每簇的扇區數、FAT 表數目、目錄項數、文件分區中的扇區數、每個FAT 表占用的扇區數。主引導區的數據結構定義如下:
typedef struct BPB_BLOCK
{
uchar bJmpBoot[3];//ofs:0.典型的如:0xEB、0x3E、0x90
char bOEMName[8]; //ofs:3.典型的如:MSWIN4.1
uint BPB_wBytesPerSec; //ofs:11.每扇區字節數
uchar BPB_bSecPerClus; //ofs:13.每簇扇區數
uint BPB_wReservedSec;
//ofs:14.保留扇區數,從DBR 到FAT 的扇區數
uchar BPB_bNumFATs; //ofs:16.FAT 的個數
uint BPB_wRootEntry; //ofs:17.根目錄項數
……
uint EndingFlag; //ofs:510.結束標志:0xAA55
} BPB_BLOCK, * PBPB_BLOCK;
FAT表用于存放文件分區信息,通常位于主引導區和保留扇區之后。存放在塊設備中的文件并不是占用連續的空間,而是根據一定的算法來決定某一部分文件內容存放到哪個簇中,然后將這些簇連接起來構成一個完整的文件。文件分配表是一一對應于數據區簇號的列表,反映了所有簇的使用情況。每個表項單元的大小決定了FAT的類型,如FAT16的表項單元為16位。為了數據安全,FAT表一般都有一個備份。
文件目錄表(file directory table,FDT)位于 FAT表之后。FDT由32位的目錄項線性構成,記錄著根目錄下每個文件(子目錄)的起始單元、屬性等。FDT大小為32個扇區,最多可以保存512個目錄項。其數據結構定義如下:
typedef struct _DIR_INFO
{
unsigned char name[8]; //文件名
unsigned char extension[3];//文件擴展名
unsigned char attribute; //文件屬性
unsigned char Reserved[10];//保留區域
unsigned int lastUpdateDate; //文件更新日期
unsigned int lastUpdateTime; //文件更新時間
unsigned int startCluster; //文件開始簇號
unsigned long length;//文件長度
} DIR_INFO, * PDIR_INFO;
3.2文件系統實現流程
圖2為在塊設備中實現文件系統操作的流程。
a)首先在目錄區中搜索與文件名“PDSA”匹配的文件目錄項,對應地找到該文件開始的首簇的簇號000a;如果沒有相匹配的目錄,則需要新建一個名為“PDSA”的文件,調用函數Getfreeclusternum()來搜索FAT表得到空閑簇,并且寫入到目錄項中。假設得到的空閑簇為000a。
b)根據首簇號OO0a訪問FAT表,讀出首簇號對應的FAT表項內容000b,這就是第二個簇號。根據第二個簇號再訪問FAT表,讀出其對應的FAT表內容,就是第三個簇號000c。依此下去,直到最后一個表項內容為FFF8H~FFFFH為止(表示最后一簇)。如果是新建文件,則需要根據其文件長度來判斷需要寫入的簇數。假設需要寫入的文件長度為三個簇,此時,調用函數Getnextcluster()來搜索FAT表,依次得到相應的簇號,并將下一簇的簇號寫入到上一簇所在的FAT表項中,最后一簇的FAT表項中寫入FFFF,表示文件結束。
c)根據b)可知“PDSA”這個文件占用了三個簇,這三個簇號形成一個簇鏈,000a-000b-000c。根據這些簇號所形成的簇鏈訪問這三個簇號對應的三個數據存儲區域,文件“PDSA”就分成三個部分分別存放在這三個存儲區域中。
4用戶接口模塊
按照上述文件系統組織格式,系統通過目錄項和FAT表來實現對整個塊設備上的數據按照文件形式進行建立和管理。
最終實現了如下面向用戶的文件級的操作。
FS_FileInital():系統初始化時調用該函數,調入文件系統的相關數據結構;
FS_FileFormat():系統初始化時調用該函數,初始化設備,讀取設備信息到相關數據結構;
FS_FileCreate (INT8U filename):建立新文件;
FS_FileOpen (INT8U filename, INT8U Openflag):以讀或者寫的方式打開文件;
FS_FileClose():關閉已打開的文件,釋放相關緩沖區,保證文件操作的安全;
FS_FileRead(filename, INT8U buf,INT32U datalength):讀取文件到相應的緩沖區,第三個參數是數據長度;
FS_FileWrite(filename, INT8U buf,INT32U datalength):將緩沖區中的內容寫入到文件中,每次寫入的數據長度由第三個參數確定;
FS_FileDelete(filename):刪除文件。
5結束語
本文介紹的面向閃存類設備的文件系統在筆者開發的基于8位單片機C8051F124的便攜式數據采集中已經得到了采用,可以實現與外部存儲類閃存設備的文件級數據交換。其穩定性和實用性已經得到了驗證,并且對別的儀器開發也有一定借鑒意義。
參考文獻:
[1]李慶誠,孫明達.基于NAND型閃存的嵌入式文件系統設計[J].計算機應用與研究,2006,23(4):231-233,239.
[2]陳智育.嵌入式系統中的flash文件系統[J].單片機與嵌入式系統應用,2002(2):5-8.
[3]Cygnal Integrated Products,Inc.C8051F單片機應用解析[M].潘琢金,孫德龍,夏秀峰,譯.北京:北京航空航天大學出版社,2002.
[4]宋群生,宋亞瓊.硬盤扇區讀寫技術——修復硬盤與恢復文件[M].北京:機械工業出版社,2004.
[5]鄭宗漢.實時系統軟件基礎[M].北京:清華大學出版社,2002.
“本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文”