CH32移植Fatfs文件操作系统(沁恒RISC-V内核)

本文所用芯片:CH32V307VCT6

使用SDIO读写SD卡,同时移植Fatfs对文件进行管理

1.首先在MounRiverStudio(后续称为MRS)中新建一个工程 在这里插入图片描述

选择自己单片机的型号,点击完成。 在这里插入图片描述

接下来我们去找到沁恒官方的例程 打开例程中 EVT->EXAM->SDIO->User文件夹

在这里插入图片描述 复制sdio.c和sdio.h 在这里插入图片描述 把这两个文件粘贴到你的工程中去。

然后到Fatfs官网下载最新的文件 下载网址:elm-chan.org/fsw/ff/00in…

滚动页面到底,可以看到Download 选择我圈出来的这个选项 在这里插入图片描述 浏览器会自动开始下载,下载完成后解压文件,打开文件夹能看到: 在这里插入图片描述 我们选择source,里面是Fatfs的源码 选中除了两个txt结尾的文件 在这里插入图片描述 也一同复制到我们的工程中去。 然后我们在工程中在新建一个headfile.h文件用来管理头文件 这样工程中总共有 在这里插入图片描述 Ps:这样直接在user中添加.h文件和.c文件的方式不太好,我这里是为了方便演示,实际使用最好把自己的代码放到一个新的文件夹下面。

然后回到MRS中(自己添加文件夹的同学,记得添加下文件夹路径) 我们先打开headfile.h文件夹 在这里插入图片描述 把一会要用到的.h文件定义好。 Fatfs的移植主要在diskio.c中,所以我们先打开这个文件

第一步适配应用层函数

将headfile.h文件包含进 diskio.c (diskio.h也可以) 在这里插入图片描述 然后我们往下看,能看到3个#define,这是对设备类型的定义 我们本次移植的SD卡,属于MMC类型,所以我们可以直接用源文件中的定义,记住这个DEV_MMC 他的define为 1 我们接下来的操作主要都是争对他。 因为我们这里使用默认的3个类型,所以我们最好去ff_conf.h中修改在这里插入图片描述 使用卷的个数,我们先改成3,然后回到原来的地方

继续往下看能够看到几个函数,把文件滑倒底总共也只有 disk_status disk_initialize disk_read disk_write disk_ioctl 5个函数,我们要做的就是适配这5个函数即可。

我们由上及下的顺序来操作 看第一个函数

1.disk_status

看名字我们也能知道,这是获取Disk磁盘设备状态的函数,但是我们其实用不到这个,沁恒官方的SD卡初始化中已经对SD的状态做出来判断,所以我们直接放弃这个函数。 将函数switch中的除了DEV_MMC的选项直接改成break(因为我们本次移植只用到了SD卡,所以其他设备一律不检测,强制返回设备未初始化),对DEV_MMC选项直接返回 0 (也就初始化成功状态)。 在这里插入图片描述

2.disk_initialize

我们还是先看名字,就能知道这个函数是磁盘初始化函数,所以我们要在这个函数中初始化我们的磁盘也就是SD卡初始化。 同样的我们将函数switch中的除了DEV_MMC的选项直接改成break(因为我们本次移植只用到了SD卡,所以其他设备一律不检测,强制返回设备未初始化),然后对DEV_MMC选项进行SD卡初始化,沁恒官方的SD初始化函数为SD_Init();函数原型在sdio.c中可以查看,有兴趣的同学可以去了解下SD初始化的过程(自己移植非常的痛苦,我们就先享受下便利),SD_Init() 返回值为0代表初始化成功(刚好0在Fatfs中也是成功),所以我们直接返回就好了。这个函数移植结束,我们看下一个。 在这里插入图片描述

3.disk_read

磁盘读取函数,我们先找到sdio.c中对应磁盘读取函数SD_ReadDisk(),复制到DEV_MMC选项下面,然后我们看SD_ReadDisk函数需要的参数(数据地址,扇区,数量),再看我们disk_read函数的传参(驱动器编号,数据地址,扇区,数量)这不是巧了嘛,我们直接复制粘贴就好了 在这里插入图片描述 这个函数我们也移植好了。

4.disk_write

磁盘写入函数,同理找到sdio.c中的磁盘写入函数SD_WriteDisk(),依样画葫芦。 在这里插入图片描述 但是会有一个警告,原因是传入参数 const BYTE *buff 带有const类型,传入SD_WriteDisk 后 const 就被丢弃了,这个不影响,我们先不管。

5.disk_ioctl

这个函数主要是用来获取磁盘的各种信息

在这里插入图片描述 GET_SECTOR_SIZE是获取磁盘扇区大小,就保存在sido.c中的SDCardInfo结构体下CardBlockSize GET_BLOCK_SIZE是用来指定擦除的最小单位,就是SDCardInfo结构体下CardBlockSize 这里有的同学可能就要疑惑了,为什么这两个是一样的,这个Fatfs中,块是大于等于扇区的,和SD卡里刚好相反(为什么会这样我也不知道,有大佬指点迷津吗) GET_SECTOR_COUNT是获取扇区个数 按照FatFs官网的驱动中还有几个指令,但是用不上我们就先不写了。 在这里插入图片描述 好了,我们移植5个函数完成。 大功告吉,点击编译。 没有报错。我们开始愉快的写代码。 我们先来挂载下磁盘。

我们现在main.c文件最上方注释了变量定义区的地方定义

FATFS fs;                     /* FatFs文件系统对象 */
FIL fnew;                     /* 文件对象 */
UINT fnum;                    /* 文件成功读写数量 */
FRESULT res_sd;               /* 文件操作结果 */
BYTE    work[FF_MAX_SS];
BYTE WriteBuffer[] = {"txt.test\r\n"};/* 写缓冲区*/
复制代码

在这里插入图片描述 然后在main函数中我们开始挂载磁盘

    res_sd = f_mount(&fs,"1:",1);

    if(res_sd == FR_NO_FILESYSTEM)
    {
        printf("formatting\r\n");
        res_sd=f_mkfs("1:",0,work, sizeof(work));
        res_sd = f_mount(NULL,"1:",1);
        /* 重新挂载	*/
        res_sd = f_mount(&fs,"1:",1);
    }
复制代码

在这里插入图片描述 点击编译,然后我们就发现,报错了,原因是f_mkfs未定义(不能创建文件系统这怎么能忍) 但是我们点击转跳发现这个函数在ff.c中已存在 在这里插入图片描述

在这里插入图片描述 我们可以看到灰色的f_mkfs,这是编译器屏蔽编译的提示,我们往上翻就可以看到,有两个判断条件 FF_FS_READONLY = 0,!FF_FS_READONLY == 1 所以我们看另一个FF_USE_MKFS ,看名字叫使用mkfs,不就是我们要用的函数吗,我们进去把他改为1 在这里插入图片描述 这下应该好了把,都改完了,点击编译。 又报错了 在这里插入图片描述 提示没有get_fattime函数(获取文件时间),我们点一下,发现这个函数真的没有,那没办法了,我们只能自己创建了,因为我们用不到这个函数(要用的话需要上RTC)

我们在diskio.c最下面定义这个没啥用的函数

DWORD get_fattime (void)
{
    return 0;
}
复制代码

在这里插入图片描述 别忘了在diskio.h中声明下 在这里插入图片描述 此时我们再点编译,就没有问题了。

一步到位,我们已经移植完毕Fatfs了,可以开始愉快的使用了(怎么使用我就不教了,大家自己百度吧)

注意事项,如果全部完成后依旧出现文件打开/创建失败,可能是文件名超长了,把ffconf.h中FF_USE_LFN改为1 (启用长文件名)就好了,但是依旧不建议文件名太长。 在这里插入图片描述 PS:最近使用了一下沁恒的CH32系列芯片,还是挺好用的,几乎和ST标准库一模一样,芯片性能和价格都比较出色(沁恒打钱),后续估计还会CH系列的使用教程,感谢观看。

猜你喜欢

转载自juejin.im/post/7193618591453806651