• [置顶] 基于stm32f103zet6的FAT16文件系统学习2(初步移植ff9a)


    直接上移植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就是这样


    二、整体框架的修改,对于文件系统,我们需要修改的文件真的很少,因为很多东西,都帮我们想好了的,这里我就直接把代码贴出来,一看就能明白,哪些地方坐了修改的。

    主要的就是修改diskio.c里面的文件

    /*************************************************************************************
    *   函数库说明: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;
    }
    


    其中

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

    这个3个函数是在SD驱动文件里面的。

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

    int get_fattime()
    {
    	return 0;
    }

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

    三、首先贴上主函数,看是如何实现对我们文件的访问的

    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);
    	}


    具体函数暂时不进行分析,等待分析执行流程的时候一并解决,现在关键是看现象,才有动力!如果这时候进行编译下载的话,会发现打印的信息是乱码,为什么呢?因为在

    ffconf.h文件里面默认的是支持日文的,所以对于文件名的支持类型,我们得修改呀!

    修改的地方不多,如下两处:

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


    这样编译之后就没有问题了。

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












  • 相关阅读:
    BZOJ1588_营业额统计_KEY
    关于欧几里得算法的认识
    javacv实战篇
    图像处理里面的的尺度什么?
    改成 否“依然报LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏”问题的解决
    javacv
    以前写过的一些oracle语句
    warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
    在vs环境中跑动sift特征提取(原理部分)
    《sift算法详解》阅读笔记
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3002676.html
Copyright © 2020-2023  润新知