CH32 移植 Fatfs ファイル オペレーティング システム (Qinheng RISC-V カーネル)

この記事で使用したチップ: CH32V307VCT6

SDIO を使用して SD カードを読み書きし、Fatfs を移植してファイルを管理します

1.まず、MounRiverStudio (後に MRS と呼ばれる) で新しいプロジェクトを作成します。ここに画像の説明を挿入

MCU のモデルを選択し、[完了] をクリックします。ここに画像の説明を挿入

次に、Qinheng の公式ルーチンを見つけて、ルーチン内の EVT->EXAM->SDIO->User フォルダを開きます。

ここに画像の説明を挿入sdio.c と sdio.h をコピーここに画像の説明を挿入して、これら 2 つのファイルをプロジェクトに貼り付けます。

次に、Fatfs の公式 Web サイトに移動して、最新のファイル ダウンロード URL をダウンロードします: elm-chan.org/fsw/ff/00in…

ページの最後までスクロールすると、[ダウンロード] が表示されます。丸で囲んだオプションを選択すると、ここに画像の説明を挿入ブラウザーが自動的にダウンロードを開始します。ダウンロードが完了したら、ファイルを解凍し、フォルダーを開くと、次のことがわかりここに画像の説明を挿入ます。 Fatfs のソース コード (2 つの txt 末尾を除く) のファイルここに画像の説明を挿入もプロジェクトにコピーされます。次に、ヘッダー ファイルを管理するためにプロジェクトに新しい headfile.h ファイルを作成するので、プロジェクトには合計ここに画像の説明を挿入Ps があり、ユーザーに .h ファイルと .c ファイルを直接追加するのはあまり良くありません。デモンストレーションの便宜上. 実際の使用では、独自のコードを新しいフォルダーに配置するのが最善です.

次に、MRS に戻ります (自分でフォルダーを追加する学生は、フォルダー パスを追加することを忘れないでください)。最初に headfile.hここに画像の説明を挿入フォルダー。Fatfs の移植は主に diskio.c にあるため、このファイルを最初に開きます。

最初のステップは、アプリケーション層機能を適応させることです

headfile.h ファイルを diskio.c にインクルード (diskio.h も利用可能)ここに画像の説明を挿入すると、下を見るとデバイス タイプの定義である 3 つの #define が表示されます。 MMC タイプ. したがって、ソース ファイルの定義を直接使用できます。DEV_MMCには1の定義があることを思い出してください。次の操作は主にそれと競合することです。ここではデフォルトの 3 種類を使用しているため、ff_conf.h に移動してここに画像の説明を挿入使用ボリューム数を変更し、最初に 3 に変更してから元の場所に戻します。

引き続き下を見ていくと、いくつかの関数が見えます.ファイルを下にスライドさせる関数は、 disk_status、disk_initialize、disk_read、disk_write、disk_ioctl の5 つだけです.必要なのは、これら 5 つの関数を適応させることだけです.

最初の機能を見るために上から下に操作します

1.ディスクステータス

名前からもDiskディスク装置の状態を取得する機能であることがわかりますが、Qinheng公式のSDカード初期化でSDカードの状態を判断済みなので、そのまま使うことはできません。この機能をアップします。DEV_MMC以外の機能スイッチのオプションを直接ブレークするように変更します (この移植では SD カードのみを使用するため、他のデバイスは検出されず、デバイスは初期化されていない状態に強制的に戻されます) 。DEV_MMCオプションは、直接 0 に戻されます (つまり、初期化が成功した状態)。ここに画像の説明を挿入

2.ディスク初期化

我们还是先看名字,就能知道这个函数是磁盘初始化函数,所以我们要在这个函数中初始化我们的磁盘也就是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 で宣言することを忘れないでくださいここに画像の説明を挿入。この時点でもう一度 [コンパイル] をクリックします。問題はありません。

1 つのステップが整っており、Fatfs は既に移植されており、楽しく使用を開始できます (使用方法は教えません。誰もが自分で Baidu を使用できます)。

すべてが完了してもファイルのオープン/作成に失敗する場合は、ファイル名が長すぎる可能性があります.ffconf.h のFF_USE_LFNを 1 に変更します (長いファイル名を有効にします)。名前が長すぎます。ここに画像の説明を挿入PS: 私は最近 Qinheng の CH32 シリーズ チップを使用しました, これは非常に使いやすいです. それらは ST 標準ライブラリとほぼ同じです. チップの性能と価格は比較的良いです (Qinheng はそれを支払います).今後もCHシリーズのチュートリアルを予定しておりますので、どうぞよろしくお願いいたします。

おすすめ

転載: juejin.im/post/7193618591453806651