繼上一篇博客https://www.cnblogs.com/showtime20190824/p/11523402.html
這一次我們我們再深入探討了解一下FATFS的移植過程,並嘗試在其他內存上進行拓展物理磁盤,博主成功移植於SPI FLASH,硬件為W25Q256,32MB。
關於外部FLASH,具體的細節就不說了,如果對其不是很了解,建議先去學習一下。這里主要提幾點需要注意的:
首先,與上一篇博客的SD卡不同的是,該FLASH的扇區sector大小不是512字節,而是4096字節,每個block塊有16個扇區,每個block大小為65536,因此在CUBEMX中需要調節一個參數(最大扇區大小)
其次,需要選一下FATFS下拉列表中的user-defined,接着生成工程文件
自己拓展用戶自定義磁盤需要在user-diskio.c中添加API接口函數,這點與SD卡不同,因為SD卡自動幫你添加了這些接口,非常方便。
下一步,打開user-diskio.c,添加接口函數,具體有USER_read,USER_write,USER_ioctl三個部分
首先根據我們選擇的硬件,添加幾個宏定義:
#include "STW_w25qxx.h" #define FLASH_SECTOR_SIZE 4096 #define FLASH_SECTOR_COUNT 256*25 //W25Q256,ǰ25M×Ö½Ú¸øFATFSÕ¼Óà #define FLASH_BLOCK_SIZE 65536 //ÿ¸öBLOCKÓÐ8¸öÉÈÇø
接下來修改三個部分的API函數(函數原型框架已經搭好了,只需添加有色字體的代碼):
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 */ for(;count>0;count--){ W25QXX_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE); sector++; buff+=FLASH_SECTOR_SIZE; } return RES_OK; /* USER CODE END READ */ }
#if _USE_WRITE == 1 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 */ for(;count>0;count--){ W25QXX_Write((u8*)buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE); sector++; buff+=FLASH_SECTOR_SIZE; } return RES_OK; /* USER CODE END WRITE */ }
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 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_ERROR; switch(cmd){ case CTRL_SYNC: res = RES_OK; break; case GET_SECTOR_SIZE: *(WORD*)buff = FLASH_SECTOR_SIZE; res = RES_OK; break; case GET_BLOCK_SIZE: *(WORD*)buff = (WORD)FLASH_BLOCK_SIZE; res = RES_OK; break; case GET_SECTOR_COUNT: *(DWORD*)buff = FLASH_SECTOR_COUNT; res = RES_OK; break; default: res = RES_PARERR; break; } return res; /* USER CODE END IOCTL */ } #endif /* _USE_IOCTL == 1 */
OK,以上,我們完成了對外部FLASH的FATFS框架搭建,現在讓我們編寫相關代碼實驗一下:
void FATFS_MOUNT(void){ POINT_COLOR = DARKBLUE; LCD_ShowString(400,400,500,24,24,"****** FATFS START ******"); retSD = f_mount(&SDFatFS, "", 0) && f_mount(&USERFatFS, "", 0); if(retSD){ LCD_ShowString(400,440,500,24,24,"****** mount error ******"); LCD_ShowNum(800,440,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,440,500,24,24,"****** mount successfully!!! ******"); }
void FATFS_WRITE_TEST(void){ POINT_COLOR = DARKBLUE; retSD = f_open(&SDFile, filename, FA_CREATE_ALWAYS | FA_WRITE) && f_open(&USERFile, filename, FA_CREATE_ALWAYS | FA_WRITE);; if(retSD){ LCD_ShowString(400,480,500,24,24,"****** open file error ******"); LCD_ShowNum(800,480,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,480,500,24,24,"****** open file successfully!!! ******"); retSD = f_write(&SDFile, wtext, sizeof(wtext), (void *)&byteswritten) && f_write(&USERFile, wtext, sizeof(wtext), (void *)&byteswritten); if(retSD){ LCD_ShowString(400,520,500,24,24,"****** write file error ******"); LCD_ShowNum(800,520,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,520,500,24,24,"****** write file successfully!!! ******"); retSD = f_close(&SDFile) && f_close(&USERFile); if(retSD){ LCD_ShowString(400,560,500,24,24,"****** close file error ******"); LCD_ShowNum(800,560,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,560,500,24,24,"****** close file successfully!!! ******"); }
void FAFTF_READ_FILE_TEST(void){ POINT_COLOR = DARKBLUE; retSD = f_open(&USERFile, filename, FA_READ);; if(retSD){ LCD_ShowString(400,480,500,24,24,"****** open file error ******"); LCD_ShowNum(800,480,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,480,500,24,24,"****** open file successfully!!! ******"); retSD = f_read(&USERFile, rtext, sizeof(rtext), (void *)&bytesread); if(retSD){ LCD_ShowString(400,520,500,24,24,"****** read file error ******"); LCD_ShowNum(800,560,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,520,500,24,24,"****** read file successfully!!! ******"); retSD = f_close(&USERFile); if(retSD){ LCD_ShowString(400,560,500,24,24,"****** close file error ******"); LCD_ShowNum(800,560,retSD,2,24); Error_Handler(); } else LCD_ShowString(400,560,500,24,24,"****** close file successfully!!! ******"); POINT_COLOR = RED; LCD_ShowString(300,640,260,24,24,"The File Content is:"); LCD_ShowString(560,640,500,24,24,(char*)rtext); }
博主寫了以上三個測試函數,在初始化之后while(1)之前加入下面代碼:
FATFS_MOUNT();
FATFS_WRITE_TEST();
FAFTF_READ_FILE_TEST();
測試結果如下:
最后,提供工程文件下載鏈接。覺得有幫助的朋友可以關注一下博主。
鏈接:https://pan.baidu.com/s/1en7C-aezeWjK2dtSN20pnw
提取碼:ibga