概述
FATFS
文件系統可以掛載SD卡也可以掛載FLASH
eMMC
等設備
SD卡需要格式化為
FAT32
模式 塊大小默認即可
移植
SD卡
SD卡扇區大小是 512B
SD卡 SDIO模式 可以直接在
cubeMX
里一鍵設置
先設置好SD卡的設置
這個是選擇支持中文 其余是默認
這個是檢測引腳可以留空
當SD卡插入拔出時會引起檢測腳的變化
FLASH
FLASH接入FATFS需要自行修改接口,選用自定義模式
建議配合USB MSC功能使用
cubeMX配置
使用自定義模式,將扇區大小改為從512到4096都可
設置內容
全在cubeMX生成的
user_diskio.c
中
先導入頭文件和設置扇區大小
需要設置的APIs
全在
cubeMX
生成的user_diskio.c
中
初始化
描述 | 名稱 | 功能 |
---|---|---|
BYTE (uint8_t ) | pdrv | 磁盤編號 |
DSTATUS | 輸出 | 錯誤碼 |
DSTATUS USER_initialize (BYTE pdrv)
成功返回
RES_OK
失敗返回RES_ERROR
根據自己初始化寫入函數
例子
這里不需要初始化直接返回成功即可
DSTATUS USER_initialize(BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{/* USER CODE BEGIN INIT */UNUSED(pdrv);return RES_OK;/* USER CODE END INIT */
}
獲取磁盤狀態
描述 | 名稱 | 功能 |
---|---|---|
BYTE (uint8_t ) | pdrv | 磁盤編號 |
DSTATUS | 輸出 | 錯誤碼 |
DSTATUS USER_status(BYTE pdrv)
成功返回
RES_OK
失敗返回RES_ERROR
不使用返回即可
例子
DSTATUS USER_status(BYTE pdrv /* Physical drive number to identify the drive */
)
{/* USER CODE BEGIN STATUS */UNUSED(pdrv);return RES_OK;/* USER CODE END STATUS */
}
讀取扇區
描述 | 名稱 | 功能 |
---|---|---|
BYTE (uint8_t ) | pdrv | 磁盤編號 |
BYTE (uint8_t ) | buff | 緩沖區 |
DWORD | sector | 扇區編號 |
UINT (uint32_t ) | count | 扇區數量 |
DSTATUS | 輸出 | 錯誤碼 |
DRESULT USER_read(BYTE pdrv,BYTE *buff,DWORD sector,UINT count)
示例
這個函數
W25Qxx_Read_Data
輸入的是FLASH的地址和byte數量,因此要乘上扇區大小
DRESULT USER_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 */
)
{/* USER CODE BEGIN READ */W25Qxx_Read_Data(sector * USER_SECTOR_SIZE, buff, count * USER_SECTOR_SIZE);return RES_OK;/* USER CODE END READ */
}
寫入扇區
描述 | 名稱 | 功能 |
---|---|---|
BYTE (uint8_t ) | pdrv | 磁盤編號 |
BYTE (uint8_t ) | buff | 緩沖區 |
DWORD | sector | 扇區編號 |
UINT (uint32_t ) | count | 扇區數量 |
DSTATUS | 輸出 | 錯誤碼 |
DRESULT USER_write(BYTE pdrv,const BYTE *buff,DWORD sector,UINT count)
示例
這個函數
W25Qxx_Write
輸入的是FLASH的地址和byte數量,因此要乘上扇區大小
DRESULT USER_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 */
)
{/* USER CODE BEGIN WRITE *//* USER CODE HERE */W25Qxx_Write(sector * USER_SECTOR_SIZE, (uint8_t *)buff, count * USER_SECTOR_SIZE, 0);return RES_OK;/* USER CODE END WRITE */
}
控制操作
描述 | 名稱 | 功能 |
---|---|---|
BYTE (uint8_t ) | pdrv | 磁盤編號 |
BYTE (uint8_t ) | cmd | 命令 |
void * | buff | 緩沖區 |
DSTATUS | 輸出 | 錯誤碼 |
DRESULT USER_ioctl(BYTE pdrv,BYTE cmd,void *buff)
必須要響應的命令
描述 | 功能 |
---|---|
GET_SECTOR_COUNT | 扇區數量 |
GET_SECTOR_SIZE | 扇區大小 單位byte |
GET_BLOCK_SIZE | 區塊大小 |
例子
使用W25Q128 16MB
扇區大小為4096=4KB
扇區數為 4096 這里寫4095
區塊直接寫1 即可
DRESULT USER_ioctl(BYTE pdrv, /* Physical drive nmuber (0..) */BYTE cmd, /* Control code */void *buff /* Buffer to send/receive control data */
)
{/* USER CODE BEGIN IOCTL */DRESULT res = RES_OK;switch (cmd){case CTRL_SYNC:res = RES_OK;break;case CTRL_TRIM:res = RES_OK;break;case GET_SECTOR_COUNT:*(DWORD *)buff = 4095;break;case GET_SECTOR_SIZE:*(DWORD *)buff = USER_SECTOR_SIZE;break;case GET_BLOCK_SIZE:*(DWORD *)buff = 1;break;}return res;/* USER CODE END IOCTL */
}
APIs
地址問題
根據初始化順序,驅動器的根地址分別為
0:/
1:/
…比如這個例子里 SD卡的根地址是
0:/
USER(可以設為FLASH等) 地址為1:/
掛載
描述 | 名稱 | 功能 |
---|---|---|
FATFS* | fs | 句柄 |
const TCHAR* | path | 地址 |
BYTE | opt | 是否立即加載(一般寫1) |
FRESULT | 輸出 | 錯誤碼 |
FRESULT f_mount (FATFS* fs,const TCHAR* path,BYTE opt)
掛載例子
f_mount(&hFatfs, "0:/", 1);
打開文件
描述 | 名稱 | 功能 |
---|---|---|
FIL* | fp | 文件 |
const TCHAR* | path | 地址 |
BYTE | mode | 模式 |
FRESULT | 輸出 | 錯誤碼 |
描述 | 功能 |
---|---|
FA_READ | 只讀 |
FA_WRITE | 只寫 |
FA_OPEN_EXISTING | 如果文件存在,則打開;否則打開失敗 |
FA_CREATE_NEW | 創建一個文件,如果文件存在,則創建失敗 |
FA_CREATE_ALWAYS | 創建一個文件,如果文件存在,則覆蓋原文件 |
FA_OPEN_ALWAYS | 如果文件存在,則打開,如果不存在則創建一個文件并打開 |
可以輸入
FA_READ | FA_WRITE
來使用讀寫
FRESULT f_open (FIL* fp,const TCHAR* path,BYTE mode)
打開后光標指向開頭
關閉文件
描述 | 名稱 | 功能 |
---|---|---|
FIL* | fp | 文件 |
FRESULT | 輸出 | 錯誤碼 |
FRESULT f_close (FIL* fp)
讀文件
描述 | 名稱 | 功能 |
---|---|---|
FIL* | fp | 文件 |
void* | buff | 緩沖區 |
UINT | btr | 操作數量 |
UINT* | br | 已操作數量 |
FRESULT | 輸出 | 錯誤碼 |
FRESULT f_read (FIL* fp,void* buff,UINT btr,UINT* br)
會從光標處開始讀取 指針自增
寫文件
描述 | 名稱 | 功能 |
---|---|---|
FIL* | fp | 文件 |
void* | buff | 緩沖區 |
UINT | btr | 操作數量 |
UINT* | br | 已操作數量 |
FRESULT | 輸出 | 錯誤碼 |
FRESULT f_write (FIL* fp,const void* buff,UINT btw,UINT* bw)
會從光標處開始寫入 指針自增
打印到文件
描述 | 名稱 | 功能 |
---|---|---|
FIL* | fp | 文件 |
const TCHAR* | fmt | 規則格式串 |
... | ... | ... |
int | 輸出 | 寫入數量 |
int f_printf (FIL* fp,const TCHAR* fmt,...)
會從光標處開始寫入 指針自增
獲取文件大小
描述 | 名稱 | 功能 |
---|---|---|
FIL* | fp | 文件 |
FSIZE_t | 輸出 | 大小 |
f_size(fp)
改變光標位置
描述 | 名稱 | 功能 |
---|---|---|
FIL* | fp | 文件 |
FSIZE_t | ofs | 從頂部開始的偏移 |
FRESULT | 輸出 | 錯誤碼 |
FRESULT f_lseek (FIL* fp,FSIZE_t ofs)
刪除文件
描述 | 名稱 | 功能 |
---|---|---|
const TCHAR* | path | 路徑 |
FRESULT | 輸出 | 錯誤碼 |
FRESULT f_unlink (const TCHAR* path)
檢查文件是否存在
描述 | 名稱 | 功能 |
---|---|---|
const TCHAR* | path | 路徑 |
FILINFO* | fno | 信息 |
FRESULT | 輸出 | 不存在FR_NO_FILE ,存在FR_OK |
FRESULT f_stat (const TCHAR* path,FILINFO* fno)