SD卡文件系统移植

前言

我们使用一个现成的SDIO-读写测试文件

(1)拷贝FatFs文件系统源文件到user目录下,并重命名为fatfs

(2)创建工作目录FATFS,并添加文件系统底层文件和中间层文件

添加头文件路径

底层驱动移植

1、修改头文件

修改为

其中ATA作为SD卡

2、disk_status函数

原:

修改后

默认返回初始化正确,因为如果真的初始化出错后面有其它操作可以继续判断

3、disk_initialize函数

原:

修改后

4、disk_read函数

修改前

修改后:

首先外部定义一个SD卡信息结构体变量

添加块读取函数

SD_ReadMultiBlocks(buff,sector * SDCardInfo.CardBlockSize,SDCardInfo.CardBlockSize,count);

其中第一个参数为输出给上层文件系统的数组,第二个变量为读取块的起始地址(块号*每个块的大小),第三个参数为每个块的大小,第四个参数为读取块的个数。

还要注意地址对齐的问题,如果上层传入的buff的地址不是四个字节对齐,由于我们的SD卡是采用DMA来进行数据搬运,按照32位搬运,所以地址需要四个字节对齐,因此如果不是,可能会导致读取出错。待会进行处理。

读取之后还需要进行等待读取完成

5、disk_write函数

修改前

修改后

与disk_read类似

(注意同样待会儿需要进行地址对齐问题的改进)

6、disk_ioctl函数

修改前:

 

修改后

7、最后手动添加上get_fattime函数

到此就完成最基本的文件系统接口操作了。

8、修改相关宏_CODE_PAGE为437,就可以使用英文名,并且不需要添加编码页

由于暂时只添加了一个SD存储介质,因此_VOLUMES设置为1

如果还添加了FLASH,_MAX_SS必须设置为4096,否则无法使用FLASH

此外_USE_MKFS必须设置为1,才可以格式化文件系统

还有_USE_STRFUNC要设置为1,才可以使用f_gets、fputs相关函数

9、main函数

我们将之前移植的FLASH文件系统的main文件拿过来,并进行简单修改

#include "stm32f10x.h"
#include "./sdio/bsp_sdio_sdcard.h"
#include "./usart/bsp_usart.h"    
#include "./led/bsp_led.h"
#include "ff.h"

/**
  ******************************************************************************
  *                              定义变量
  ******************************************************************************
  */
FATFS fs;                                                    /* FatFs文件系统对象 */
FIL fnew;                                                    /* 文件对象 */
FRESULT res_sd;                /* 文件操作结果 */
UINT fnum;                                  /* 文件成功读写数量 */
BYTE ReadBuffer[1024]={0};        /* 读缓冲区 */
BYTE WriteBuffer[] =              /* 写缓冲区*/
"欢迎使用野火STM32 开发板 今天是个好日子,新建文件系统测试文件\r\n";  
extern  SD_CardInfo SDCardInfo;
/**
  * @brief  主函数
  * @param  无
  * @retval 无
  */
int main(void)
{
    /* 初始化LED */
    LED_GPIO_Config();    
    LED_BLUE;
    
    /* 初始化调试串口,一般为串口1 */
    USART_Config();    
  printf("\r\n****** 这是一个SD卡 文件系统实验 ******\r\n");
  
    //在外部SPI Flash挂载文件系统,文件系统挂载时会对SPI设备初始化
    res_sd = f_mount(&fs,"0:",1);
    
//    printf("容量=%lld",SDCardInfo.CardCapacity/1024/1024);
/*----------------------- 格式化测试 ---------------------------*/  
    /* 如果没有文件系统就格式化创建创建文件系统 */
    if(res_sd == FR_NO_FILESYSTEM)
    {
        printf("》SD卡还没有文件系统,即将进行格式化...\r\n");
    /* 格式化 */
        res_sd=f_mkfs("0:",0,0);                            
        
        if(res_sd == FR_OK)
        {
            printf("》SD卡已成功格式化文件系统。\r\n");
      /* 格式化后,先取消挂载 */
            res_sd = f_mount(NULL,"0:",1);            
      /* 重新挂载    */            
            res_sd = f_mount(&fs,"0:",1);
        }
        else
        {
            LED_RED;
            printf("《《格式化失败。》》\r\n");
            while(1);
        }
    }
  else if(res_sd!=FR_OK)
  {
    printf("!!SD卡挂载文件系统失败。(%d)\r\n",res_sd);
    printf("!!可能原因:SD卡初始化不成功。\r\n");
        while(1);
  }
  else
  {
    printf("》文件系统挂载成功,可以进行读写测试\r\n");
  }
  
/*----------------------- 文件系统测试:写测试 -----------------------------*/
    /* 打开文件,如果文件不存在则创建它 */
    printf("\r\n****** 即将进行文件写入测试... ******\r\n");    
    res_sd = f_open(&fnew, "0:FatFs读写测试文件.txt",FA_CREATE_ALWAYS | FA_WRITE );
    if ( res_sd == FR_OK )
    {
        printf("》打开/创建FatFs读写测试文件.txt文件成功,向文件写入数据。\r\n");
    /* 将指定存储区内容写入到文件内 */
        res_sd=f_write(&fnew,WriteBuffer,sizeof(WriteBuffer),&fnum);
    if(res_sd==FR_OK)
    {
      printf("》文件写入成功,写入字节数据:%d\n",fnum);
      printf("》向文件写入的数据为:\r\n%s\r\n",WriteBuffer);
    }
    else
    {
      printf("!!文件写入失败:(%d)\n",res_sd);
    }    
        /* 不再读写,关闭文件 */
    f_close(&fnew);
    }
    else
    {    
        LED_RED;
        printf("!!打开/创建文件失败。\r\n");
    }
    
/*------------------- 文件系统测试:读测试 ------------------------------------*/
    printf("****** 即将进行文件读取测试... ******\r\n");
    res_sd = f_open(&fnew, "0:FatFs读写测试文件.txt", FA_OPEN_EXISTING | FA_READ);      
    if(res_sd == FR_OK)
    {
        LED_GREEN;
        printf("》打开文件成功。\r\n");
        res_sd = f_read(&fnew, ReadBuffer, sizeof(ReadBuffer), &fnum); 
    if(res_sd==FR_OK)
    {
      printf("》文件读取成功,读到字节数据:%d\r\n",fnum);
      printf("》读取得的文件数据为:\r\n%s \r\n", ReadBuffer);    
    }
    else
    {
      printf("!!文件读取失败:(%d)\n",res_sd);
    }        
    }
    else
    {
        LED_RED;
        printf("!!打开文件失败。\r\n");
    }
    /* 不再读写,关闭文件 */
    f_close(&fnew);    
  
    /* 不再使用文件系统,取消挂载文件系统 */
    f_mount(NULL,"0:",1);
  
  /* 操作完成,停机 */
    while(1)
    {
    }
}

10、首先将编码改为936,支持中文

然后设置支持长文件名,并将文件名存储在全局区

最后添加中文编码页

11、运行效果

12、地址对齐改进

(1)首先定义一个宏,表示SD卡块的大小

(2)对于disk_read函数修改如下:

buff&3的效果相对于buff%4判断地址能否被4整除,(因为4的二进制表示为100,所以buff&(011B),判断低两位是否有1)如果不能被4整除就执行if判断里面的内容。

首先定义一个数组scratch(unsigned int类型),将我们的数据缓冲起来,这样就不会引起DMA传输的错误,然后我们自己调用自己(用disk_read读取一个扇区),最后再拷贝给buff,传输给文件系统的上层,从而解决了地址不对齐的问题。

对于disk_write函数,方法和disk_read一样,只是传输数据方向是反的

到此SD卡FATFS文件系统的全部移植过程结束,而应用层与之前的FLASH都是一样的,不需要进行修改。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

竹烟淮雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值