對STM32中FATFS檔案系統常用API函式的理解
首先,第一次在CSDN上面開通部落格,這也算是我的第一篇博文吧,寫的不好的地方還請大家不吝賜教,筆者現大二在校學生,之所以會選擇在這裡使用部落格,是在一位嵌入式大蝦的渲染下,和小夥伴一起分享學習的話,我相信可以學的更多。
廢話不多說,進入主題。
首先,FATFS 是一個完全免費開源的 FAT 檔案系統模組,專門為小型的嵌入式系統而設計的,使用標準的C語言編寫,具有很強的獨立性,可以輕鬆的移植到8位,16位,及其我正在用的32位ARM系列的STM32上面。即FATFS是可裁剪的檔案系統。這點,尤為重要。
FATFS模組的層次結構圖如下,這裡,參考了部分正點原子的資料,感謝原子大大
其中底層介面,包括儲存媒介讀/寫介面(disk I/O)和供給檔案建立修改時間的實時時鐘,需要我們根據平臺和儲存介質編寫移植程式碼。
而中間層FATFS模組,實現了FAT 檔案讀/寫協議。FATFS模組提供的是ff.c和ff.h。除非有必要,使用者一般不用修改,使用時將標頭檔案直接包含進去即可。
最頂層是應用層,使用者無需理會FATFS複雜的FAT 協議和內部結構
那麼,下面就來介紹下 我對FATFS檔案系統的常用API介面函式的一些理解。(以下是我直接在WPS裡面寫好的,故直接cp過來了,往理解)
/* FRESULT f_open函式mode全部開啟方式說明
---------------------------------------------------------------------------------
FA_READ | 讀模式,( 讀寫模式可同時生效)
FA_WRITE | 寫模式,( 讀寫模式可同時生效)
FA_OPEN_EXISTING | 預設開啟方式
FA_OPEN_ALWAYS | 開啟檔案,如果檔案不存在,則建立一個新檔案;
| 用此種方式,可以用 f_lseek 在檔案後追加資料
|
FA_CREATE_NEW | 新建檔案,如果檔案已存在,則新建失敗
FA_CREATE_ALWAYS | 新建檔案,如果檔案已存在,覆蓋舊檔案
|
---------------------------------------------------------------------------------
*/
/*---------------------------------------------------------------------------------
/①以下測試 f_write 通過程式寫入資料 即通過程式新建txt文件且有資料
res=f_open (&fil,"0:/寫入.txt", FA_CREATE_ALWAYS|FA_WRITE); //新建檔案和寫操作
f_write (&fil, "This is a new file, the data is just written in!", 48, &bww);//前提是以寫檔案的形式開啟檔案
f_close(&fil);//關閉檔案,必須和 f_open 函式成對出現,同下
res=f_open (&fil,"0:/寫入.txt", FA_READ);
f_read (&fil, buf,48,&bww);
f_close(&fil);//不論開啟還是新建檔案啊,一定記得關閉
LCD_ShowString(10,210,280,24,24,(u8 *)buf);//
①以下測試通過程式寫入資料 即通過程式新建txt文件且有資料
--------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------
②以下測試FRESULT f_lseek()移動檔案指標,此函式在對已開啟的檔案進行讀或寫時,可以移動當前指標位置 即可以加入或者減去某些不需要的資料
res=f_open (&fil,"0:/寫入.txt", FA_WRITE);
res = f_lseek (&fil , 25); ////指標指向第 25 個位元組
res = f_write (&fil , "40" ,2 , &bw);//2為表示寫入資料為2位元組
// res = f_lseek (&fil , fil.fptr + 10); ////指標向前移動 10 個位元組
res = f_lseek (&fil , 28); ////指標指向第 28個位元組
res = f_write (&fil , "forward" ,8 , &bw);
// res = f_lseek (&fil , fil.fptr - 20); ////指標向後移動 20 個位元組
res = f_lseek (&fil , 37); ////指標指向第 37 個位元組
res = f_write (&fil , "backward" , 9, &bw);//寫入資料為9位元組
res = f_lseek (&fil , fil.fsize); ////指標指向檔案末尾
res = f_write (&fil , "end" ,3 , &bw);
res = f_close ( &fil );
--------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------
③以下測試FRESULT f_truncate()截斷檔案,此函式可以在將檔案在當前指標處截斷,也可以延長檔案長度
res = f_open (&fil ,"0:/寫入.txt", FA_WRITE);//開啟檔案和寫操作
res = f_lseek (&fil , 60); ////指標指向第 60 個位元組
res = f_truncate (&fil ); ////將檔案在此截斷,在60位元組以後的資料都會消失,即截斷檔案
res = f_sync ( &fil ); ////關閉檔案
-------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------
④重新整理快取資訊FRESULT f_sync (FIL* FileObject )函式,* FileObject==指向檔案物件結構體的指標
例如:res=f_sync(&fil);
函式說明:此函式功能相容f_close,它與f_close的區別就是在執行後,當前檔案是否有效.
呼叫該函式後,當前檔案仍然可讀可寫可查詢.
使用方法:當檔案長期處於寫模式,如資料記錄時,定期呼叫此函式,或者在寫入資料後立即呼叫
此函式,可以減少因為斷電等意外情況帶來的資料損失,有點WORD中後臺定期儲存的意思.
--------------------------------------------------------------------------------- */
/*---------------------------------------------------------------------------------
⑤新建資料夾FRESULT f_mkdir (const TCHAR* DirName)函式,*DirName==指向將要建立的資料夾名的指標
函式說明:新建一個資料夾,
注意:檔名應符合 fatfs 標準,不能包含非法字元,
檔名長度不能大於8,否則新建不成功
例:f_mkdir("new");//新建一個檔名為new的資料夾
--------------------------------------------------------- */
/*---------------------------------------------------------------------------------
⑥刪除檔案和資料夾FRESULT f_unlink()函式,*FileName : 指向檔案或資料夾的名稱的指標
函式說明:此函式可以刪除一個檔案或者資料夾
使用注意項:
刪除資料夾時:1.不能為當前資料夾
2.不能為非空資料夾
刪除檔案時: 1.不能為已開啟檔案
2.不能為只讀檔案
例如:f_unlink("new");//刪除“new”這個資料夾
f_unlink("TEXT/寫入.txt");//刪除“TEXT”這個資料夾下的“寫入”txt文字
刪除檔案的時候必須注意一點 此外的所有尾巴都必須是以png txt結束的
--------------------------------------------------------- */
/*---------------------------------------------------------------------------------
⑦重新命名\移動檔案或資料夾FRESULT f_rename (const TCHAR* OldName,const TCHAR* NewName)
函式說明:此函式可以移動或者重新命名一個檔案或者資料夾
引數說明:*OldName : 指向舊檔名的指標
*NewName : 指向新檔名的指標
使用注意項:
1.此函式可以重新命名 檔案或者資料夾,而不論資料夾是否為空.
2.此函式可以移動 檔案或者資料夾,而不論資料夾是否為空.
例如: res = f_rename("測試.txt","測試1.txt"); //重新命名測試.txt檔案,
res = f_rename("測試1.txt","PAINT/測試2.txt");
//將測試1.txt檔案移動到資料夾PAINT中並重命名為測試2.txt
--------------------------------------------------------- */
/*---------------------------------------------------------------------------------
⑧獲取檔案資訊 FRESULT f_stat(const TCHAR* FileName,FILINFO* FileInfo)
函式說明:此函式可以獲取檔案的最近修改時間,屬性等資訊,獲取的資訊儲存在fileninfo結構體中
引數說明:*FileName: 指向檔名的指標
*FileInfo: 指向儲存檔案資訊的結構體的指標 型別必須為FileInfo
使用注意項:
1.如果目標是資料夾,獲取的大小為0.
2.此函式對根目錄無效.
3.時間和日期均為兩位元組,儲存格式如下:
a) 日期:
i. bit15…bit9: 年 計算後的十進位制數應該加上1980
ii. bit8 … bit5: 月
iii. bit4 … bit0: 日
b) 時間:
i. bit15… bit11 : 時
ii. bit10… bit5 : 分
iii. bit4 … bit0 : 秒 算出的十進位制數應 *2
舉例:
i. 日期: 0000001 0001 00001, 表示 1981 年 1 月 1 日
ii.時間: 00001 000001 00001,表示 1 點 1 分 2 秒
舉例: res = f_stat("TEXT/寫入.txt", &filinfo); //讀取 folder 目錄下 newname.txt 檔案的資訊
if( res )
printf("newname.txt err : %d\r\n", res);//沒讀取檔案資訊成功
else
{
printf("newname.txt size : %lu\r\n",filinfo.fsize);//讀取檔案的長度,即佔多少位元組
printf("fdate : %d\r\n",filinfo.fdate); //讀取檔案的最近修改日期 轉化為2進位制,
printf("ftime : %d\r\n",filinfo.ftime);//讀取檔案的最近修改時間,轉化為2進位制
printf("fattrib : %d\r\n",filinfo.fattrib);//顯示檔案的屬性,即什麼檔案
//#define AM_RDO 0x01 //只讀檔案
//#define AM_HID 0x02 //隱藏檔案
//#define AM_SYS 0x04 //系統檔案
//#define AM_VOL 0x08 //卷標檔案
//#define AM_LFN 0x0F //
//#define AM_DIR 0x10 //程式目錄
//#define AM_ARC 0x20 //存檔檔案
//#define AM_MASK 0x3F //
}
--------------------------------------------------------- */
/*---------------------------------------------------------------------------------
⑨改變檔案屬性:FRESULT f_chmod (const TCHAR* FileName,BYTE Attribute,BYTE AttributeMask)
函式說明:
1. 此函式可以修改檔案或資料夾的屬性
2. 可修改的屬性只能是以下一種或幾種的組合,對其它屬性無效
AM_RDO //只讀檔案
AM_ARC //存檔檔案
AM_SYS //系統檔案
AM_HID //隱藏檔案
引數說明:
a) *Filename:指向檔案或資料夾的名稱的指標
b) Attribute:要置位的屬性,即需要將檔案或者資料夾屬性改成什麼
c) AttributeMask:需要改變的屬性(包括要置位的和要清除的屬性),即包含原屬性和需要更改的屬性
使用方法:
a) Attribute 須為 AttributeMask 的子集
b) 函式對 AttributeMask 中的屬性集合進行處理,若屬性包含在 Attribute中,則置位,否則清除
舉例: 對檔案 TEXT/寫入.txt,置位 HID 和 SYS 屬性,取消 ARC和 RDO 屬性
res = f_chmod("TEXT/寫入.txt", AM_HID | AM_SYS, AM_ARC | AM_RDO | AM_HID |AM_SYS);
if( res )
printf("err :%d\r\n", res);
else
{
res = f_stat("TEXT/寫入.txt", &filinfo);
printf("fattrib : %d\r\n",filinfo.fattrib);//
}
--------------------------------------------------------- */
/*---------------------------------------------------------------------------------
⑩改變檔案時間戳FRESULT f_utime (TCHAR* FileName,FILINFO* TimeDate)
函式說明:
1. 此函式可以更改檔案的最近修改時間
引數說明:
a) Filename :指向檔案的指標
b) Timedate :指向檔案資訊結構體的指標
使用方法: 在這個函式裡,可以我們可以寫入常規的日期時間,然後此函式按日期儲存格式(見上)將資料整合後呼叫 f_utime.
FRESULT set_timestamp ( char *obj,int year, int month, int mday, int hour, int min, int sec);//
{
FILINFO fno;
fno.fdate = (WORD)(((year - 1980) * 512U) | month * 32U | mday);
fno.ftime = (WORD)(hour * 2048U | min * 32U | sec / 2U);
return f_utime(obj, &fno);
res = set_timestamp("123.txt",2001,06,05,02,03,34);//修改 123.txt 時間
printf("%d\r\n",res);
此例沒有通過,沒有找到FRESULT set_timestamp();這個函式原型 。
---------------------------------------------------------
好了,以上就是我對於FATFS檔案系統常用API函式的一些理解,希望可以幫到一些朋友快速瞭解。
筆者也打算定時寫出一些好的博文,雖然現在還很菜,但是我會^_^o~ 努力的,
CSDN,讓我們一起成長
2017.3.18 22:50