打印
[应用相关]

基于stm32f103zet6的FAT16文件系统学习(初步移植ff9a)

[复制链接]
1185|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Vitality1|  楼主 | 2015-2-28 15:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
直接上移植ff9a文件系统的移植步骤了,有些地方不了解,比如ff.c文件里面的一些函数,看得比较糊涂,但是那不影响我们的移植,先让文件系统跑起来,然后继续拧分析比较好。OK,不说废话了。
一、官网下载ff9a源代码,解压出来有doc和src两个文件夹。在我们的SD实验里面的project下面建立一个名为FAT的文件夹,然后将src里面的diskio.c、diskio.h、ff.c、ff.h、integer.h、ffcinf.h一共6个文件添加进去,最后看到我的Manage compnents就是这样

沙发
Vitality1|  楼主 | 2015-2-28 15:20 | 只看该作者
二、整体框架的修改,对于文件系统,我们需要修改的文件真的很少,因为很多东西,都帮我们想好了的,这里我就直接把代码贴出来,一看就能明白,哪些地方坐了修改的。
主要的就是修改diskio.c里面的文件

[csharp] view plaincopyprint?


  • /*************************************************************************************
  • *   函数库说明:Disk驱动函数                                 
  • *   作者:      King_BingGe                     
  • *   创建日期:  2013年04月4号                           
  • *       说明:移植FF9A   
  • **************************************************************************************/  
  • #include "diskio.h"      
  • #include "SD_Card.h"         
  • /**************************************************************************************
  • * 名    称: disk_initialize
  • * 功    能: Inidialize a Drive  
  • * 参    数: drv:表示需要初始化的磁盘对象
  • * 调用方式:disk_initialize(0);
  • * 返 回 值:    状态标识0:表示成功
  • **************************************************************************************/  
  • DSTATUS disk_initialize (BYTE drv)  
  • {  
  •     switch (drv) {  
  •     case 0 :  
  •         if(!SD_Initialize())  
  •             return RES_OK;  
  •         else return RES_ERROR;  
  •     case 1 :  
  •         return RES_ERROR;  
  •     case 2 :  
  •         return RES_ERROR;  
  •     default:  
  •         return RES_ERROR;  
  •     }  
  • }  
  • /**************************************************************************************
  • * 名    称: disk_status
  • * 功    能: Get Disk RES_ERRORus   
  • * 参    数: drv:表示需要获取状态的磁盘对象
  • * 调用方式:disk_status(0);
  • * 返 回 值:    状态标识0:表示成功
  • **************************************************************************************/  
  •   
  • DSTATUS disk_status (BYTE drv)  
  • {  
  •     switch (drv) {  
  •     case 0 :  
  •   
  •         return RES_OK;  
  •   
  •     case 1 :  
  •         return RES_ERROR;  
  •     case 2 :  
  •         return RES_ERROR;  
  •     default:  
  •         return RES_ERROR;  
  •     }  
  • }  
  •   
  • /**************************************************************************************
  • * 名    称: disk_read
  • * 功    能: Read Sector(s)   
  • * 参    数:drv :表示需要读扇区的磁盘对象
  • *    BYTE *buff: Data buffer to store read data  
  • *  DWORD sector: Sector address (LBA)  
  • *    BYTE count: Number of sectors to read (1..128)  
  • * 调用方式:disk_read(0,buff,0,1);
  • * 返 回 值:    状态标识0:表示成功
  • ***************************************************************************************/  
  •   
  • DSTATUS disk_read (BYTE drv,BYTE *buff, DWORD sector,   BYTE count)  
  • {  
  •     switch (drv) {  
  •     case 0 :  
  •         if(!SD_ReadDisk(buff,sector,count))//读块  
  •             return RES_OK;  
  •         else return RES_ERROR;  
  •     case 1 :  
  •         return RES_ERROR;  
  •     case 2 :  
  •         return RES_ERROR;  
  •     default:  
  •         return RES_ERROR;  
  •     }  
  • }  
  •   
  • /**************************************************************************************
  • * 名    称: disk_write
  • * 功    能: Write Sector(s)   
  • * 参    数:drv :表示需要写扇区的磁盘对象
  • *    BYTE *buff: Data buffer to store write data  
  • *  DWORD sector: Sector address (LBA)  
  • *    BYTE count: Number of sectors to write(1..128)  
  • * 调用方式    :disk_write(0,buff,0,1);
  • * 调用方式:disk_initialize(0,buff,0,1);
  • * 返 回 值:    状态标识0:表示成功
  • ***************************************************************************************/  
  • #if _USE_WRITE  
  • DSTATUS disk_write (BYTE drv,   const BYTE *buff,   DWORD sector,   BYTE count)  
  • {  
  •     switch (drv) {  
  •     case 0 :  
  •         if(!SD_WriteDisk(buff,sector,count))//读块  
  •             return RES_OK;  
  •         else return RES_ERROR;  
  •     case 1 :  
  •         return RES_ERROR;  
  •     case 2 :  
  •         return RES_ERROR;  
  •     default:  
  •         return RES_ERROR;  
  •     }  
  • }  
  • #endif  
  •   
  • /**************************************************************************************
  • * 名    称: disk_write
  • * 功    能: 该函数在磁盘格式化、获取文件系统信息等操作时会被调用  
  • * 参    数: drv:表示需要读扇区的磁盘对象
  • *   BYTE drv: Physical drive nmuber (0..)  
  • *     BYTE *buff: Data buffer to store read data  
  • * 调用方式:disk_ioctl(0,1,buff);
  • * 返 回 值:    状态标识0:表示成功
  • ***************************************************************************************/  
  • #if _USE_IOCTL  
  • DSTATUS disk_ioctl (BYTE drv,   BYTE ctrl,void *buff)  
  • {  
  •     switch (drv) {  
  •     case 0  :  
  •         return RES_ERROR;  
  •     case 1 :  
  •         return RES_ERROR;  
  •     case 2 :  
  •         return RES_ERROR;  
  •     case 3 :  
  •         return RES_ERROR;         
  •     case 4 :  
  •         return RES_ERROR;  
  •     default:  
  •         return RES_ERROR;  
  •     }  
  • }  
  • #endif  
  •   
  • int get_fattime()  
  • {  
  •     return 0;  
  • }  


使用特权

评论回复
板凳
Vitality1|  楼主 | 2015-2-28 15:21 | 只看该作者
其中

[csharp] view plaincopyprint?


  • SD_Initialize()  
  • SD_ReadDisk(buff,sector,count)  
  • SD_WriteDisk(buff,sector,count)  


这个3个函数是在SD驱动文件里面的。
这样处理之后,如果直接编译的话,会出现get_fattime这个符号报错,是因为我们在ff.c里面使用到了这个函数,但是没有定义,所以最后的这个函数添加上去,但是没有实现具体功能的。

[csharp] view plaincopyprint?


  • int get_fattime()  
  • {  
  •     return 0;  
  • }  

至此就完成了底层函数的移植。那么接下来如何测试,我们的文件系统呢?

使用特权

评论回复
地板
Vitality1|  楼主 | 2015-2-28 15:21 | 只看该作者
三、首先贴上主函数,看是如何实现对我们文件的访问的

[csharp] view plaincopyprint?


  • int main(void)  
  • {  
  •       
  •     //初始化系统定时器  
  •     SysTick_Init();  
  •     USART1_Config();  
  •     SPIx_Init();                    //初始化SPI  
  •     printf("\r\n ("__DATE__ " - " __TIME__ ") \r\n");  
  •   
  •     res = f_mount(0,&fs);       //挂接根文件系统  
  •       
  •     if(res != FR_OK){  
  •         printf("mount filesystem 0 failed : %d\n\r",res);  
  •     }  
  •     //写文件测试  
  •     printf("write file test......\n\r");  
  •     res = f_open(&fdst, "0:/test.txt", FA_CREATE_ALWAYS | FA_WRITE);  
  •     if(res != FR_OK){  
  •         printf("open file error : %d\n\r",res);  
  •     }else{  
  •         res = f_write(&fdst, Test_Buffer, sizeof(Test_Buffer), &bw);               /* Write it to the dst file */  
  •         if(res == FR_OK){  
  •             printf("write data ok! %d\n\r",bw);  
  •         }else{  
  •             printf("write data error : %d\n\r",res);  
  •         }  
  •         /*close file */  
  •         f_close(&fdst);  
  •     }  
  •     //读文件测试  
  •     printf("read file test......\n\r");  
  •     res = f_open(&fsrc, "0:/test.txt", FA_OPEN_EXISTING | FA_READ);  
  •     if(res != FR_OK){  
  •         printf("open file error : %d\n\r",res);  
  •     }else{  
  •         res = f_read(&fsrc, buffer, sizeof(Test_Buffer), &br);     /* Read a chunk of src file */  
  •         if(res==FR_OK){  
  •             printf("read data num : %d\n\r",br);  
  •             printf("%s\n\r",buffer);  
  •         }else{  
  •             printf("read file error : %d\n\r",res);  
  •         }  
  •         /*close file */  
  •         f_close(&fsrc);  
  •     }  


使用特权

评论回复
5
Vitality1|  楼主 | 2015-2-28 15:22 | 只看该作者
具体函数暂时不进行分析,等待分析执行流程的时候一并解决,现在关键是看现象,才有动力!如果这时候进行编译下载的话,会发现打印的信息是乱码,为什么呢?因为在
ffconf.h文件里面默认的是支持日文的,所以对于文件名的支持类型,我们得修改呀!
修改的地方不多,如下两处:

[csharp] view plaincopyprint?


  • // #define _CODE_PAGE   932  
  • #define _CODE_PAGE  936         //支持中文长文件名  
  • // #define _CODE_PAGE   437         //只支持英文长文件名  
  • // #define _USE_LFN 0         
  • #define _USE_LFN    1           //支持中文长文件名  


这样编译之后就没有问题了。
暂时就到这里吧,算是初步成功了,一些类似于uboot或者shell更强大的功能,暂时不搞,分析完文件系统再说!

使用特权

评论回复
6
小浣熊| | 2015-2-28 15:42 | 只看该作者
整体框架看上去不错哦。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

81

主题

421

帖子

9

粉丝