在前面章節(jié)中介紹了使用MM32F3270的SDIO外設(shè)驅(qū)動SD卡,對SD卡識別和簡單的數(shù)據(jù)讀寫驗證,不過像這樣直接操作SD卡存儲單元,在實際應(yīng)用中是不現(xiàn)實的。SD卡一般用來存放文件,所以都需要加載文件系統(tǒng)到里面。
FatFs 是一個通用的文件系統(tǒng)(FAT/exFAT)模塊,用于在小型嵌入式系統(tǒng)中實現(xiàn)FAT文件系統(tǒng)。完全用標(biāo)準(zhǔn)C語言編寫,所以具有良好的硬件平臺獨立性。可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列單片機上而只需做簡單的修改。它支持FATl2、FATl6和FAT32格式,支持多個存儲媒介,具有獨立的緩沖區(qū),可以對多個文件進行讀/寫,并特別對8位單片機和16位單片機做了優(yōu)化。
本章節(jié)主要介紹移植FatFs文件系統(tǒng)到SD卡內(nèi)。
FatFs的特點
1)Windows兼容的FAT文件系統(tǒng)(支持FAT12/FAT16/FAT32)與平臺無關(guān),移植簡單;
2)代碼量少、效率高;
3)多種配置選項;
4)支持多卷(物理驅(qū)動器或分區(qū),最多10個卷);
5)多個ANSI/OEM代碼頁包括DBCS;
6)支持長文件名、 ANSI/OEM 或Unicode;
7)支持RTOS;
8)支持多種扇區(qū)大小;
9)只讀、最小化的API和I/O緩沖區(qū)等。
FatFs源碼獲取
FatFs文件系統(tǒng)的源碼可以從FatFs官網(wǎng)下載:
http://elm-chan.org/fsw/ff/00index_e.html
此地址不僅僅包含資料包下載,還包括文件系統(tǒng)一些知識,包括函數(shù)說明,函數(shù)調(diào)用實例等。
官網(wǎng)有對FatFs做詳細(xì)的介紹,感興趣可以多了解一些。所有版本的FatFs源碼的移植步驟都是類似的,我們選擇選擇其中一個版本下載即可。
FatFs文件結(jié)構(gòu)
解壓之后可看到里面有 doc 和src 這兩個文件。
其中doc文件夾里面是一些使用幫助文檔,src是FatFs文件系統(tǒng)的源碼。
FatFs的源代碼主要包含幾個文件:
diskio.c、 diskio.h、 ff.c、 ff.h、 integer.h文件。
其中diskio.c 這個文件是文件系統(tǒng)底層和SD驅(qū)動的中間接口的實現(xiàn)代碼,移植的時候需要改寫在diskio.h中聲明的那幾個函數(shù),代碼在ff.c中被調(diào)用;diskio.h定義了FatFs用到的宏;ff.c是一般FatFs的代碼文件;ff.h是一般FatFs包含的頭文件;integer.h是內(nèi)部基本類型的定義。
option文件夾下是一些可選的外部c文件,包含了多語言支持需要用到的文件和轉(zhuǎn)換函數(shù)。
00readme.txt 說明了當(dāng)前目錄下 diskio.c 、 diskio.h、 ff.c、 ff.h、 integer.h 的功能。
FatFs移植步驟
在工程目錄下新建FatFs文件夾,并將src文件夾下的文件復(fù)制一份至該文件夾。
使用KEIL打開工程文件并添加FatFs組件,并將src文件夾下的ff.c、 diskio.c 和 cc936.c 三個文件加入FatFs組件中。
加入cc936.c文件可以支持簡體中文,同時需要把 ffconf.h 中的 _CODE_PAGE 的宏改成 936。
接著添加FatFs路徑到工程選項。
此時進行編譯,會發(fā)現(xiàn)提示錯誤。
編寫FatFs接口函數(shù)
來看diskio.c文件,注釋前面的幾個頭文件,這里要加入自己的頭文件。下面的三個宏定義ATA、MMC、USB也可以改成想要的名稱,可以改成SD并定義為0。
然后將函數(shù)disk_status、disk_initialize、disk_read、disk_write里面執(zhí)行的代碼注釋或者刪除,這里需要添加自己的代碼。由于上面改了宏定義,這里switch-case也要做一些修改。
更改如下:
對disk_initialize、disk_read、disk_write幾個函數(shù)也這樣更改。
再次編譯,發(fā)現(xiàn)提示一個關(guān)于get_fattime的錯誤,get_fattime用來獲取當(dāng)前時間,如果不需要,在ffconf.h中的宏定義#define _FS_NORTC改為1關(guān)閉,如果需要這個功能,需要在diskio.c里面,實現(xiàn)get_fattime函數(shù),加入如下代碼即可。
然后進行編譯,這時錯誤就沒有了。
至此我們已經(jīng)完成FatFs文件管理系統(tǒng)的移植,不過功能還沒有實現(xiàn),需要在disk_status、disk_initialize、disk_read、disk_writ、disk_ioctl函數(shù)中加入執(zhí)行代碼:
設(shè)備狀態(tài)獲取
DSTATUS disk_status ( BYTE pdrv /* Physical drive number to identify the drive */ ) { DSTATUS stat; stat = disk.drv[pdrv]->disk_status(disk.lun[pdrv]); return stat; }
設(shè)備初始化
DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { DSTATUS stat = RES_OK; if(disk.is_initialized[pdrv] == 0) { disk.is_initialized[pdrv] = 1; stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]); } return stat; }
讀取扇區(qū)
DRESULT disk_read ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ BYTE* buff, /* Data buffer to store read data */ DWORD sector, /* Sector address in LBA */ UINT count /* Number of sectors to read */ ) { DRESULT res; res = disk.drv[pdrv]->disk_read(disk.lun[pdrv], buff, sector, count); return res; }
扇區(qū)寫入
DRESULT disk_write ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ const BYTE* buff, /* Data to be written */ DWORD sector, /* Sector address in LBA */ UINT count /* Number of sectors to write */ ) { DRESULT res; res = disk.drv[pdrv]->disk_write(disk.lun[pdrv], buff, sector, count); return res; }
其他
DRESULT disk_ioctl ( BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE cmd, /* Control code */ void* buff /* Buffer to send/receive control data */ ) { DRESULT res; res = disk.drv[pdrv]->disk_ioctl(disk.lun[pdrv], cmd, buff); return res; }
審核編輯:彭菁
-
驅(qū)動器
+關(guān)注
關(guān)注
53文章
8259瀏覽量
146604 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7081瀏覽量
89181 -
SD卡
+關(guān)注
關(guān)注
2文章
566瀏覽量
63969 -
文件系統(tǒng)
+關(guān)注
關(guān)注
0文章
287瀏覽量
19926
發(fā)布評論請先 登錄
相關(guān)推薦
評論