文章目录
RT-Thread(后文简称RT)提供的DFS组件、Fatfs组件和SDIO驱动组合起来可用于操作SD卡,但RT的底层驱动目前对STM32H743(后文简称H743)适配不是很好,在stm32h743上移植RT时,包括SDIO在内的多个设备驱动都无法直接编译通过。且当前官方论坛中关于在H743上应用RT的相关的帖子也比较少,因此在本次使用SD卡挂载文件系统时,因为底层驱动不适配,遇到了很多问题,也尝试了很多办法,最后通过 重写块设备部分的代码实现了文件系统的挂载。
开发环境
主控芯片:stm32h743iit6
硬件平台:自行制作的单板
RT-Thread版本:4.0.2
开发工具:RT-Thread Studio (Version: 2.0.0)(后文简称RT-Studio)
STM32CubeMX(Version: 6.0.1)
STM32CubeIDE(Version: 1.5.1)
存储设备:SD卡
RT虚拟文件系统简介
详细内容参看RT官方文档。
RT虚拟文件系统层次架构如下图所示。
![](https://raw.githubusercontent.com/hekuzhengfeng/pictures/master/img20200001.png)
DFS是RT提供的虚拟文件系统组件,该组件为应用程序提供方便的文件操作接口,并支持多种文件系统和存储设备。本文采用的文件系统是FatFS,主要是因为FatFS可以兼容微软的FAT格式,基于该文件系统将文件写入到SD卡后,SD内容可以直接被windows系统识别。
由于底层驱动不适配的问题,本文基于ST的HAL库重写了块设备相关代码,最终实现了文件系统的功能。
基于RT-Studio的配置
在RT-Studio中新建工程及其他功能的实现此处不再详述,首先介配置DFS组件和FatFS组件。如下图所示:
![](https://raw.githubusercontent.com/hekuzhengfeng/pictures/master/img20210225155935.png)
点亮DFS组件和Fatfs组件。可能需要libc组件的支持,这点没有做过验证。其他组件与文件系统本身无关,此处不详细介绍。
![](https://raw.githubusercontent.com/hekuzhengfeng/pictures/master/img20210225160534.png)
按上图所示进行配置,DFS可以加载多种文件系统,但此处只使用了FatFs文件系统。
重写块设备相关代码
重写块设备代码的原因
之所以要重新块设备相关代码,主要原因有二:一个是本文已经反复提到的底层驱动不适配的问题,另一个是RT原有的SD Card设备类mcsd_blk_device
较为复杂,包含了多个子类,需要研究多个类型及相关函数才能完成实例化,比较困难。
mcsd_blk_device
的定义如下:
struct mmcsd_blk_device
{
struct rt_mmcsd_card *card;
rt_list_t list;
struct rt_device dev;
struct dfs_partition part;
struct rt_device_blk_geometry geometry;
rt_size_t max_req_size;
};
生成SDMMC初始化代码
使用STM32CubeMX创建项目,配置SDMMC1为SD 4 bit Wide bus模式。配置如下图:
![](https://raw.githubusercontent.com/hekuzhengfeng/pictures/master/img20210225171354.png)
时钟配置此处不做展示,项目中时钟源选择PLL1Q,频率为400MHz。配置完成后生成代码备用。
在RT中初始化并注册块设备
struct rt_device
{
struct rt_object parent; /**< inherit from rt_object */
enum rt_device_class_type type; /**< device type */
rt_uint16_t flag; /**< device flag */
rt_uint16_t open_flag; /**< device open flag */
rt_uint8_t ref_count; /**< reference count */
rt_uint8_t device_id; /**< 0 - 255 */
/* device call back */
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);