FatFs文件系统:
ff11a.zip
来自网站:http://elm-chan.org/fsw/ff/00index_e.html

FatFs文件系统移植

视频教程:https://www.bilibili.com/video/BV1yW411Y7Gw?p=65

diskio.h

  1. /*-----------------------------------------------------------------------/
  2. / Low level disk interface modlue include file (C)ChaN, 2014 /
  3. /-----------------------------------------------------------------------*/
  4. #ifndef _DISKIO_DEFINED
  5. #define _DISKIO_DEFINED
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. #define _USE_WRITE 1 /* 1: Enable disk_write function */
  10. #define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */
  11. #include "integer.h"
  12. /* Status of Disk Functions */
  13. typedef BYTE DSTATUS;
  14. /* Results of Disk Functions */
  15. typedef enum {
  16. RES_OK = 0, /* 0: Successful */
  17. RES_ERROR, /* 1: R/W Error */
  18. RES_WRPRT, /* 2: Write Protected */
  19. RES_NOTRDY, /* 3: Not Ready */
  20. RES_PARERR /* 4: Invalid Parameter */
  21. } DRESULT;
  22. /*---------------------------------------*/
  23. /* Prototypes for disk control functions */
  24. DSTATUS disk_initialize (BYTE pdrv);
  25. DSTATUS disk_status (BYTE pdrv);
  26. DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
  27. DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
  28. DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
  29. /* Disk Status Bits (DSTATUS) */
  30. #define STA_NOINIT 0x01 /* Drive not initialized */
  31. #define STA_NODISK 0x02 /* No medium in the drive */
  32. #define STA_PROTECT 0x04 /* Write protected */
  33. /* Command code for disk_ioctrl fucntion */
  34. /* Generic command (Used by FatFs) */
  35. #define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
  36. #define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
  37. #define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
  38. #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
  39. #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
  40. /* Generic command (Not used by FatFs) */
  41. #define CTRL_POWER 5 /* Get/Set power status */
  42. #define CTRL_LOCK 6 /* Lock/Unlock media removal */
  43. #define CTRL_EJECT 7 /* Eject media */
  44. #define CTRL_FORMAT 8 /* Create physical format on the media */
  45. /* MMC/SDC specific ioctl command */
  46. #define MMC_GET_TYPE 10 /* Get card type */
  47. #define MMC_GET_CSD 11 /* Get CSD */
  48. #define MMC_GET_CID 12 /* Get CID */
  49. #define MMC_GET_OCR 13 /* Get OCR */
  50. #define MMC_GET_SDSTAT 14 /* Get SD status */
  51. /* ATA/CF specific ioctl command */
  52. #define ATA_GET_REV 20 /* Get F/W revision */
  53. #define ATA_GET_MODEL 21 /* Get model name */
  54. #define ATA_GET_SN 22 /* Get serial number */
  55. #ifdef __cplusplus
  56. }
  57. #endif
  58. #endif

diskio.c

  1. /*-----------------------------------------------------------------------*/
  2. /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2013 */
  3. /*-----------------------------------------------------------------------*/
  4. /* If a working storage control module is available, it should be */
  5. /* attached to the FatFs via a glue function rather than modifying it. */
  6. /* This is an example of glue functions to attach various exsisting */
  7. /* storage control module to the FatFs module with a defined API. */
  8. /*-----------------------------------------------------------------------*/
  9. #include "diskio.h" /* FatFs lower layer API */
  10. #include "ff.h"
  11. #include "./flash/bsp_spi_flash.h"
  12. /* 为每个设备定义一个物理编号 */
  13. #define ATA 0 // 预留SD卡使用
  14. #define SPI_FLASH 1 // 外部SPI Flash
  15. /*-----------------------------------------------------------------------*/
  16. /* 获取设备状态 */
  17. /*-----------------------------------------------------------------------*/
  18. DSTATUS disk_status (
  19. BYTE pdrv /* 物理编号 */
  20. )
  21. {
  22. DSTATUS status = STA_NOINIT;
  23. switch (pdrv) {
  24. case ATA: /* SD CARD */
  25. break;
  26. case SPI_FLASH:
  27. /* SPI Flash状态检测:读取SPI Flash 设备ID */
  28. if(sFLASH_ID == SPI_FLASH_ReadID())
  29. {
  30. /* 设备ID读取结果正确 */
  31. status &= ~STA_NOINIT;
  32. }
  33. else
  34. {
  35. /* 设备ID读取结果错误 */
  36. status = STA_NOINIT;;
  37. }
  38. break;
  39. default:
  40. status = STA_NOINIT;
  41. }
  42. return status;
  43. }
  44. /*-----------------------------------------------------------------------*/
  45. /* 设备初始化 */
  46. /*-----------------------------------------------------------------------*/
  47. DSTATUS disk_initialize (
  48. BYTE pdrv /* 物理编号 */
  49. )
  50. {
  51. uint16_t i;
  52. DSTATUS status = STA_NOINIT;
  53. switch (pdrv) {
  54. case ATA: /* SD CARD */
  55. break;
  56. case SPI_FLASH: /* SPI Flash */
  57. /* 初始化SPI Flash */
  58. SPI_FLASH_Init();
  59. /* 延时一小段时间 */
  60. i=500;
  61. while(--i);
  62. /* 唤醒SPI Flash */
  63. SPI_Flash_WAKEUP();
  64. /* 获取SPI Flash芯片状态 */
  65. status=disk_status(SPI_FLASH);
  66. break;
  67. default:
  68. status = STA_NOINIT;
  69. }
  70. return status;
  71. }
  72. /*-----------------------------------------------------------------------*/
  73. /* 读扇区:读取扇区内容到指定存储区 */
  74. /*-----------------------------------------------------------------------*/
  75. DRESULT disk_read (
  76. BYTE pdrv, /* 设备物理编号(0..) */
  77. BYTE *buff, /* 数据缓存区 */
  78. DWORD sector, /* 扇区首地址 */
  79. UINT count /* 扇区个数(1..128) */
  80. )
  81. {
  82. DRESULT status = RES_PARERR;
  83. switch (pdrv) {
  84. case ATA: /* SD CARD */
  85. break;
  86. case SPI_FLASH:
  87. /* 扇区偏移2MB,外部Flash文件系统空间放在SPI Flash后面6MB空间 */
  88. sector+=512;
  89. SPI_FLASH_BufferRead(buff, sector <<12, count<<12);
  90. status = RES_OK;
  91. break;
  92. default:
  93. status = RES_PARERR;
  94. }
  95. return status;
  96. }
  97. /*-----------------------------------------------------------------------*/
  98. /* 写扇区:见数据写入指定扇区空间上 */
  99. /*-----------------------------------------------------------------------*/
  100. #if _USE_WRITE
  101. DRESULT disk_write (
  102. BYTE pdrv, /* 设备物理编号(0..) */
  103. const BYTE *buff, /* 欲写入数据的缓存区 */
  104. DWORD sector, /* 扇区首地址 */
  105. UINT count /* 扇区个数(1..128) */
  106. )
  107. {
  108. uint32_t write_addr;
  109. DRESULT status = RES_PARERR;
  110. if (!count) {
  111. return RES_PARERR; /* Check parameter */
  112. }
  113. switch (pdrv) {
  114. case ATA: /* SD CARD */
  115. break;
  116. case SPI_FLASH:
  117. /* 扇区偏移2MB,外部Flash文件系统空间放在SPI Flash后面6MB空间 */
  118. sector+=512;
  119. write_addr = sector<<12;
  120. SPI_FLASH_SectorErase(write_addr); // 擦掉
  121. SPI_FLASH_BufferWrite((u8 *)buff,write_addr,count<<12);
  122. status = RES_OK;
  123. break;
  124. default:
  125. status = RES_PARERR;
  126. }
  127. return status;
  128. }
  129. #endif
  130. /*-----------------------------------------------------------------------*/
  131. /* 其他控制 */
  132. /*-----------------------------------------------------------------------*/
  133. #if _USE_IOCTL
  134. DRESULT disk_ioctl (
  135. BYTE pdrv, /* 物理编号 */
  136. BYTE cmd, /* 控制指令 */
  137. void *buff /* 写入或者读取数据地址指针 */
  138. )
  139. {
  140. DRESULT status = RES_PARERR;
  141. switch (pdrv) {
  142. case ATA: /* SD CARD */
  143. break;
  144. case SPI_FLASH:
  145. switch (cmd) {
  146. /* 扇区数量:1536*4096/1024/1024=6(MB) */
  147. case GET_SECTOR_COUNT:
  148. *(DWORD * )buff = 1536;
  149. break;
  150. /* 扇区大小 */
  151. case GET_SECTOR_SIZE :
  152. *(WORD * )buff = 4096;
  153. break;
  154. /* 同时擦除扇区个数 */
  155. case GET_BLOCK_SIZE :
  156. *(DWORD * )buff = 1;
  157. break;
  158. }
  159. status = RES_OK;
  160. break;
  161. default:
  162. status = RES_PARERR;
  163. }
  164. return status;
  165. }
  166. #endif
  167. __weak DWORD get_fattime(void) {
  168. /* 返回当前时间戳 */
  169. return ((DWORD)(2015 - 1980) << 25) /* Year 2015 */
  170. | ((DWORD)1 << 21) /* Month 1 */
  171. | ((DWORD)1 << 16) /* Mday 1 */
  172. | ((DWORD)0 << 11) /* Hour 0 */
  173. | ((DWORD)0 << 5) /* Min 0 */
  174. | ((DWORD)0 >> 1); /* Sec 0 */
  175. }

main.c

  1. /**
  2. ******************************************************************************
  3. * @file main.c
  4. * @author fire
  5. * @version V1.0
  6. * @date 2013-xx-xx
  7. * @brief SPI FLASH文件系统例程
  8. ******************************************************************************
  9. * @attention
  10. *
  11. * 实验平台:野火 STM32 F103-霸道 开发板
  12. * 论坛 :http://www.firebbs.cn
  13. * 淘宝 :https://fire-stm32.taobao.com
  14. *
  15. ******************************************************************************
  16. */
  17. #include "stm32f10x.h"
  18. #include "ff.h"
  19. #include "./flash/bsp_spi_flash.h"
  20. #include "./usart/bsp_usart.h"
  21. #include "./led/bsp_led.h"
  22. FATFS fs; /* FatFs文件系统对象 */
  23. FIL fnew; /* 文件对象 */
  24. FRESULT res_flash; /* 文件操作结果 */
  25. UINT fnum; /* 文件成功读写数量 */
  26. BYTE ReadBuffer[1024]={0}; /* 读缓冲区 */
  27. BYTE WriteBuffer[] = /* 写缓冲区*/
  28. "欢迎使用野火STM32开发板 今天是个好日子,新建文件系统测试文件\r\n";
  29. int main(void)
  30. {
  31. /* 初始化LED */
  32. LED_GPIO_Config();
  33. LED_BLUE;
  34. /* 初始化调试串口,一般为串口1 */
  35. USART_Config();
  36. printf("****** 这是一个SPI FLASH 文件系统实验 ******\r\n");
  37. //在外部SPI Flash挂载文件系统,文件系统挂载时会对SPI设备初始化
  38. //初始化函数调用流程如下
  39. //f_mount()->find_volume()->disk_initialize->SPI_FLASH_Init()
  40. res_flash = f_mount(&fs,"1:",1);
  41. /*----------------------- 格式化测试 -----------------*/
  42. /* 如果没有文件系统就格式化创建创建文件系统 */
  43. if(res_flash == FR_NO_FILESYSTEM)
  44. {
  45. printf("》FLASH还没有文件系统,即将进行格式化...\r\n");
  46. /* 格式化 */
  47. res_flash=f_mkfs("1:",0,0);
  48. if(res_flash == FR_OK)
  49. {
  50. printf("》FLASH已成功格式化文件系统。\r\n");
  51. /* 格式化后,先取消挂载 */
  52. res_flash = f_mount(NULL,"1:",1);
  53. /* 重新挂载 */
  54. res_flash = f_mount(&fs,"1:",1);
  55. }
  56. else
  57. {
  58. LED_RED;
  59. printf("《《格式化失败。》》\r\n");
  60. while(1);
  61. }
  62. }
  63. else if(res_flash!=FR_OK)
  64. {
  65. printf("!!外部Flash挂载文件系统失败。(%d)\r\n",res_flash);
  66. printf("!!可能原因:SPI Flash初始化不成功。\r\n");
  67. while(1);
  68. }
  69. else
  70. {
  71. printf("》文件系统挂载成功,可以进行读写测试\r\n");
  72. }
  73. /*----------------------- 文件系统测试:写测试 -------------------*/
  74. /* 打开文件,每次都以新建的形式打开,属性为可写 */
  75. printf("\r\n****** 即将进行文件写入测试... ******\r\n");
  76. res_flash = f_open(&fnew, "1:FatFs读写测试文件.txt",FA_CREATE_ALWAYS | FA_WRITE );
  77. if ( res_flash == FR_OK )
  78. {
  79. printf("》打开/创建FatFs读写测试文件.txt文件成功,向文件写入数据。\r\n");
  80. /* 将指定存储区内容写入到文件内 */
  81. res_flash=f_write(&fnew,WriteBuffer,sizeof(WriteBuffer),&fnum);
  82. if(res_flash==FR_OK)
  83. {
  84. printf("》文件写入成功,写入字节数据:%d\n",fnum);
  85. printf("》向文件写入的数据为:\r\n%s\r\n",WriteBuffer);
  86. }
  87. else
  88. {
  89. printf("!!文件写入失败:(%d)\n",res_flash);
  90. }
  91. /* 不再读写,关闭文件 */
  92. f_close(&fnew);
  93. }
  94. else
  95. {
  96. LED_RED;
  97. printf("!!打开/创建文件失败。\r\n");
  98. }
  99. /*------------------- 文件系统测试:读测试 --------------------------*/
  100. printf("****** 即将进行文件读取测试... ******\r\n");
  101. res_flash = f_open(&fnew, "1:FatFs读写测试文件.txt",FA_OPEN_EXISTING | FA_READ);
  102. if(res_flash == FR_OK)
  103. {
  104. LED_GREEN;
  105. printf("》打开文件成功。\r\n");
  106. res_flash = f_read(&fnew, ReadBuffer, sizeof(ReadBuffer), &fnum);
  107. if(res_flash==FR_OK)
  108. {
  109. printf("》文件读取成功,读到字节数据:%d\r\n",fnum);
  110. printf("》读取得的文件数据为:\r\n%s \r\n", ReadBuffer);
  111. }
  112. else
  113. {
  114. printf("!!文件读取失败:(%d)\n",res_flash);
  115. }
  116. }
  117. else
  118. {
  119. LED_RED;
  120. printf("!!打开文件失败。\r\n");
  121. }
  122. /* 不再读写,关闭文件 */
  123. f_close(&fnew);
  124. /* 不再使用文件系统,取消挂载文件系统 */
  125. f_mount(NULL,"1:",1);
  126. /* 操作完成,停机 */
  127. while(1)
  128. {
  129. }
  130. }
  131. /*********************************************END OF FILE**********************/

1-FatFs文件系统移植.zip

FatFs文件系统常用函数测试

视频教程:https://www.bilibili.com/video/BV1yW411Y7Gw?p=67

diskio.h

  1. /*-----------------------------------------------------------------------/
  2. / Low level disk interface modlue include file (C)ChaN, 2014 /
  3. /-----------------------------------------------------------------------*/
  4. #ifndef _DISKIO_DEFINED
  5. #define _DISKIO_DEFINED
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. #define _USE_WRITE 1 /* 1: Enable disk_write function */
  10. #define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */
  11. #include "integer.h"
  12. /* Status of Disk Functions */
  13. typedef BYTE DSTATUS;
  14. /* Results of Disk Functions */
  15. typedef enum {
  16. RES_OK = 0, /* 0: Successful */
  17. RES_ERROR, /* 1: R/W Error */
  18. RES_WRPRT, /* 2: Write Protected */
  19. RES_NOTRDY, /* 3: Not Ready */
  20. RES_PARERR /* 4: Invalid Parameter */
  21. } DRESULT;
  22. /*---------------------------------------*/
  23. /* Prototypes for disk control functions */
  24. DSTATUS disk_initialize (BYTE pdrv);
  25. DSTATUS disk_status (BYTE pdrv);
  26. DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
  27. DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
  28. DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
  29. /* Disk Status Bits (DSTATUS) */
  30. #define STA_NOINIT 0x01 /* Drive not initialized */
  31. #define STA_NODISK 0x02 /* No medium in the drive */
  32. #define STA_PROTECT 0x04 /* Write protected */
  33. /* Command code for disk_ioctrl fucntion */
  34. /* Generic command (Used by FatFs) */
  35. #define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
  36. #define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
  37. #define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
  38. #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
  39. #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
  40. /* Generic command (Not used by FatFs) */
  41. #define CTRL_POWER 5 /* Get/Set power status */
  42. #define CTRL_LOCK 6 /* Lock/Unlock media removal */
  43. #define CTRL_EJECT 7 /* Eject media */
  44. #define CTRL_FORMAT 8 /* Create physical format on the media */
  45. /* MMC/SDC specific ioctl command */
  46. #define MMC_GET_TYPE 10 /* Get card type */
  47. #define MMC_GET_CSD 11 /* Get CSD */
  48. #define MMC_GET_CID 12 /* Get CID */
  49. #define MMC_GET_OCR 13 /* Get OCR */
  50. #define MMC_GET_SDSTAT 14 /* Get SD status */
  51. /* ATA/CF specific ioctl command */
  52. #define ATA_GET_REV 20 /* Get F/W revision */
  53. #define ATA_GET_MODEL 21 /* Get model name */
  54. #define ATA_GET_SN 22 /* Get serial number */
  55. #ifdef __cplusplus
  56. }
  57. #endif
  58. #endif

diskio.c

  1. /*-----------------------------------------------------------------------*/
  2. /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2013 */
  3. /*-----------------------------------------------------------------------*/
  4. /* If a working storage control module is available, it should be */
  5. /* attached to the FatFs via a glue function rather than modifying it. */
  6. /* This is an example of glue functions to attach various exsisting */
  7. /* storage control module to the FatFs module with a defined API. */
  8. /*-----------------------------------------------------------------------*/
  9. #include "diskio.h" /* FatFs lower layer API */
  10. #include "ff.h"
  11. #include "./flash/bsp_spi_flash.h"
  12. /* 为每个设备定义一个物理编号 */
  13. #define ATA 0 // 预留SD卡使用
  14. #define SPI_FLASH 1 // 外部SPI Flash
  15. /*-----------------------------------------------------------------------*/
  16. /* 获取设备状态 */
  17. /*-----------------------------------------------------------------------*/
  18. DSTATUS disk_status (
  19. BYTE pdrv /* 物理编号 */
  20. )
  21. {
  22. DSTATUS status = STA_NOINIT;
  23. switch (pdrv) {
  24. case ATA: /* SD CARD */
  25. break;
  26. case SPI_FLASH:
  27. /* SPI Flash状态检测:读取SPI Flash 设备ID */
  28. if(sFLASH_ID == SPI_FLASH_ReadID())
  29. {
  30. /* 设备ID读取结果正确 */
  31. status &= ~STA_NOINIT;
  32. }
  33. else
  34. {
  35. /* 设备ID读取结果错误 */
  36. status = STA_NOINIT;;
  37. }
  38. break;
  39. default:
  40. status = STA_NOINIT;
  41. }
  42. return status;
  43. }
  44. /*-----------------------------------------------------------------------*/
  45. /* 设备初始化 */
  46. /*-----------------------------------------------------------------------*/
  47. DSTATUS disk_initialize (
  48. BYTE pdrv /* 物理编号 */
  49. )
  50. {
  51. uint16_t i;
  52. DSTATUS status = STA_NOINIT;
  53. switch (pdrv) {
  54. case ATA: /* SD CARD */
  55. break;
  56. case SPI_FLASH: /* SPI Flash */
  57. /* 初始化SPI Flash */
  58. SPI_FLASH_Init();
  59. /* 延时一小段时间 */
  60. i=500;
  61. while(--i);
  62. /* 唤醒SPI Flash */
  63. SPI_Flash_WAKEUP();
  64. /* 获取SPI Flash芯片状态 */
  65. status=disk_status(SPI_FLASH);
  66. break;
  67. default:
  68. status = STA_NOINIT;
  69. }
  70. return status;
  71. }
  72. /*-----------------------------------------------------------------------*/
  73. /* 读扇区:读取扇区内容到指定存储区 */
  74. /*-----------------------------------------------------------------------*/
  75. DRESULT disk_read (
  76. BYTE pdrv, /* 设备物理编号(0..) */
  77. BYTE *buff, /* 数据缓存区 */
  78. DWORD sector, /* 扇区首地址 */
  79. UINT count /* 扇区个数(1..128) */
  80. )
  81. {
  82. DRESULT status = RES_PARERR;
  83. switch (pdrv) {
  84. case ATA: /* SD CARD */
  85. break;
  86. case SPI_FLASH:
  87. /* 扇区偏移2MB,外部Flash文件系统空间放在SPI Flash后面6MB空间 */
  88. sector+=512;
  89. SPI_FLASH_BufferRead(buff, sector <<12, count<<12);
  90. status = RES_OK;
  91. break;
  92. default:
  93. status = RES_PARERR;
  94. }
  95. return status;
  96. }
  97. /*-----------------------------------------------------------------------*/
  98. /* 写扇区:见数据写入指定扇区空间上 */
  99. /*-----------------------------------------------------------------------*/
  100. #if _USE_WRITE
  101. DRESULT disk_write (
  102. BYTE pdrv, /* 设备物理编号(0..) */
  103. const BYTE *buff, /* 欲写入数据的缓存区 */
  104. DWORD sector, /* 扇区首地址 */
  105. UINT count /* 扇区个数(1..128) */
  106. )
  107. {
  108. uint32_t write_addr;
  109. DRESULT status = RES_PARERR;
  110. if (!count) {
  111. return RES_PARERR; /* Check parameter */
  112. }
  113. switch (pdrv) {
  114. case ATA: /* SD CARD */
  115. break;
  116. case SPI_FLASH:
  117. /* 扇区偏移2MB,外部Flash文件系统空间放在SPI Flash后面6MB空间 */
  118. sector+=512;
  119. write_addr = sector<<12;
  120. SPI_FLASH_SectorErase(write_addr);
  121. SPI_FLASH_BufferWrite((u8 *)buff,write_addr,count<<12);
  122. status = RES_OK;
  123. break;
  124. default:
  125. status = RES_PARERR;
  126. }
  127. return status;
  128. }
  129. #endif
  130. /*-----------------------------------------------------------------------*/
  131. /* 其他控制 */
  132. /*-----------------------------------------------------------------------*/
  133. #if _USE_IOCTL
  134. DRESULT disk_ioctl (
  135. BYTE pdrv, /* 物理编号 */
  136. BYTE cmd, /* 控制指令 */
  137. void *buff /* 写入或者读取数据地址指针 */
  138. )
  139. {
  140. DRESULT status = RES_PARERR;
  141. switch (pdrv) {
  142. case ATA: /* SD CARD */
  143. break;
  144. case SPI_FLASH:
  145. switch (cmd) {
  146. /* 扇区数量:1536*4096/1024/1024=6(MB) */
  147. case GET_SECTOR_COUNT:
  148. *(DWORD * )buff = 1536;
  149. break;
  150. /* 扇区大小 */
  151. case GET_SECTOR_SIZE :
  152. *(WORD * )buff = 4096;
  153. break;
  154. /* 同时擦除扇区个数 */
  155. case GET_BLOCK_SIZE :
  156. *(DWORD * )buff = 1;
  157. break;
  158. }
  159. status = RES_OK;
  160. break;
  161. default:
  162. status = RES_PARERR;
  163. }
  164. return status;
  165. }
  166. #endif
  167. __weak DWORD get_fattime(void) {
  168. /* 返回当前时间戳 */
  169. return ((DWORD)(2015 - 1980) << 25) /* Year 2015 */
  170. | ((DWORD)1 << 21) /* Month 1 */
  171. | ((DWORD)1 << 16) /* Mday 1 */
  172. | ((DWORD)0 << 11) /* Hour 0 */
  173. | ((DWORD)0 << 5) /* Min 0 */
  174. | ((DWORD)0 >> 1); /* Sec 0 */
  175. }

main.c

  1. /**
  2. ******************************************************************************
  3. * @file main.c
  4. * @author fire
  5. * @version V1.0
  6. * @date 2013-xx-xx
  7. * @brief SPI FLASH文件系统常用功能演示
  8. ******************************************************************************
  9. * @attention
  10. *
  11. * 实验平台:野火 STM32 F103-霸道 开发板
  12. * 论坛 :http://www.firebbs.cn
  13. * 淘宝 :https://fire-stm32.taobao.com
  14. *
  15. ******************************************************************************
  16. */
  17. #include "stm32f10x.h"
  18. #include "./usart/bsp_usart.h"
  19. #include "ff.h"
  20. #include "string.h"
  21. /**
  22. ******************************************************************************
  23. * 定义变量
  24. ******************************************************************************
  25. */
  26. FATFS fs; /* FatFs文件系统对象 */
  27. FIL fnew; /* 文件对象 */
  28. FRESULT res_flash; /* 文件操作结果 */
  29. UINT fnum; /* 文件成功读写数量 */
  30. char fpath[100]; /* 保存当前扫描路径 */
  31. char readbuffer[512];
  32. /**
  33. ******************************************************************************
  34. * 任务函数
  35. ******************************************************************************
  36. */
  37. /* FatFs多项功能测试 */
  38. static FRESULT miscellaneous(void)
  39. {
  40. DIR dir;
  41. FATFS *pfs;
  42. DWORD fre_clust, fre_sect, tot_sect;
  43. printf("\n*************** 设备信息获取 ***************\r\n");
  44. /* 获取设备信息和空簇大小 */
  45. res_flash = f_getfree("1:", &fre_clust, &pfs);
  46. /* 计算得到总的扇区个数和空扇区个数 */
  47. tot_sect = (pfs->n_fatent - 2) * pfs->csize;
  48. fre_sect = fre_clust * pfs->csize;
  49. /* 打印信息(4096 字节/扇区) */
  50. printf("》设备总空间:%10lu KB。\n》可用空间: %10lu KB。\n", tot_sect *4, fre_sect *4);
  51. printf("\n******** 文件定位和格式化写入功能测试 ********\r\n");
  52. res_flash = f_open(&fnew, "1:FatFs读写测试文件.txt",
  53. FA_OPEN_ALWAYS|FA_WRITE|FA_READ );
  54. if ( res_flash == FR_OK )
  55. {
  56. /* 文件定位 */
  57. res_flash = f_lseek(&fnew,f_size(&fnew));
  58. if (res_flash == FR_OK)
  59. {
  60. /* 格式化写入,参数格式类似printf函数 */
  61. f_printf(&fnew,"\n在原来文件新添加一行内容\n");
  62. f_printf(&fnew,"》设备总空间:%10lu KB。\n》可用空间: %10lu KB。\n", tot_sect *4, fre_sect *4);
  63. /* 文件定位到文件起始位置 */
  64. res_flash = f_lseek(&fnew,0);
  65. /* 读取文件所有内容到缓存区 */
  66. res_flash = f_read(&fnew,readbuffer,f_size(&fnew),&fnum);
  67. if(res_flash == FR_OK)
  68. {
  69. printf("》文件内容:\n%s\n",readbuffer);
  70. }
  71. }
  72. f_close(&fnew);
  73. printf("\n********** 目录创建和重命名功能测试 **********\r\n");
  74. /* 尝试打开目录 */
  75. res_flash=f_opendir(&dir,"1:TestDir");
  76. if(res_flash!=FR_OK)
  77. {
  78. /* 打开目录失败,就创建目录 */
  79. res_flash=f_mkdir("1:TestDir");
  80. }
  81. else
  82. {
  83. /* 如果目录已经存在,关闭它 */
  84. res_flash=f_closedir(&dir);
  85. /* 删除文件 */
  86. f_unlink("1:TestDir/testdir.txt");
  87. }
  88. if(res_flash==FR_OK)
  89. {
  90. /* 重命名并移动文件 */
  91. res_flash=f_rename("1:FatFs读写测试文件.txt","1:TestDir/testdir.txt");
  92. }
  93. }
  94. else
  95. {
  96. printf("!! 打开文件失败:%d\n",res_flash);
  97. printf("!! 或许需要再次运行“FatFs移植与读写测试”工程\n");
  98. }
  99. return res_flash;
  100. }
  101. FILINFO fno;
  102. /**
  103. * 文件信息获取
  104. */
  105. static FRESULT file_check(void)
  106. {
  107. /* 获取文件信息 */
  108. res_flash=f_stat("1:TestDir/testdir.txt",&fno);
  109. if(res_flash==FR_OK)
  110. {
  111. printf("“testdir.txt”文件信息:\n");
  112. printf("》文件大小: %ld(字节)\n", fno.fsize);
  113. printf("》时间戳: %u/%02u/%02u, %02u:%02u\n",
  114. (fno.fdate >> 9) + 1980, fno.fdate >> 5 & 15, fno.fdate & 31,fno.ftime >> 11, fno.ftime >> 5 & 63);
  115. printf("》属性: %c%c%c%c%c\n\n",
  116. (fno.fattrib & AM_DIR) ? 'D' : '-', // 是一个目录
  117. (fno.fattrib & AM_RDO) ? 'R' : '-', // 只读文件
  118. (fno.fattrib & AM_HID) ? 'H' : '-', // 隐藏文件
  119. (fno.fattrib & AM_SYS) ? 'S' : '-', // 系统文件
  120. (fno.fattrib & AM_ARC) ? 'A' : '-'); // 档案文件
  121. }
  122. return res_flash;
  123. }
  124. /**
  125. * @brief scan_files 递归扫描FatFs内的文件
  126. * @param path:初始扫描路径
  127. * @retval result:文件系统的返回值
  128. */
  129. static FRESULT scan_files (char* path)
  130. {
  131. FRESULT res; //部分在递归过程被修改的变量,不用全局变量
  132. FILINFO fno;
  133. DIR dir;
  134. int i;
  135. char *fn; // 文件名
  136. #if _USE_LFN
  137. /* 长文件名支持 */
  138. /* 简体中文需要2个字节保存一个“字”*/
  139. static char lfn[_MAX_LFN*2 + 1];
  140. fno.lfname = lfn;
  141. fno.lfsize = sizeof(lfn);
  142. #endif
  143. //打开目录
  144. res = f_opendir(&dir, path);
  145. if (res == FR_OK)
  146. {
  147. i = strlen(path);
  148. for (;;)
  149. {
  150. //读取目录下的内容,再读会自动读下一个文件
  151. res = f_readdir(&dir, &fno);
  152. //为空时表示所有项目读取完毕,跳出
  153. if (res != FR_OK || fno.fname[0] == 0) break;
  154. #if _USE_LFN
  155. fn = *fno.lfname ? fno.lfname : fno.fname;
  156. #else
  157. fn = fno.fname;
  158. #endif
  159. //点表示当前目录,跳过
  160. if (*fn == '.') continue;
  161. //目录,递归读取
  162. if (fno.fattrib & AM_DIR)
  163. {
  164. //合成完整目录名
  165. sprintf(&path[i], "/%s", fn);
  166. //递归遍历
  167. res = scan_files(path);
  168. path[i] = 0;
  169. //打开失败,跳出循环
  170. if (res != FR_OK)
  171. break;
  172. }
  173. else
  174. {
  175. printf("%s/%s\r\n", path, fn); //输出文件名
  176. /* 可以在这里提取特定格式的文件路径 */
  177. }//else
  178. } //for
  179. }
  180. return res;
  181. }
  182. /**
  183. * @brief 主函数
  184. * @param 无
  185. * @retval 无
  186. */
  187. int main(void)
  188. {
  189. /* 初始化调试串口,一般为串口1 */
  190. USART_Config();
  191. printf("******** 这是一个SPI FLASH 文件系统实验 *******\r\n");
  192. //在外部SPI Flash挂载文件系统,文件系统挂载时会对SPI设备初始化
  193. res_flash = f_mount(&fs,"1:",1);
  194. if(res_flash!=FR_OK)
  195. {
  196. printf("!!外部Flash挂载文件系统失败。(%d)\r\n",res_flash);
  197. printf("!!可能原因:SPI Flash初始化不成功。\r\n");
  198. while(1);
  199. }
  200. else
  201. {
  202. printf("》文件系统挂载成功,可以进行测试\r\n");
  203. }
  204. /* FatFs多项功能测试 */
  205. res_flash = miscellaneous();
  206. printf("\n*************** 文件信息获取测试 **************\r\n");
  207. res_flash = file_check();
  208. printf("***************** 文件扫描测试 ****************\r\n");
  209. strcpy(fpath,"1:");
  210. scan_files(fpath);
  211. /* 不再使用文件系统,取消挂载文件系统 */
  212. f_mount(NULL,"1:",1);
  213. /* 操作完成,停机 */
  214. while(1)
  215. {
  216. }
  217. }
  218. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

2-FatFs文件系统常用函数测试.zip