MCF51QE128微控制器是FREESCALE公司生產(chǎn)的8位/32位兼容的低功耗微處理器。工作電壓的典型值是3.6V,與SD卡的工作電壓兼容,可直接與SD卡連接而無(wú)需電平轉換電路。SD卡因為其體積小、功耗低、容量大且成本低,目前被廣泛應用于各類(lèi)嵌入式數據采集系統中。本文針對此類(lèi)應用,通過(guò)實(shí)測512MB SD卡數據,以實(shí)例的形式深入解析了FAT16文件系統的存儲原則,并給出了實(shí)現方案。 1 FAT16文件系統 SD卡格式化為FAT文件系統時(shí),一般只采用1個(gè)分區,以便于存儲空間的管理。FAT16主要由圖1所示的6個(gè)陰影部分組成。通常情況下,每扇區的大小為512字節。 1. 1 主引導記錄 MBR(Master Boot Record,主引導記錄)總是位于存儲卡的起始位置,即扇區O。圖2是主引導記錄的詳細信息。由于只有1個(gè)分區,所以由偏移量0x1BE可找到第1分區的入口,接著(zhù)由偏移量0x08找到第1分區的相對起始扇區,即第1分區引導記錄所在的扇區。以512 MB SD卡為例,讀取圖2中地址OxlC6~OxlC9處的4個(gè)字節數據(由高位向低位讀取),即Ox000000E9?芍,第1分區引導記錄位于SD卡的第0xE9個(gè)扇區。 1.2 分區引導記錄 分區BR(Boot Record,引導記錄)位于分區的第O扇區。它由跳轉代碼,OEM(Original Eqtlipment Manufacturer,原始設備制造商),BPB(BIOs Parameter Block,BIOS參數塊),擴展BPB,引導代碼和結束標志(Ox55 AA)組成。圖3重點(diǎn)列出了分區引導記錄中BPB的各項參數。讀圖3中Ox000000E9扇區,由偏移量0x0B處2字節數據Ox0200=512可知,SD卡每扇區的字節數為512。類(lèi)似地,可得到其他相關(guān)參數。 1.3 FAT表和文件存儲原則 FAT16文件系統主要通過(guò)FAT表(FATl和FAT2)、根目錄和數據區實(shí)現對文件的存儲管理。FAT表記錄了數據文件的存儲鏈表,對數據的讀取極為重要,通常都會(huì )有一個(gè)或多個(gè)備份。這里,FAT2就是對FATl的備份,必須隨著(zhù)FATl即時(shí)同步更新。根目錄一般以32字節為單位來(lái)存放文件記錄。 數據區主要存放文件數據,為了有效利用存儲空間,一般以簇為單位,簇的大小通常是2的,n次冪個(gè)扇區。FAT格式化后,簇的大小就確定下來(lái)了,可通過(guò)讀取分區引導記錄獲得。例如,讀取圖3中Ox000000E9扇區,由偏移量OxOD處1字節數據0x10=16可知,SD卡的1個(gè)簇占16個(gè)扇區。 如果將SD卡的存儲空間想象成一本書(shū),那么要閱讀一篇文章,首先應該打開(kāi)目錄找到文章的頁(yè)碼,然后根據頁(yè)碼翻到文章所在的地方。類(lèi)比到FAT16文件系統,FAT表和根目錄就像書(shū)的目錄,簇號類(lèi)似于書(shū)的頁(yè)碼,而數據區存放的就是文章的具體內容。 以打開(kāi)文件為例,文件的存儲原則可以這樣描述:首先在根目錄中查找文件名,如有匹配,就找到了文件的開(kāi)始簇號,好比知道了文章的頁(yè)碼。但文件的存儲和書(shū)不同,書(shū)的內容一般是連續的,而文件在存儲后是可以隨意修改的(例如添加或刪除),因而在存儲空間上可能不連續,這樣就無(wú)法僅通過(guò)開(kāi)始簇號找到整個(gè)文件。那么怎樣才能完整找到這些不連續的數據呢?答案就是FAT表。FAT表以“0xF8FF FFFF”作為開(kāi)始標志,以2字節為單位存放文件簇號。FAT表實(shí)質(zhì)是一個(gè)二維鏈表,如圖4所示。 FAT表上面的數字是這2個(gè)字節在表中的位置序號,同時(shí)也代表文件的簇號,與數據區的簇號對應,類(lèi)似目錄的頁(yè)碼。通常SD卡上第一個(gè)文件的開(kāi)始簇號為2。若文件長(cháng)度小于1簇,則其開(kāi)始簇號所對應的2字節值為FFFF。若文件長(cháng)度大于1簇,則其開(kāi)始簇號所對應2字節中存放的是文件所在的下一個(gè)簇號,由所得簇號再查找其對應的2字節,可找到文件接下來(lái)的簇號。依此類(lèi)推,直到最后所得簇號對應的2字節值為FFFF,即為文件的結束簇號。根據上述原則,由FAT表和根目錄就可以確定文件在數據區的存儲簇號,從而實(shí)現文件數據的管理。 2 FAT16文件系統設計 文件系統的基本功能包括:文件的創(chuàng )建、打開(kāi)和讀寫(xiě)。這里假定已經(jīng)實(shí)現了MCF51QE128微控制器和SD卡的硬件接口和底層通信,具體細節參考文獻。 2.1 數據結構 為了便于對主引導記錄、分區引導記錄、FAT表、根目錄和數據區中的相關(guān)信息進(jìn)行記錄和處理,定義了FAT16_t和FILE_t兩個(gè)結構體類(lèi)型。數據類(lèi)型byte、word和dword分別對應于8位、16位和32位數據。 FAT16_t結構體類(lèi)型用于記錄主引導記錄和第1分區引導扇區信息,部分定義如下: FILE_t結構體類(lèi)型用于記錄每個(gè)文件項信息,部分定義如下: 2.2 FAT16初始化 FAT16的初始化主要是讀取主引導記錄和第1分區引導扇區信息,并保存到FAT16_t類(lèi)型變量中。初始化流程如圖5所示。 FAT16初始化子程序中調用了底層SD卡讀數據塊函數SD_ReadBlock。其函數聲明為byte SD_ReadBlock(dword sector,byte*buffer),用于讀入地址為sector扇區中的數據,暫存入buffer中。預編譯函數from_BE_32和from_BE_16分別實(shí)現由高位向低位讀取4字節和2字節數據。 FAT16初始化子程序聲明為byte Init_FAT(FArl6_t*FAT,byte*buffer),部分代碼如下: 2.3 打開(kāi)和創(chuàng )建文件 打開(kāi)和創(chuàng )建文件采用一個(gè)函數來(lái)實(shí)現。首先根據讀入的文件名查找根目錄,若有匹配項則打開(kāi)文件,否則創(chuàng )建一個(gè)新文件。流程如圖6所示。 打開(kāi)和創(chuàng )建文件子程序聲明為byte Open_File(FILE_t*FILE,FAT16_t*FAT,byte*buffer,byte*name)。部分代碼如下: 在根目錄中查找是否有文件項匹配,從根目錄的第1個(gè)扇區開(kāi)始讀扇區。 根據文件起始簇號和根目錄的記錄項號,計算文件FAT表、根目錄和數據區的相關(guān)信息。對于根目錄和數據區的信息,已有文件和新文件的計算一致。如果是新文件,還需修改FAT表和根目錄記錄項。 2.4 多扇區數據讀寫(xiě) 多扇區數據的讀寫(xiě)是在打開(kāi)文件的基礎上,以扇區為單位讀寫(xiě)文件,可連續讀寫(xiě)多個(gè)扇區數據,同時(shí)寫(xiě)入文件的屬性、日期和時(shí)間。寫(xiě)數據的流程如圖7所示,讀數據與之類(lèi)似。多扇區數據的寫(xiě)子程序聲明為byte Write_File(FILE_t*FILE,FAT16_t*FAT, byte attribute,word time,word date,dWOEd size_s,byte*buffer),根據寫(xiě)入扇區數size_s,設置文件的寫(xiě)入位置。首先將寫(xiě)入扇區數與文件剩余扇區數進(jìn)行比較,若寫(xiě)入扇區數小于等于剩余扇區數,則新寫(xiě)入扇區數、簇數均為0,文件結束簇、寫(xiě)簇號不變,不需要修改FAT表,僅修改根目錄中的文件長(cháng)度。否則,需要計算新寫(xiě)入扇區數和簇數。若有增加簇,則需修改FAT表,包括FATl和FAT2、根目錄的文件記,錄項。最后,將數據寫(xiě)入文件數據區。 結語(yǔ) 本文基于FREESCALE公司MCF51QE128微控制器,深入探討了SD卡上FAT16文件系統的存儲原則,給出了實(shí)現方案。軟件算法上,對單扇區數據讀寫(xiě)進(jìn)行改進(jìn),實(shí)現了連續多個(gè)扇區數據的讀寫(xiě),大大提高了文件的讀寫(xiě)效率,特別適用于數據量較大的視頻、音頻數據采集系統的文件存儲。隨著(zhù)SD卡的快速流行,在此類(lèi)存儲設備中引入文件系統將得到更加廣泛的應用。 |