李敏++侯亞玲++劉穎
摘 要:為解決嵌入式系統(tǒng)中便攜式存儲設備的大容量數(shù)據存儲問題,并便于對數(shù)據進行查詢、讀取及分析,系統(tǒng)采用具備SD卡插座的Cortex M3處理器平臺,分析了SD卡的驅動實現(xiàn),并按照FAT32文件系統(tǒng)規(guī)范進行文件系統(tǒng)設計。設計使用c語言進行開發(fā),通過系統(tǒng)采集實時溫度,并將數(shù)據按照一定的格式規(guī)范存儲在SD卡的文件中;通過讀取SD卡進行數(shù)據的查詢、讀取。經反復測試,系統(tǒng)運行穩(wěn)定,數(shù)據的存儲及讀取都很可靠,且軟件便于移植,可應用于大容量數(shù)據采集的系統(tǒng)中。
關鍵詞:SD卡;FAT32文件系統(tǒng);SPI;ds18b20
中圖分類號:TP39;TN915.41 文獻標識碼:A 文章編號:2095-1302(2017)07-00-03
0 引 言
隨著嵌入式技術的飛速發(fā)展,很多嵌入式系統(tǒng)都需要大容量的存儲設備,用于數(shù)據存儲。而當前,常用的存儲設備有U盤、移動硬盤、Flash芯片、SD卡等,它們各有優(yōu)缺點。綜合考慮在系統(tǒng)設計時的性價比、功耗及體積等要求時,SD卡無疑是一個非常好的選擇。隨著存儲技術的發(fā)展,其容量也越來越大,可以達到32 G以上,且支持SPI接口,同時SD卡有幾種不同的體積可供選擇,可滿足不同的設計及應用要求。
具備SPI接口的嵌入式系統(tǒng)只需4個I/O接口就可以擴展達32 G以上的外部存儲器,存儲容量不等,設備更換方便,程序在不同的設備上移植也更簡單?;谝陨蟽?yōu)點,SD卡在嵌入式市場得到廣泛應用,成為存儲設備的首選。然而SD卡中的數(shù)據以塊的形式進行存儲,不便于數(shù)據的組織管理,為了能夠在PC端有效的對數(shù)據進行存儲、管理、查詢及讀取,需要對SD卡進行文件系統(tǒng)的設計。一般而言,PC端可直接對其進行格式化后直接使用,而在嵌入式系統(tǒng)中,需要設計FAT文件系統(tǒng)對其進行數(shù)據管理。
1 SD卡驅動設計
SPI有9個引腳,支持兩種操作模式,即SD卡模式(SDIO通信)和SPI模式[1]。SD卡模式允許4線的高速數(shù)據傳輸模式,但需要MCU帶SD卡控制器,設計中會增加產品的硬件成本;SPI模式通過SPI總線接口與SD卡通信。
設計中采用的MCU為Cortex M3,它是一種低功耗、內核架構為ARM7的控制器,自帶SPI控制器。處理器平臺SD卡硬件連接電路均已完成,采用SPI連接方式。
系統(tǒng)使用SPI模式。系統(tǒng)上電后,設置SD卡模式轉換為SPI模式。在SD卡收到復位命令(CMO)時,CS引腳被拉低,進入SPI模式。上電后,因為SD卡內部供電電壓上升時間需要大約64個CLK,還需要10個CLK用于SD卡同步,在發(fā)送CMO指令前,發(fā)送至少74個系統(tǒng)CLK,初始化時,CLK最大不得超過400 kHz。
通過SD卡初始化就可以知道SD卡的類型,讀寫數(shù)據。SD卡讀取數(shù)據通過 CMD17實現(xiàn),具體過程如下:
(1)發(fā)送 CMD17;
(2)接收卡響應 R1;
(3)接收數(shù)據起始令牌 0XFE;
(4)接收數(shù)據;
(5)接收 2 個字節(jié)的 CRC,如果不使用CRC,這兩個字節(jié)在讀取后可以丟掉。
(6)禁止片選之后發(fā)送8個CLK;
SD卡的寫和讀數(shù)據過程基本相同,寫數(shù)據通過CMD24實現(xiàn)[2],具體過程如下:
(1)發(fā)送CMD24;
(2)接收卡響應R1;
(3)發(fā)送寫數(shù)據起始令牌0XFE;
(4)發(fā)送數(shù)據;
(5)發(fā)送2 B的偽CRC;
(6)禁止片選之后多發(fā)8個CLK。
2 FAT32文件系統(tǒng)介紹
為了有效管理寫入SD卡的數(shù)據,使SD卡在PC機端能夠被有效訪問,必須將SD卡中的數(shù)據以文件形式存儲,需要在SD卡中創(chuàng)建常用的文件系統(tǒng)。目前,SD卡的容量越來越大,因此設計中采用FAT32文件系統(tǒng)。
在設計中使用了FATFS,它是一種開源免費且專用于小型嵌入式系統(tǒng)的文件系統(tǒng)模塊,硬件獨立性強,是Windows系統(tǒng)兼容的文件系統(tǒng)格式,其代碼特點與平臺無關,支持長文件名、多種大小的扇區(qū)[3]?;诖颂攸c,F(xiàn)ATFS的使用非常廣泛,其層次結構如圖1所示。
應用層用戶只需調用FATFS模塊提供給用戶接口函數(shù),就可在PC機上對SD卡進行讀寫操作[4]。中間層FATFS模塊實現(xiàn)了FAT文件的讀/寫協(xié)議,使用中一般不做修改,可直接將相關頭文件包含在應用程序中。編寫移植代碼的是FATFS模塊提供的底層接口,包括存儲媒介讀/寫接口以及提供文件創(chuàng)建修改時間的實時時鐘。在FATFS源碼包中,需要修改的是與平臺相關的代碼diskio.c,即FATFS和disk I/O模塊接口層文件[5]。
FATFS模塊在移植時,只需修改2個文件,即ffconf.h 和 diskio.c。FATFS模塊的所有配置項都存放在ffconf.h中,可以通過配置一些選項來滿足設計的需求。對于SD卡的一些操作特性,可修改ffconf.h中的宏定義來實現(xiàn),比如宏_FS_READONLY將其設置為0,即表示對SD卡進行讀寫權限的操作,_USE_MKFS為1表示使能SD卡的格式化操作等。
FATFS的移植主要分為3個步驟:
(1)在 integer.h 里定義好數(shù)據的類型;
(2)根據對SD卡的功能需要,通過 ffconf.h配置FATFS的相關功能;
(3)函數(shù)編寫:打開 diskio.c以進行底層驅動編寫,實現(xiàn) 6個接口函數(shù)的編寫,如圖2所示。
通過上述步驟就可以完成FATFS的移植。
3 FAT32文件系統(tǒng)設計
FAT32文件系統(tǒng)的設計包括以下步驟:
(1)程序初始化。定義兩個結構體變量,其類型分別為DIR與FILINFO[6]。其中,DIR結構體表示文件夾目錄相關信息,例如文件夾cewen,文件夾下有文件wendu1.txt,wendu2.txt,wendu3.txt以及文件夾cw。DIR用來存儲LM、limin的目錄信息,F(xiàn)ILINFO用來存儲limin1.txt,limin2.txt,limin3.txt。
DIR cewendir;//臨時目錄信息
FILE fileinfo;//臨時文件信息
(2)程序初始化中要初始化內存,因為文件信息分配的內存空間大,一般存儲在內部RAM中,也可存放在外部RAM中。先初始化內存,再申請fata所用到的變量分配內存空間。
mem_init(SRAMIN);//初始化內部內存池
exfuns_init( );//為FATFS相關變量申請內存[7]
(3)掛載SD卡。只有掛載了SD卡,才能使用,即尋找是否存在。
f_mount(0,fs[0]);//掛載SD卡
(4)打開SD卡下的文件夾,函數(shù)為FRESULT f_opendir (DIR *dj,/* 指向一個空白的結構體,用來存儲要打開的文件信息,用到初始化定義的DIR型變量*/const TCHAR *path /*指向文件夾名稱的指針,即打開文件的路徑 */)。函數(shù)返回0 ,表示打開文件成功,否則表示打開失敗[8]。
res=f_opendir ( &cewen, "0:/"); //打開 0:/cewen文件夾,文件夾的信息保存在結構體cewendir變量中,res為0,打開成功
(5)讀取文件信息。在讀取文件信息之前,先要申請相關變量信息的內存。
fileinfo.lfsize=_MAX_LFN*2+1; //長文件名最大長度
fileinfo.lfname=mymalloc(SRAMIN,fileinfo.lfsize);//為長文件緩存區(qū)分配內存
(6)只有成功打開文件夾,才能讀取或更改文件夾下的文件,與Windows系統(tǒng)下的使用原理一樣。判斷通過res進行,即if(res==FR_OK){讀取文件夾}
(7)讀取文件夾函數(shù)為:FRESULT f_readdir (DIR *dj,/*指向讀取的文件夾信息結構體的指針,打開文件夾后,文件夾的信息已存入信息結構體 */FILINFO *fno,/* 指向文件信息結構體,用來存儲讀取到的文件信息*/)。重復調用此函數(shù)可讀取文件夾內的所有文件,當所有的文件讀取結束后[9],函數(shù)返回一個空字符串到f_name[ ]中(文件信息結構體中的一個變量,存放名稱)
if(res==FR_OK) {while(1){res = f_readdir(&lmdir,&fileinfo);//遍歷文件
if(res!=FR_OK || fileinfo.fname[0]==0)
{ Show_Str(60,130,200,16,"出錯了",16,0);break;}//讀取出錯或遍歷結束,則退出
fn=(u8*)(*fileinfo.lfname?fileinfo.lfname:fileinfo.fname); printf(fn);//輸出文件名} }
以上步驟是對于文件夾及文件的操作,以下步驟為文件的讀寫操作:
(1)打開或新建一個文件(返回值為0則成功)。
FRESULT f_open (
FIL *fp,/* 指向一個用來存儲文件對象的空結構體指針*/
const TCHAR *path, /* 指向文件名的指針,即路徑*/
BYTE mode /* 讀取方式*/
)
讀取方式的使用:
FA_READ讀模式(讀寫同時生效)
FA_WRITE寫模式(讀寫同時生效)
FA_OPEN_EXISTING默認打開方式
FA_OPEN_ALWAYS打開文件,如果不存在,則建立一個新文件;用此種方式可以用f_lseek在文件后追加數(shù)據。
FA_CREATE_NEW新建文件,如果文件已存在,則新建失敗
FA_CREATE_ALWAYS新建文件,如果文件已存在,覆蓋舊文件。
新建一個文件:
res=f_open(&fsrc,"0:/dongman.txt",F(xiàn)A_OPEN_ALWAYS); //打開,新建文件測試
if(res==FR_OK)
{
POINT_COLOR=0x2299; Show_Str(60,170,200,16,"新建文件成功!",16,0);}
f_close(&fsrc);
(2)讀取文件(讀取成功返回0)。
FRESULT f_read (
FIL *fp/* 指向文件對象結構體指針*/
void *buff/* 指向存儲讀取到的數(shù)據的緩沖區(qū)的指針 */
UINT btr/* 準備讀取的字節(jié)數(shù) */
UINT *br /* 讀取到的字節(jié)數(shù) */
)
f_read函數(shù)執(zhí)行完后,*br值用來存放讀取到的字節(jié)數(shù),br res=f_open(&fsrc,"0:/limin2.txt",F(xiàn)A_READ); // 打開,新建文件測試
if(res==FR_OK)
{
USART1_SendStr("文件內容:");
USART1_SendStr("\r\n");
while(1){
res=f_read(&fsrc,pr,256,&br);
if(res ||br < 256)
break;
USART1_SendStr(pr);
USART1_SendStr("\r\n");
Show_Str(60,170,200,16,"讀取成功!",16,0); } }
f_close(&fsrc); //關閉文件,不論是打開還是新建,一定要關閉。
4 系統(tǒng)總體設計
系統(tǒng)主控核心為Cortex-M3,搭載DS18B20溫度傳感器[10],實現(xiàn)溫度的實時測量,每5 s測量一次溫度,將測量的數(shù)據寫入SD卡的wendu.txt文件中。設計中需要實現(xiàn)的功能模塊為DS18B20測溫的驅動實現(xiàn),SD卡驅動實現(xiàn),SD卡fate32文件系統(tǒng)實現(xiàn)及主控任務實現(xiàn),系統(tǒng)設計總流程如圖3所示。
圖3 系統(tǒng)設計總流程圖
在設計中,SD卡Fate32文件系統(tǒng)的實現(xiàn)步驟全面可行,系統(tǒng)上電后,會依次初始化各相關模塊。SD卡首先檢測是否插接正常并給予提示。系統(tǒng)檢測到SD卡,會掛接SD卡到主控系統(tǒng)并在SD卡根目錄中創(chuàng)建一個名為wendu.txt的測溫記錄文檔(如果已經存在,則直接打開該文檔)。準備工作完成后,系統(tǒng)開始循環(huán)測溫,并將每一次測溫結果以及RTC時間格式化寫入文檔中??稍O定文檔大小,如果寫入信息超過500 K,則關閉現(xiàn)打開文檔,重新建立文檔記錄。
5 結 語
經測試,系統(tǒng)工作穩(wěn)定,SD卡插接正??煞€(wěn)定打開,也可以FAT32格式進行格式化。通過軟件設計,可在SD卡中創(chuàng)建文件、打開文件、關閉文件及刪除文件,所采集的數(shù)據能夠正常寫入文件中,并可結合RTC寫入當前數(shù)據的采集時間供后續(xù)分析使用。SD卡可在PC端打開,提供采集的文本信息。設計中使用溫度采集進行測試,也可按需求采集具體所需數(shù)據。FAT32文件系統(tǒng)的實現(xiàn)設計可移植性良好,可移植于單片機及各類控制器的信息采集存儲系統(tǒng)中。
參考文獻
[1]王淵,楊婧.一種基于SD卡的口令認證密鑰協(xié)商方案[J].信息安全與通信保密,2014(10):88-92.
[2]劉智勇,陳鵬飛,宿磊,等.基于STM32芯片的U盤/SD卡文件傳輸技術研究[J].現(xiàn)代電子技術,2014,37(18):107-109.
[3]石長華,謝恩.基于FAT32文件系統(tǒng)和SD卡的陶瓷窯爐測溫儀設計[J].激光雜志,2014(7):100-103.
[4]樊海洋,王立鵬,安曉捧,等.FAT32文件系統(tǒng)數(shù)據恢復技術的研究[J].科技信息,2013(36).
[5]夏昀.基于FAT32文件系統(tǒng)的安全存儲方案[D].上海:上海交通大學,2013.
[6]楊明極,陳方縣,吳學君.嵌入式系統(tǒng)中SD卡的FAT32文件系統(tǒng)的設計[J].電聲技術,2010,34(4):36-39.
[7]顧春洋,李鑫,張強.基于SD卡的FAT32文件系統(tǒng)設計與實現(xiàn)[J].產業(yè)與科技論壇,2013,12(2):96-98.
[8]楊書凱.劉慧.一種用于高速數(shù)據采集的改進FAT32文件系統(tǒng)[J].信息技術與信息化,2011(6):68-70.
[9]何諧. FAT32文件系統(tǒng)在Cortex-M3音樂播放器中的應用[J].單片機與嵌入式系統(tǒng)應用,2013,13(6):71-73.
[10]袁杰,江祖敏.基于FAT32的文件隱藏方法及在Linux上的實現(xiàn)[J].電子設計工程,2012,20(13):15-18.