路敦強,吳曉榮
(天津師范大學 物理與電子信息學院,天津 300387)
基于MSP430F5438和FatFs嵌入式文件系統的實現
路敦強,吳曉榮
(天津師范大學 物理與電子信息學院,天津 300387)
以TI公司的MSP430F5438為控制核心,移植了開源免費的FatFs,詳細介紹了移植的過程,給出必要的移植代碼,在SD卡上實現了FAT文件系統.
文件系統;FatFs;MSP430;SD卡
隨著電子信息技術的發展,越來越多的嵌入式系統需要對大容量的數據進行讀取和存儲.傳統的利用非易失性存儲器(FALSH和EEPROM等)按地址和字節讀寫的方法日益不能滿足實際應用的需求[1].而利用嵌入式的文件系統管理存儲介質和數據,不僅靈活易用,而且能與通用的操作系統平臺用文件直接交換數據.在一些需要PC接收處理數據的應用上,如果在SD卡或U盤用嵌入式的文件系統讀寫數據,既省去了以往常用的通信接口設計(如串口和USB口等)和通信協議的制定,又可以避免上位機軟件的開發.此外,采用嵌入式的文件系統避免了嵌入通用的操作系統,降低了對硬件的要求和成本.因此,利用嵌入式的文件系統管理存儲介質成為一種趨勢.
常用的文件系統有FAT16,FAT32,NTFS,Ext,Ext2和HPFS等,由于微軟Windows系統的廣泛使用,其中以FAT16和FAT32最為通用.支持FAT格式且開源、免費的有EFSL和FatFs兩種,而FatFs在較大文件的讀寫上更具效率,因此本研究采用FatFs.存儲介質可以選用U盤或SD卡,使用U盤還需專用的USB芯片,為簡單起見,本研究選擇SD卡.
FatFs是一個專為小型嵌入式系統設計的開源免費的FAT文件系統[2].它完全由ANSI C編寫,且完全獨立于存儲介質的讀寫I/O,所以不需修改就可以移植到各種硬件平臺上,現在已經成功移植到AVR,PIC和ARM等低成本的微控制器上.FatFs主要具有以下特性:(1)兼容FAT12,FAT16和FAT32文件系統;(2)ANSI C編寫,不受應用平臺限制,易于移植;(3)只需要很少的代碼空間和數據空間;(4)多樣的配置選項:多種存儲媒介支持、長文件名支持、RTOS支持、可配置為只讀和最小化API等.FatFs是一個不斷更新完善的軟件,其源碼和使用說明等信息可以在其官方主頁上下載[2].
FatFs具有良好的層次結構,方便在不同的平臺上移植,如圖1所示.

圖1 FatFs的分層結構Figure 1 Divided layers structure of FatFs
FatFs共分3層.最頂層是應用層,提供了一系列的應用函數,如f_open,f_close,f_read,f_write和f_mkdir等,可以直接讀寫文件或文件夾,而使用者不需知道復雜的FAT協議和FatFs內部復雜的函數.中間層FatFs實現了FAT文件讀/寫協議.底層是存儲介質讀寫I/O,移植者只需要編寫6個接口函數即可,如塊讀函數和塊寫函數等.
微控制單元(Micro Control Unit,MCU)選用TI公司的MSP430F5438,它是一個16位的超低功耗單片機,具有256KB閃存、16KB RAM、12位ADC、4個USCI和32位HW乘法器,最高工作頻率是18MHz[3].其中4個USCI可以配置為SPI,UART和I2C中的任意一種,在與SD卡相連時配置為SPI模式.
MSP430F5438與SD卡的連接如圖2所示.

圖2 MSP430F5438與SD卡的連接原理圖Figure 2 Schematic of MSP430F5438connected with SD card
SD卡可以采用SD總線訪問,也可以采用SPI總線訪問[4],考慮到MSP430F5438只有SPI總線接口,所以直接用SPI1(P5.5_UCB1CLK,P5.4_UCB1SOMI,P3.7_UCB1SIMO 和 P3.6_UCB1STE)與SD卡相連.
卡供電模式采用可控方式[5],這樣在SD卡進入不確定狀態時,可以通過對卡重新上電使卡復位,而無需拔出卡.可控電路采用P型MOS管2SJ355,由MCU的P4.7控制.當P4.7輸出高電平時,2SJ355關斷,不給卡供電;當P4.7輸出低電平時,2SJ355開通,給SD卡供電.
卡檢測電路包括2部分:卡是否完全插到卡座中和卡是否寫保護.檢測信號由卡座的2個引腳以電平方式輸出.當卡插入到卡座并插入到位時,由于卡座內部的觸點連接到地線,P4.6為低電平;當卡拔出時,該引腳被拉為高電平.卡是否寫保護的檢測原理與卡是否完全插入到卡座中的檢測原理相同.
FatFs的最新版本是 R0.08版.下載到的FatFs主程序包括5個文件:ffconf.h,ff.h,ff.c,diskio.h和integer.h.在實際的使用過程中移植者需要添加1個diskio.c文件,與diskio.h構成底層的硬件I/O.ff.h和ff.c是FatFs主要的應用函數,向上層提供的API函數都包含在里面.ffconf.h主要對FatFs配置和裁減.integer.h定義了FatFs使用的數據類型,本次移植使用的軟件平臺是IAR4.11B,需要對integer.h內定義的數據類型作一定的修改.
本研究要把MSP430F5438的USCI1配置成SPI模式.具體配置為8位主機模式,數據高位在前.代碼如下:

配置之后USCI1就可以以SPI的方式通信.
SPI操作函數主要有通過SPI口寫1個字節、讀1個字節、片選SPI從機和修改SPI時鐘等.SPI通信時不以中斷形式運行,而是以查詢相關寄存器狀態位的方式完成讀寫.
用SPI方式寫1個字節:

在SPI操作函數的基礎上就可以實現SD的命令層函數,主要有向SD卡發送1個命令、讀SD卡內部寄存器、復位SD卡、塊命令和CRC校驗等.此外,還需要幾個輔助函數,如檢測SD卡是否插到位和是否寫保護等.
SD的API函數由FatFs的硬件層調用,實現FatFs的disk I/O.SD的API函數主要由初始化SD卡、讀多個塊和寫多個塊等構成.具體函數形式如下:


最新的FatFs R0.08版本中沒有diskio.c,需要移植者添加到工程項目中.diskio.c有6個接口函數:disk_initialize,disk_status,disk_read,disk_write,disk_ioctl和get_fattime.它們分別實現了存儲介質初始化、狀態讀取、介質讀、介質寫、介質控制和獲取時鐘的功能.
(1)DSTATUS disk_initialize(BYTE Drive);
存儲媒介初始化函數.入口參數Drive是存儲媒介編號,因為系統中只有1個SD卡,Drive為0即可.函數實體內調用已經編寫好的SD卡API函數中的初始化SD卡函數SD_Initialize即可.
(2)DSTATUS disk_status(BYTE Drive);
狀態檢測函數.檢測存儲媒介是否存在、初始化及寫保護.在本設計中只要檢測到SD卡已經插到位、初始化且沒有寫保護返回0即可.SD沒有初始化則返回1,沒有SD卡返回2,SD卡寫保護返回4.
(3)DRESULT disk_read(BYTE Drive,BYTE*Buffer,DWORD SectorNumber,BYTE SectorCount);
讀多塊函數.*Buffer是讀取緩存,SectorN-umber是起始塊號,SectorCount是要讀取的塊的個數.函數實體內調用SD卡API函數SD_Read-MultiBlock即可.讀取正確返回0,錯誤返回非0.
(4)DRESULT disk_write(BYTE Drive,const BYTE*Buffer,DWORD SectorNumber,BYTE SectorCount);
寫多塊函數.*Buffer是寫緩存,SectorNumber是起始塊號,SectorCount是要寫的塊的個數.函數實體內調用SD卡API函數SD_Write-MultiBlock即可.寫正確返回0,錯誤返回非0.
(5)DRESULT disk_ioctl(BYTE Drive,BYTE Command,void*Buffer);
存儲媒介控制函數.Command是控制代碼,*Buffer是接收數據緩存.在此沒有使用本函數,直接返回0.
(6)DWORD get_fattime(void);
獲取實時時鐘函數.獲得的數據作為文件或文件夾的修改建立時間.硬件中沒有加入實時時鐘,直接返回一個常數即可,不影響使用.
編寫完以上6個函數,FatFs的移植就基本完成了.
從FatFs的R0.07e版開始,需要對FatFs配置的選項從ff.h分離出來,成為1個單獨的文件ffconf.h.
ffconf.h中提供了豐富的配置選項,移植者可以根據硬件資源的多少和需要使用的功能進行配置,從而達到優化設計的目的.ffconf.h主要的配置選項如下:
(1)_FS_TINY.如果_FS_TINY配置為1,那么文件系統和物理介質共用1個物理緩存,不再針對每個開啟的文件建立單獨的512字節的緩存,這樣可以節省大量的RAM空間,使FatFs更容易嵌入在資源較少的微控制器上.
(2)_FS_READONLY.其值為1時可以將FatFs配置為只讀文件系統,涉及寫功能的函數在編譯時將被忽略,減少占用的代碼空間.
(3)_FS_MINIMIZE._FS_MINIMIZE用于裁減FatFs提供的API函數,其值可以為0~3,0為最大模式,保留所有API函數,3為最小模式.
(4)_USE_STRFUNC.其值為0時表示不使用字符串功能,為1或2時表示使用.
(5)_USE_MKFS.其值為1時使能f_mkfs函數,即在存儲媒介上創建新文件系統的功能.
(6)_USE_LFN.其值為1~3時使能長文件名支持,值為0時不使能.使能長文件名會增加1個幾十KB以上的轉換表,占用大量代碼空間,建議不使用.
此外,還有其他一些配置選項在ffconf.h中都有詳細說明.靈活的配置選項增加了移植者的選擇,移植者可以根據具體的使用情況調整相關選項,在功能的多少和代碼的簡潔性之間找到平衡.
FatFs共提供了多達26個應用函數,可以實現創建、刪除和讀取文件夾,創建、刪除和讀寫文件,移動文件指針以及改變文件內容和大小等功能,表1列示了這些函數的名稱和功能.

表1 FatFs提供的應用函數Table 1 Application function FatFs provided
具體使用方法上,必須先用f_mount函數注冊1個工作區,即開辟1個內存空間.然后依次使用f_open,f_read/f_write和f_close即可完成基本的文件讀寫功能.下面的代碼是在SD卡上建立1個名為test.dat的文件,并向其寫入1段字符的示例:

FatFs專為小型嵌入式系統設計,獨立于硬件平臺,只需要編寫幾個接口函數就可完成移植,并可以靈活配置.本研究以MSP430F5438微控制器為核心,以SD卡作為存儲媒介,移植了FatFs,實現了用單片機對文件/文件夾進行讀寫等功能.經過測試,在16MHz的系統時鐘下,系統讀速率約為300KB/s,寫速率約為100KB/s,滿足了一般系統的應用需求.在一些不需要數據實時傳輸或數據量比較大的嵌入式系統中,嵌入FatFs文件系統并以SD卡作為存儲媒介存儲管理數據會非常方便靈活,同時有利于降低成本,具有較為廣闊的應用前景.
[1] 洪岳煒,王百鳴,謝超英.一種易于移植和使用的文件系統FatFs Module[J].單 片 機 與 嵌 入 式 系 統 應 用,2008(5):29-31.
[2] Cha N.FatFs generic FAT file system module[EB/OL].[2010-09-10].http://elm-chan.org/fsw/ff/ooindex_e.html.
[3] Texas Instruments Corporation.MSP430×5xx1/MSP430x6xx family user'sguide[EB/OL].[2009-09-10].http://focus.ti.com.cn/cn/docs/prod/folders/print/msp430f5438.html.
[4] SD Gruop.SD Memory Card Specification Part1:Physical Layer Specification v2.0[EB/OL].[2010-09-10].http://www.sdcard.org/developers/tech/sdcard/pls/simplified_ specs.
[5] 周立功.ARM嵌入式系統實驗教程(二)[M].北京:北京航空航天大學出版社,2005:17-18.
Implementation of embedded file system based on MSP430F5438and FatFs
LUDunqiang,WUXiaorong
(College of Physics and Electronic Information Science,Tianjin Normal University,Tianjin 300387,China)
FatFs module which is free and open sourced is incorporated in TI MSP430F5438,and a FAT file system is implemented on SD card.The process of porting FatFs is introduced in detail and the necessary migration code is given.
file system;FatFs;MSP430;SD card
TP368.1;TP316
A
1671-1114(2011)02-0028-04
2010-09-20
路敦強(1986—),男,碩士研究生.
吳曉榮(1956—),男,教授,主要從事電子技術和嵌入式系統方面的研究.
(責任編校 紀翠榮)