1. 程式人生 > >對STM32中FATFS檔案系統常用API函式的理解

對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介面函式。

那麼,下面就來介紹下 我對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* OldNameconst 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. bit15bit9: 年 計算後的十進位制數應該加上1980

                    ii. bit8 bit5:

                    iii. bit4 bit0:

           b) 時間:

                    i. bit15bit11 :

                    ii. bit10bit5 :

                    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 屬性,取消 ARCRDO 屬性

         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