zeshoufx 发表于 2021-5-10 20:24

关于GD32F303 fatfs文件系统挂载

一、最近看到论坛里有人问利用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等等,不需要做任何修改,

多次尝试后,最终移植成功







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),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),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={0};      /* 读缓冲区 */
BYTE WriteBuffer[] =            /* 写缓冲区*/
"Hello 21IC,Hello GD32f30vct6!\r\n";


externsd_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

zeshoufx 发表于 2021-5-10 20:37
五、主函数

六、之前看到群里有人抱怨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

单片小菜 发表于 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

zeshoufx 发表于 2021-5-22 19:17
64g 的我没试过

昨天我重新买一张小容量的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读写的接口?下面这个参数都没用上。

奇怪的是,在GD32F407对接fatfs, 使用的是官方多个block读写的接口,文件系统都挂载不了

UchihaSasuke 发表于 2023-10-29 07:25

有长时间使用吗,我的405在长时间写数据后出现卡格式化异常。

chenqianqian 发表于 2023-10-30 08:40

看来还不能都用最新的版本?
页: [1] 2
查看完整版本: 关于GD32F303 fatfs文件系统挂载