周翔
(中國電波傳播研究所 第四研究部,山東 青島 266107)
摘要:介紹了嵌入式VxWorks的TrueFFS(True Flash File System)文件系統的結構和算法,針對項目開發中遇到的問題提出了非2的n次冪大小的TFFS文件系統的構建,描述了該理論的實現過程。經實踐證明該方法可行,并且為Flash存儲器的充分利用和通過TFFS加載鏡像提供了參考。
關鍵詞:嵌入式;VxWorks;TFFS;存儲器
中圖分類號:TP316.2文獻標識碼:ADOI: 10.19358/j.issn.1674--7720.2017.06.007
引用格式:周翔. 非2的n次冪大小的TrueFFS文件系統的構建[J].微型機與應用,2017,36(6):19-21.
0引言
Flash存儲器以其體積小、耗電省、非易失的特性,越來越廣泛地應用于嵌入式系統開發中,成為重要的程序和數據載體。TrueFFS 文件系統是M-systems 公司推出的Flash管理軟件,它為種類繁多的Flash 提供了標準的塊設備接口,因此被包括VxWorks在內的很多嵌入式操作系統所采用。建立TFFS 后,用戶可以像操作標準磁盤一樣實現對Flash的管理。
1TrueFFS文件系統結構
圖1TrueFFS結構及其在系統中的位置TrueFFS位于DOS文件系統和Flash存儲器之間,可以實現對底層Flash的讀寫操作,同時對上層提供應用接口,使Flash像標準磁盤設備一樣由操作系統和文件系統所管理。其在整個系統中的位置和結構如圖1所示。
核心層為文件系統提供完整的塊設備功能;翻譯層負責管理文件系統和Flash各個塊的關系,實現邏輯塊到物理塊的映射,另外它還實現設備模擬算法和Flash管理算法,如壞塊管理、碎片回收、損耗均衡等;MTD(Memory Technology Driver) 層實現Flash底層驅動,如讀、寫、擦除等;Socket層提供TFFS與硬件之間的接口服務,如向系統注冊Socket設備、檢測插拔、硬件寫保護等[1]。
2TrueFFS文件系統算法
TrueFFS能均勻使用Flash,用冗余數據結構保證可靠的數據操作,能排除損壞以避免錯誤,實現了FTL(Flash Translation Layer)標準[2]。
(1)損耗均衡算法
Flash存儲器的擦除壽命有限,隨著使用次數的增多,它最終會變成只讀狀態。為延長其壽命,行之有效的方法就是平衡使用所有的存儲單元,而不讓某一單元過度使用。TrueFFS使用一種基于動態維護表的blocktoflash(塊對應于Flash)傳輸系統來實現損耗均衡技術。當塊數據被修改、移動或碎片回收后,這張維護表會自動調整。
(2)碎片回收
塊數據的修改使得Flash的一些塊區域被填滿無效數據,這些區域在擦除之前變得不可寫。TrueFFS使用一種碎片回收(garbage collection)機制來回收這些塊。該機制從一個預擦除單元內拷貝所有的有效數據塊到一個新的單元,然后更新blocktoflash映射表,最后擦除廢舊的預擦除單元。
(3)塊分配和關聯數據集結
TrueFFS會將關聯的數據(如出自同一個文件)集結到同一個單獨擦除單元(erase unit)內的一段連續的區域中。為此,TrueFFS盡量在同一個擦除單元(erase unit)內維持一個由多個物理上連續自由的塊組成的存儲池。這就提高了數據的讀取效率,減少碎片的產生。
(4)錯誤恢復
TrueFFS使用了一種“先寫后擦”的策略。當更新Flash一個扇區的數據時,只有在更新操作完成并且新存儲的數據校驗成功后,先前的數據才會被允許擦掉。操作成功,新扇區的數據才有效,否則老扇區的數據有效。
3開發背景介紹
在開發中使用的硬件電路板焊接了64 MB SDRAM,兩片NOR Flash,每片8 MB。嵌入式VxWorks開發時生成bootrom.bin文件為256 KB,VxWorks鏡像文件為5.13 MB。計劃借助TrueFFS創建兩個磁盤C和D,C中存放bootrom.bin和VxWorks鏡像文件,D中存放數據文件和工作日志。但創建TFFS時,Flash大小必須以2的正整數次冪對齊,即C盤空間只能為1 MB、2 MB、4 MB或8 MB。由于bootrom.bin是直接固化到第一片NOR Flash中,所以無法實現將該Flash全部創建TFFS,導致不僅無法存放VxWorks鏡像文件,而且還造成Flash空間的浪費。
4實現過程
將第一片NOR Flash(Intel公司生產的JS28F640J3)起始處的2 MB空間用于固化bootrom.bin文件,上電后可自動運行bootrom;另外6 MB空間創建TFFS文件系統。構建TFFS的過程中涉及5個文件的修改:config.h、Makefile、sysTffs.c、tffsConfig.c、i28f640.c。各文件改動如下:
(1)config.h:加入必要的定義
#defineINCLUDE_TFFS
#defineINCLUDE_TFFS_DOSFS
#defineINCLUDE_TFFS_SHOW
#defineINCLUDE_DOSFS
#defineINCLUDE_TL_FTL
/* 包含需要使用的翻譯層 */
(2)Makefile:將生成的i28f640.o編譯進系統映像,加入定義
MACH_EXTRA = i28f640.o
(3)sysTffs.c:配置TFFS各項參數
#defineINCLUDE_MTD_I28F640
/* 可以調用i28f640Identify函數 */
#defineINCLUDE_TL_FTL
/* 包含需要使用的翻譯層 */
#undefINCLUDE_TL_SSFDC
/* 去掉不使用的翻譯層 */
#defineFLASH_BASE_ADRS0
/* TFFS空間從0地址開始 */
#defineFLASH_SIZE0x00800000
/* 共8MB */
改寫sysTffsFormat函數,完成格式化過程。此處必須弄清tffsDevFormatParams中各個參數的定義[3]。
typedef struct {
long int bootImageLen;
/*bootImage需要從flash開始處預留的長度*/
unsignedpercentUse;
/*Flash被格式化的百分率,為了提高TrueFFS的性能,不要設為100%,以便任何時候都有空余空間。默認值為99%*/
unsignednoOfSpareUnits;
/*空余擦除單元數目,目的在于flash出現壞塊時可以用它來替代,默認為1*/
unsigned long vmAddressingLimit;
/* FTL 在RAM中映射的大小,默認為61Kbytes*/
FLStatus (*progressCallback)(int totalUnitsToFormat, int totalUnitsFormattedSoFar);
/* 回調函數,用來監測flash擦除過程,如果返回值為OK,則繼續,否則停止擦除*/
char volumeId[4];
/*Dos卷標號*/
char FAR1 * volumeLabel;
/*Dos卷標字符串,如果為NULL,則沒有卷標*/
unsigned noOfFATcopies;
/* 文件分配表(FAT)的拷貝數,正常情況下只使用一個FAT,而另一個只有在使用的FAT被破壞的情況下用來恢復分配表,默認為2*/
unsigned embeddedCISlength;
/* CIS 嵌在單元頭部(unit header)之后的字節長度*/
char FAR1 * embeddedCIS;
/* 單元頭部被結構化用來作為一個PCMCIA''tuple'' 鏈(a CIS)的起始,它包含了一個數據組織tuple,通常用16進制的0xFF來標示上一個單元頭部結束的位置(''endoftuplechain'')。*/
} FormatParams;
實際使用的格式化參數為 {0x00200000l, 99, 1, 0x10000l , NULL, {0,0,0,0}, NULL, 2, 0, NULL} 。此文件的改寫是實現非2的n次冪TFFS文件系統創建的關鍵。在設置Flash地址和空間大小時依據NOR Flash的實際參數配置,而在對Flash格式化時修改bootImageLen參數,將2 MB空間給bootrom,而TFFS只使用后面6 MB空間。
(4)tffsConfig.c:在MTDidentifyRoutine mtdTable[]中加入定義
#ifdefINCLUDE_MTD_I28F640
i28f640Identify,
#endif
(5)i28f640.c:實現MTD層的功能
根據js28f640j3數據手冊編寫FLFlash結構體的各項成員,包括i28f640Write、i28f640Erase、i28f640Identify、lv28f640MTDMap。
程序中需要注意以下幾點:
①對于NOR Flash,不需要編寫i28f640Read函數;
②如果要創建多于1個TFFS文件系統,需要對每個文件系統編寫lv28f640MTDMap函數;
③首次創建時,最好#define DEBUG_PRINT printf,可以觀察整個創建過程,便于查找問題;
④需要在擦除和寫操作中屏蔽中斷,因為Flash在擦除、讀寫ID狀態時,不能正常讀取Flash中的數據。而VxWorks的異常入口位于Flash存儲器的開始處,異常發生時不能得到正常的入口指令,會導致系統跑飛。
5文件系統創建
第一次啟動時設置通過網絡加載映像,當系統啟動成功后在Shell中執行以下命令:
-> tffsShowAll
TFFS Version 2.2
0: socket=RFA: type=0x17, unitSize=0x20000, mediaSize=0x800000
1: socket=RFA: type=0x17, unitSize=0x20000, mediaSize=0x800000
value = 48 = 0x30 = '0'
-> sysTffsFormat
value = 0 = 0x0
-> sysTffsFormat
-> usrTffsConfig 0,0,"/tffs"
value = 0 = 0x0
-> devs
drv name
0 /null
1 /tyCo/0
5 host:
6 /vio
3 /tffs
value = 25 = 0x19
此時可以看到“3 /tffs”,說明設備掛接已經成功。執行dosFsShow “/tffs/”命令,/tffs空間5.68 MB可用。
6結束語
通過對TrueFFS相關函數的配置,可實現嵌入式VxWorks中非2的n次冪TFFS文件系統的構建。本文詳細描述了創建過程及注意事項。這種方式已經應用到某發射系統的顯控技術上,設備運行穩定、可靠,具有較大的實用價值。
參考文獻
[1] 曹桂平,等. VxWorks設備驅動開發詳解[M]. 北京:電子工業出版社,2011.
[2] Wind River systems Inc. VxWorks reference manual[Z]. 1999.
[3] Wind River Systems Inc. VxWorks drivers API reference[Z]. 2006.