zynq之TF卡寫入常見問題
1、基本原理
前面做過zynq的TF讀寫實驗,使用串口返回了實驗所需的現象。那個時候也沒有深究頭文件"ff.h"里的幾個常用的函數。這次需要使用TF卡做實驗時發現很多操作都不大一樣,不能夠簡單的重復,這里把幾個常見的問題列舉出來,方便以后的查閱。
2、實際問題
先用一段完整的代碼:
#include <stdio.h> #include "xil_printf.h" #include "xdevcfg.h" #include "xparameters.h" #include "ff.h" int SD_Init(void); int Sd_Test_Write(void); int main() { SD_Init(); Sd_Test_Write(); while(1) { ; } return 0; } static FATFS fatfs; int SD_Init() { FRESULT rc; rc = f_mount(&fatfs,"",0); if(rc) { return XST_FAILURE; } return XST_SUCCESS; } int Sd_Test_Write() { FIL fil; FRESULT rc; UINT br; const char src_str1[] = "t\n"; rc = f_open(&fil,"tesc.txt", FA_OPEN_ALWAYS | FA_WRITE); if(rc) { ; } rc = f_lseek(&fil, f_size(&fil)); rc = f_write(&fil,src_str1,sizeof(src_str1),&br); rc = f_lseek(&fil, f_size(&fil)); rc = f_write(&fil,"t/n",sizeof("t/n"),&br); //rc = f_sync(&fil); rc = f_close(&fil); }
代碼中幾個重要的部分如下:
SD_Init函數中的f_mount是啟動SD卡的分區的,一般一次就足夠了,可以獲得SD卡的地址方便后面函數使用。其他的判斷返回語句都是用於顯示地址載入是否成功。f_mount同樣可以用於注銷工作區,f_mount(0,NULL)就可以注銷0為根目錄的工作區。
Sd_Test_Write函數中比較關鍵的函數有:f_open , f_lseek , f_write , f_sync,f_close , f_size;
(1)f_open
打開文件的,也可以用於創建文件,第一個參數是文件對象的地址,第二個是字符串名稱,第三個是對應相關的模式。
FA_OPEN_ALWAYS:總是打開模式,有則打開,無則創建,反正要執行到底。
FA_OPEN_EXISTING:存在打開模式,有才打開,無則失敗,需要確認有文件才執行。
FA_CREATE_NEW:創建新文件模式,無才創建,有則失敗,需要確認沒有文件才執行。
FA_CREATE_ALWAYS:總是創建模式,無則創建,有則覆蓋創建(原文件被覆蓋),反正要建新文件。
FA_WRITE:寫模式,允許寫入數據
FA_READ:讀模式,允許讀取數據
顯然,前面四種模式是執行模式,后面兩種是權限模式,執行和權限可以同時設置。
注意總是打開和總是創建的區別,兩者最后都會生成一個文件,總是打開模式會留有已存文件,而總是創建模式只會出新文件。
(2)f_lseek
用於設置起始操作點,第一個參數還是文件對象的地址,第二個可以是數字表示長度,也可以是專門的文件大小的類。這里可以配合f_size(文件對象的地址)得到的文件長度來設置為文件尾為初始操作。
(3)f_write
用於寫入數據的函數。第一個參數依舊是文件對象的地址,第二個是字符串或者數組地址(也可能有其他的,還沒有遇到),第三個是字符長度,這里可以使用sizeof函數讀取,第四個是無符號整型變量的地址,用於指針計數。第四個參數的作用暫時不清楚。
這里需要注意的是,在打開文件之后,如果進行多次的f_write操作,寫入的字符串不能太大,否則容易出現亂碼。也可以提高寫入數據的長度(具體多大根據測試可知,一般需要提高到256的整數倍才可以避免亂碼)。這也是f_write不好作為SD卡寫入的函數的原因,容易浪費資源。找資料時發現可以使用f_printf,有時間再測試一下。
(4)f_sync
這個好像是一個用於檢查的函數,寫入失敗可能會有一些提示,由於沒有測試這個函數,就不好多解釋了。參數也就是文件對象的地址。
(5)f_close
關閉文件。這個就一個參數,文件對象的地址。
test my_sd function! test my_sd function! test my_sd function! t t t t/n
這個是開頭源碼產生的文件的內容,可以參考一下(不完全是,還有其他操作的內容)。
3、概括小結
總結一下文件寫操作的基本步驟:
創建工作區 == 打開移動存儲卡
打開文件 == 打開文件(這里也可以通過轉義字符\實現目錄的構建)
確認寫入起點 == 鼠標點擊某處
寫入特定長度字符 == 鍵盤輸入數據
檢查文件 ==確認輸入正確
關閉文件 == 關閉文件
關閉工作台 == 拔出移動存儲卡
這就是寫操作的基本流程與PC操作的基本流程的對應關系。
至於讀操作,基本原理是一樣的,就是將f_write換成f_read。兩者的參數都是一樣的,注意f_open的工作模式即可。注意存儲數據需要使用字符串數組存儲。