windows平台模拟测试FATFS

时间:2022-01-26 04:01:15

由于项目中需要从SD卡中读取文件,为了方便操作,需要移植文件系统,源码比较容易获取的两个文件系统为FATFS和znFAT,看了一下FatFS文旦比较丰富,同时接口清晰,所以优先选择FatFS进行测试,这样在了解FatFS移植的关键点后再移植到STM32平台会比较有把握,网上也有windows平台移植文件系统的Demo,但是大家要么直接读写本机的磁盘,要么读写U盘,本人不建议这么弄,要是程序有问题把磁盘搞坏了,这个就比较郁闷了。

工欲善其事必先利其器,首先准备我们需要的工具,这里我准备了两个工具,一个创建FAT12格式镜像的工具,此工具是我从网上COPY一个朋友代码制作的,还有一个是从ADT工具包中拷贝的模拟SD卡创建工具mksdcard,此工具创建的镜像为FAT32格式,这两个工具我会共享,共享地址见文章底部,另外我们还需要一个镜像查看工具,本人推荐UltraISO。

第一步创建测试镜像,使用mksdcard创建一个128M的虚拟SD卡文件

windows平台模拟测试FATFS

使用UltraISO打开查看如下,此时SD空白

windows平台模拟测试FATFS

第二步移植FATFS,使用VS2010创建Console项目,不要使用Unicode,否则会出现路径问题,拷贝FatFS到项目目录,添加相关文件,如果你不使用长文件名option目下的文件不用添加,FatFS本人使用的是V12C,项目的组织结构本人就不描述了,每个人的习惯不同,组织习惯也不同,项目源码最终会共享,共享地址在文章的末尾,现在说移植重点,对于ffconf.h的配置,每一项的说明都很清楚,因为测试,本人一行没改,修改diskio.c,重新实现磁盘读写函数,其实就是读写镜像文件,本人使用的是C语言的方式,

[cpp] view plain copy
  1. #ifdef _MSC_VER  
  2. #include <Windows.h>  
  3. #include "adaptor.h"  
  4. #include <stdio.h>  
  5.   
  6. #define     SECTOR_SIZE 512  
  7.   
  8. #endif  
  9.   
  10. FILE *fpImg = 0;  
disk_status函数实现

[cpp] view plain copy
  1. if (pdrv == 0 && fpImg)  
  2.     {  
  3.         return RES_OK;  
  4.     }  
  5.   
  6.     return STA_NOINIT;  
disk_initialize函数实现

[cpp] view plain copy
  1. if (pdrv == 0)  
  2.     {  
  3.         if (!fpImg)  
  4.         {  
  5.             char strImgName[0xff];  
  6.             memset(strImgName, 0, 0xff);  
  7.             GetSimFilePath(strImgName, 0xff);  
  8.             fpImg = fopen(strImgName, "rb+"); //open file for read/write  
  9.             if (fpImg == NULL)  
  10.                 return STA_NOINIT;  
  11.   
  12.   
  13.         }  
  14.         return RES_OK;  
  15.     }  
disk_read函数实现
[cpp] view plain copy
  1. if (pdrv == 0)  
  2.     {  
  3.         BYTE *pOut = buff;  
  4.         int i = 0;  
  5.         if (!fpImg)  
  6.             return RES_ERROR;  
  7.   
  8.         fseek(fpImg, SECTOR_SIZE*sector, SEEK_SET);  
  9.   
  10.         for (i = 0; i < count; i++)  
  11.         {  
  12.             fread(pOut, SECTOR_SIZE, 1, fpImg);  
  13.   
  14.             pOut = pOut + SECTOR_SIZE;  
  15.         }  
  16.   
  17.         return RES_OK;  
  18.     }  

disk_write函数实现

[cpp] view plain copy
  1. if (pdrv == 0)  
  2.     {  
  3.         BYTE *pOut = buff;  
  4.         int i = 0;  
  5.         if (!fpImg)  
  6.             return RES_ERROR;  
  7.   
  8.         fseek(fpImg, SECTOR_SIZE*sector, SEEK_SET);  
  9.   
  10.         for (i = 0; i < count; i++)  
  11.         {  
  12.             //fread(pOut, SECTOR_SIZE, 1, fpImg);  
  13.   
  14.             fwrite(pOut, SECTOR_SIZE, 1, fpImg);  
  15.   
  16.             pOut = pOut + SECTOR_SIZE;  
  17.         }  
  18.         result = RES_OK;  
  19.   
  20.         return result;  
  21.     }  
[cpp] view plain copy
  1. DWORD get_fattime(void)  
  2. {  
  3. #ifdef _MSC_VER  
  4.     return GetTickCount();  
  5. #endif  
  6.     return 0;  
  7. }  



disk_ioctl函数实现

[cpp] view plain copy
  1. switch (cmd)  
  2. {  
  3. case CTRL_SYNC:  
  4. {  
  5.     break;  
  6. }  
  7. case GET_SECTOR_COUNT:  
  8. {  
  9.     DWORD fz = 0;  
  10.     if (!fpImg)  
  11.         return;  
  12.     fseek(fpImg,0,SEEK_END);  
  13.     fz = ftell(fpImg);  
  14.   
  15.     *(DWORD*)buff = (fz / SECTOR_SIZE);  
  16.   
  17.     break;  
  18. }  
  19. case GET_SECTOR_SIZE:  
  20. {  
  21.     break;  
  22. }  
  23. case GET_BLOCK_SIZE:  
  24. {  
  25.     break;  
  26. }  
  27. case CTRL_TRIM:  
  28. {  
  29.     break;  
  30. }  
  31. default:  
  32.     break;  
  33. }  
第三部,测试

[cpp] view plain copy
  1. FATFS fs;  
  2. FRESULT res;  
  3. FIL fil;  
  4. UINT read = 0;  
  5.   
  6. memset(fs.win, 0, 512);  
  7.   
  8. res = f_mount(&fs, _T("0"), 1);  
  9.   
  10. if (res != FR_OK) return 1;  
  11.   
  12. /* 
  13. res = f_open(&fil, _T("config.h"), FA_OPEN_ALWAYS | FA_READ); 
  14.  
  15. BYTE msg[128]; 
  16. memset(msg, 0, 128); 
  17.  
  18. res = f_read(&fil, msg, 128,&read); 
  19. */  
  20.   
  21. res = f_open(&fil, _T("config.h"), FA_CREATE_NEW | FA_WRITE);  
  22. char* str = "Hello From FATFS";  
  23.   
  24. res = f_write(&fil, str, strlen(str), &read);  
  25.   
  26.   
  27. f_close(&fil);  

使用UltraISO打开查看如下

 windows平台模拟测试FATFS

将文件CONFIG.H拖出来,打开如下

windows平台模拟测试FATFS

同样,也可以进行读取测试,这里就不在赘述,还可以使用FAT12Tool创建软盘镜像进行测试,

写这篇文章一是为了记录,二是为了给需要的朋友提供一个切入点,在完成基本的读写测试后,有兴趣的朋友可以进行格式化,创建文件夹等测试,也可以基于FATFS做一个虚拟SD卡管理工具(如果哪位朋友做了,给我发一个),更高级的可以阅读FAT系统规范,写属于自己的FAT文件系统,用以上介绍的知识进行测试。

镜像创建工具,内附说明

测试工程源码