# FATS的移植过程 1.[参考文档](https://blog.csdn.net/weixin_42042056/article/details/118190017?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-118190017-blog-22197877.pc_relevant_3mothn_strategy_recovery&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-118190017-blog-22197877.pc_relevant_3mothn_strategy_recovery&utm_relevant_index=1) 课程资料EX8 2.添加FATS的库文件,把.C改成.CPP,移除头文件里面所有的 ```c #ifdef __cplusplus extern "C" { #endif ``` 3.添加FLASH读写的接口文件 4.改写diskio.cpp文件的接口函数,参考如下,FATS的版本为:12c ```c /*第一步:添加自己的头文件*/ #include "../W25QXXArduino/w25qxx.h" /*第二步:添加一些宏定义*/ #define FLASH_SECTOR_SIZE 512 #define FLASH_SECTOR_COUNT 2048 * 16 #define FLASH_BLOCK_SIZE 8 /*第三步:改写如下函数*/ DSTATUS disk_status ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { return RES_OK; } /*-----------------------------------------------------------------------*/ /* Inidialize a Drive */ /*-----------------------------------------------------------------------*/ DSTATUS disk_initialize ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { DSTATUS stat = RES_OK; W25QXX_Init(); return stat; } /*-----------------------------------------------------------------------*/ /* Read Sector(s) */ /*-----------------------------------------------------------------------*/ DRESULT disk_read ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ BYTE *buff, /* Data buffer to store read data */ DWORD sector, /* Start sector in LBA */ UINT count /* Number of sectors to read */ ) { DRESULT res = RES_OK; if(!count) return RES_PARERR; //count????0,???????? for(;count > 0;count--){ W25QXX_Read(buff,sector * FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE); sector ++; buff += FLASH_SECTOR_SIZE; } return res; } /*-----------------------------------------------------------------------*/ /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ DRESULT disk_write ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ const BYTE *buff, /* Data to be written */ DWORD sector, /* Start sector in LBA */ UINT count /* Number of sectors to write */ ) { DRESULT res = RES_OK; if(!count) return RES_PARERR; //count????0,???????? for(;count > 0;count --){ W25QXX_Write((uint8_t *)buff, sector * FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE); sector ++; buff += FLASH_SECTOR_SIZE; } return res; } /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ /*-----------------------------------------------------------------------*/ DRESULT disk_ioctl ( BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE cmd, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { DRESULT res = RES_OK; 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 = 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; } ``` 5.修改**ffconf.h**宏定义: ```c #define _FS_NORTC 1 //修改为1,禁用时间 #define _MIN_SS 512 //不修改 #define _MAX_SS 4096 //修改为4096 #define _USE_MKFS 1 //使能一些函数 ``` 6.写入测试块 ```c /***FATS 这几个变量设置为全局变量,不然会栈溢出错误***/ BYTE work[4096]; //FATFS工作缓冲区 FATFS fs; //文件系统对象 FIL fil; //文件对象 FRESULT res;//操作返回对象 UINT bw, i; //临时变量 BYTE mm[500]; //临时数组 /***FATS***/ ``` ``` res = f_mount(&fs, "0:",1); if(res == 0X0D) //FLASH磁盘,FAT文件系统错误,重新格式化FLASH { Serial.printf("Flash Disk Formatting...\n"); //格式化FLASH res = f_mkfs("0:",FM_ANY,0,work,sizeof(work)); if(res != FR_OK) Serial.printf("mkfs error.\n"); } if(res == FR_OK) Serial.printf("FATFS Init ok!\n"); res = f_open(&fil,"0:/test.txt",FA_CREATE_NEW); if(res != FR_OK && res != FR_EXIST) Serial.printf("create file error.\n"); if(res == FR_EXIST) res = f_open(&fil,"0:test.txt",FA_WRITE|FA_READ|FA_OPEN_APPEND); if(res != FR_OK) Serial.printf("open file error.\n"); else{ Serial.printf("open file ok.\n"); f_puts("Hello,World!\n你好世界\n",&fil); Serial.printf("file size:%lu Bytes.\n", f_size(&fil)); memset(mm,0x0,500); f_lseek(&fil,0); res = f_read(&fil,mm,500,&i); if(res == FR_OK) printf("read size:%d Bytes.\n%s",i,mm); else Serial.printf("read error!\r\n"); f_close(&fil); /*卸载文件系统*/ f_mount(0,"0:",0); } ``` 正常结果显示: ```c ets Jun 8 2016 00:22:57 rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff0030,len:1344 load:0x40078000,len:13864 load:0x40080400,len:3608 entry 0x400805f0 flash is EF17 FATFS Init ok! open file ok. file size:104 Bytes. read size:104 Bytes. Hello,World! 你好世界 Hello,World! 你好世界 Hello,World! 你好世界 Hello,World! 你好世界 ``` ## 注意点 1. [Arduino头文件包含的注意](https://blog.csdn.net/weixin_42042056/article/details/118190017?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-118190017-blog-22197877.pc_relevant_3mothn_strategy_recovery&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-1-118190017-blog-22197877.pc_relevant_3mothn_strategy_recovery&utm_relevant_index=1) 2. C++和C语言冲突的问题解决相关C语言和C++冲突的问题: ```c error: unknown type name 'class' error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token error: unknown type name 'SPIClass' ``` 解决 :把所有的.c改成.cpp;删除 ```c #ifdef __cplusplus extern "C" { #endif /*代码块*/ #ifdef __cplusplus extern "C" } #endif 3. 栈溢出错误导致无限重启,将FATS测试变量设置为全局的,[参考解释](https://blog.csdn.net/qq_41828707/article/details/108527610)