关于GD32F303 fatfs文件系统挂载

[复制链接]
2810|27
手机看帖
扫描二维码
随时随地手机跟帖
zeshoufx|  楼主 | 2021-5-10 20:24 | 显示全部楼层 |阅读模式
一、最近看到论坛里有人问利用gd的官方SD卡驱动移植fatfs有没有成功的,于是在想这有什么,于是动手试了一下,
各种报错,挂载不上,格式化不了,各个网站查资料,也没有解决的办法,fatfs每个版本挨个都试一下,从R14降版本,最后R09版本移植成功了。


使用特权

评论回复
zeshoufx|  楼主 | 2021-5-10 20:27 | 显示全部楼层
二、FatFs 是一个通用的文件系统(FAT/exFAT)模块,用于在小型嵌入式系统中实现FAT文件系统。 FatFs 组件的编写遵循ANSI C(C89),完全分离于磁盘 I/O 层,因此不依赖于硬件平台。它可以嵌入到资源有限的微控制器中,如 8051, PIC, AVR, ARM, Z80, RX等等,不需要做任何修改,

多次尝试后,最终移植成功
815046099264a0404f.png

8196609926892c2f6.png

24657609926a43f892.png

99699609926b8c2217.png

使用特权

评论回复
zeshoufx|  楼主 | 2021-5-10 20:31 | 显示全部楼层
zeshoufx 发表于 2021-5-10 20:27
二、FatFs 是一个通用的文件系统(FAT/exFAT)模块,用于在小型嵌入式系统中实现FAT文件系统。 FatFs 组件的 ...

三、SD卡驱动
SD卡驱动直接采用官方固件库,sdio的例子,,什么都不用改,需要注意的是
工程所采用的固件库版本和sdio的例程版本要对应,之前用gd32f450的时候就是工程
采用最新的固件库,SD卡驱动采用开发板的例程,,老是初始化不成功;

使用特权

评论回复
zeshoufx|  楼主 | 2021-5-10 20:36 | 显示全部楼层
zeshoufx 发表于 2021-5-10 20:31
三、SD卡驱动
SD卡驱动直接采用官方固件库,sdio的例子,,什么都不用改,需要注意的是
工程所采用的固件 ...

四、fatfs函数注册
一开始移植的时候,以为很简单,,毕竟其他平台都成功了,,结果用gd的官方驱动一直碰壁,
参考原子、野火、普中等都失败了,他们的注册函数都考虑比较周全,下面是我的注册函数
#include "diskio.h"                /* FatFs lower layer API */
#include "sdcard.h"


/* Definitions of physical drive number for each media */
#define ATA                0
#define MMC                1
#define USB                2

#define SECTOR_SIZE 512U

/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */

DSTATUS disk_initialize (
        BYTE drv                                /* Physical drive nmuber (0..) */
)
{
        return 0;
}



/*-----------------------------------------------------------------------*/
/* Return Disk Status                                                    */

DSTATUS disk_status (
        BYTE drv                /* Physical drive nmuber (0..) */
)
{       
        return 0;
}



/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */

DRESULT disk_read (
        BYTE drv,                /* Physical drive nmuber (0..) */
        BYTE *buff,                /* Data buffer to store read data */
        DWORD sector,        /* Sector address (LBA) */
        BYTE count                /* Number of sectors to read (1..255) */
)
{         
        if(count==1)
    {
          sd_block_read((u32 *)(&buff[0]),sector << 9 ,SECTOR_SIZE);
         
        }
        return RES_OK;
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */

#if _READONLY == 0
DRESULT disk_write (
        BYTE drv,                        /* Physical drive nmuber (0..) */
        const BYTE *buff,        /* Data to be written */
        DWORD sector,                /* Sector address (LBA) */
        BYTE count                        /* Number of sectors to write (1..255) */
)
{
        if(count==1)
    {     
          sd_block_write((u32 *)(&buff[0]),sector << 9 ,SECTOR_SIZE);
        }         
          return RES_OK;
}
#endif /* _READONLY */



/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */

DRESULT disk_ioctl (
        BYTE drv,                /* Physical drive nmuber (0..) */
        BYTE ctrl,                /* Control code */
        void *buff                /* Buffer to send/receive control data */
)
{
        return RES_OK;
}

DWORD get_fattime(void){
        return 0;
}



使用特权

评论回复
zeshoufx|  楼主 | 2021-5-10 20:37 | 显示全部楼层
zeshoufx 发表于 2021-5-10 20:36
四、fatfs函数注册
一开始移植的时候,以为很简单,,毕竟其他平台都成功了,,结果用gd的官方驱动一直碰 ...

五、主函数
#include "bitband.h"
#include "usart.h"
#include "systick.h"
#include "led.h"
#include "timer_base.h"
#include "timer_gen.h"
#include "timer_adv.h"
#include "at24c02.h"
#include "sdcard.h"
#include "ff.h"
#include "diskio.h"

FATFS fs;                                                                                                        /* FatFs文件系统对象 */
FIL fnew;                                                                                                        /* 文件对象 */
FRESULT res_sd;                /* 文件操作结果 */
UINT fnum;                                                      /* 文件成功读写数量 */
BYTE ReadBuffer[1024]={0};        /* 读缓冲区 */
BYTE WriteBuffer[] =              /* 写缓冲区*/
"Hello 21IC,Hello GD32f30vct6!\r\n";  


extern  sd_card_info_struct SDCardInfo;


int main(void)
{
//    sd_error_enum sd_error;
//    u16 i = 5;
   
    enhenced_run_enable();
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
    systick_set(120);
    at24c02_set();
    usart_set(9600);
    led_set();
    sd_io_init();
   
    disk_initialize(0);
    res_sd=f_mount(0, &fs);
   
    if(res_sd == FR_NO_FILESYSTEM)
        {
                printf("》SD卡还没有文件系统,即将进行格式化...\r\n");
    /* 格式化 */
                //res_sd=f_mkfs(0,0,0);                                                       
                printf("%d\r\n",res_sd);
                if(res_sd == FR_OK)
                {
                        printf("》SD卡已成功格式化文件系统。\r\n");
      /* 格式化后,先取消挂载 */
                        res_sd = f_mount(0,NULL);                       
      /* 重新挂载        */                       
                        res_sd = f_mount(0, &fs);
                }
                else
                {
                        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:GD32FatFs读写测试文件.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
        {       
                printf("!!打开/创建文件失败。\r\n");
        }
       
/*------------------- 文件系统测试:读测试 ------------------------------------*/
        printf("****** 即将进行文件读取测试... ******\r\n");
        res_sd = f_open(&fnew, "0:GD32FatFs读写测试文件.txt", FA_OPEN_EXISTING | FA_READ);          
        if(res_sd == FR_OK)
        {
                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
        {
                printf("!!打开文件失败。\r\n");
        }
        /* 不再读写,关闭文件 */
        f_close(&fnew);       
  
        /* 不再使用文件系统,取消挂载文件系统 */
        f_mount(0, &fs);
   
    while(1)
    {
        led_toggle(led_all);
        delay_xs(1);
    }
}


使用特权

评论回复
zeshoufx|  楼主 | 2021-5-10 20:42 | 显示全部楼层

六、之前看到群里有人抱怨gd官方的SD卡驱动标新立异,块读写的数组为32位,stm32的为8位,实际上这不影响移植成功与否
,早先的stm32官方的块读写也是32位的,老规矩,最后将工程上传,与大家分享。

使用特权

评论回复
zeshoufx|  楼主 | 2021-5-10 20:49 | 显示全部楼层
zeshoufx 发表于 2021-5-10 20:42
六、之前看到群里有人抱怨gd官方的SD卡驱动标新立异,块读写的数组为32位,stm32的为8位,实际上这不影响 ...

移植工程,适用于gd32f303vct6官方开发板,固件库版本为目前最新版,为2.1.1

sd_fatfs_GD32F303.zip

8.14 MB

程序源码

使用特权

评论回复
评论
悟于执迷 2023-12-22 18:39 回复TA
@ywd_Linux :我也是这个问题,大佬怎么解决的 
ywd_Linux 2021-5-21 16:00 回复TA
用楼主的工程移植到GD32F450上,基于官方的SDIO例程+开发板,轮询模式,没成功,卡在main()第一个f_open()函数里的 res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ)); //这句返回0x0D 就是错误码13 FR_NO_FILESYSTEM 请教一下楼主,这个您有遇到过没,有啥好办法解决没 
单片小菜| | 2021-5-10 21:10 | 显示全部楼层
这个例程确实不错的。

使用特权

评论回复
yangxiaor520| | 2021-5-11 07:14 | 显示全部楼层
难道还有版本匹配问题?

使用特权

评论回复
ywd_Linux| | 2021-5-21 16:05 | 显示全部楼层
zeshoufx 发表于 2021-5-10 20:31
三、SD卡驱动
SD卡驱动直接采用官方固件库,sdio的例子,,什么都不用改,需要注意的是
工程所采用的固件 ...

楼主好,我现在初始化可以读出一点信息,是用GD32F450的SDIO例程里  card_info_get();获取卡的信息并打印出来的,这样是不是能说明,我的SD卡初始化成功了?
## Card version 3.0x ##
## SDXC card ##
## Device容量 size is 62521344KB ##
## Block 块大小size is 512B ##
## Block 块个数count is 125042688 ##
## CardCommandClassesSD卡命令类 is: 5b5 ##

## Block operation 支持块操作supported ##

## Erase 支持擦除supported ##

## Lock unlock 支持取消写保护supported ##

## Application specific 支持应用supported ##

## Switch function 支持转换功能supported ##

使用特权

评论回复
zeshoufx|  楼主 | 2021-5-21 17:27 | 显示全部楼层
ywd_Linux 发表于 2021-5-21 16:05
楼主好,我现在初始化可以读出一点信息,是用GD32F450的SDIO例程里  card_info_get();获取卡的信息并打印 ...

对,块读写和多块读写测试了吗,最好测试一下

使用特权

评论回复
ywd_Linux| | 2021-5-22 10:14 | 显示全部楼层
zeshoufx 发表于 2021-5-21 17:27
对,块读写和多块读写测试了吗,最好测试一下

测试了,按照例程里的0~255十六进制数值读写都正常打印,这样就能说明我的F450固件库和SD卡的驱动是匹配的,但我还是卡在了f_open()函数那里了,7楼那里我评论的内容,想不到原因,难道是我的SD卡64G容量太大了不支持吗?

使用特权

评论回复
zeshoufx|  楼主 | 2021-5-22 19:17 | 显示全部楼层
ywd_Linux 发表于 2021-5-22 10:14
测试了,按照例程里的0~255十六进制数值读写都正常打印,这样就能说明我的F450固件库和SD卡的驱动是匹配 ...

64g 的我没试过

使用特权

评论回复
ywd_Linux| | 2021-5-23 12:58 | 显示全部楼层

昨天我重新买一张小容量的SD卡  ,果然容量有问题,换上就正常了

使用特权

评论回复
eWorker| | 2021-5-23 22:46 | 显示全部楼层
fatfs高版本移植不成功,lz有分析原因么?

使用特权

评论回复
zeshoufx|  楼主 | 2021-5-24 09:48 | 显示全部楼层
ywd_Linux 发表于 2021-5-23 12:58
昨天我重新买一张小容量的SD卡  ,果然容量有问题,换上就正常了

大部分最大都不超过32G

使用特权

评论回复
ywd_Linux| | 2021-6-15 17:25 | 显示全部楼层
zeshoufx 发表于 2021-5-24 09:48
大部分最大都不超过32G

多谢多谢!

使用特权

评论回复
ccxzjz| | 2022-4-18 13:50 | 显示全部楼层
楼主,底层的读写对接使用的是单个block读写,不应该是多个block读写的接口?下面这个参数都没用上。
2984625cfb7ce15e4.png
奇怪的是,在GD32F407对接fatfs, 使用的是官方多个block读写的接口,文件系统都挂载不了

使用特权

评论回复
UchihaSasuke| | 2023-10-29 07:25 | 显示全部楼层
有长时间使用吗,我的405在长时间写数据后出现卡格式化异常。

使用特权

评论回复
chenqianqian| | 2023-10-30 08:40 | 显示全部楼层
看来还不能都用最新的版本?

使用特权

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

本版积分规则

66

主题

1945

帖子

14

粉丝