一、rtthread使用SD卡
1、配置RT-ThreadSetting
开启SDIO,配置保存。
2、开启board.h及stm32f1xx_hal_conf.h的宏定义
3、使用STM32cube配置引脚及通讯参数
生成配置文件,复制stm32f1xx_hal_msp.c中void HAL_SD_MspInit(SD_HandleTypeDef* hsd)到board.c的最后,HAL库初始化时会调用,同时别忘记更改board.c上面的函数改为外部时钟。
void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hsd->Instance==SDIO)
{
/* USER CODE BEGIN SDIO_MspInit 0 */
/* USER CODE END SDIO_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SDIO_CLK_ENABLE();
/**SDIO GPIO Configuration
PC8 ------> SDIO_D0
PC9 ------> SDIO_D1
PC10 ------> SDIO_D2
PC11 ------> SDIO_D3
PC12 ------> SDIO_CK
PD2 ------> SDIO_CMD
*/
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USER CODE BEGIN SDIO_MspInit 1 */
/* USER CODE END SDIO_MspInit 1 */
}
}
4、挂载文件elm-fat系统
虚拟文件系统资料链接
前2个步骤开启文件系统的时候就已经被调用了,第3步如果是使用SDIO,会在程序中自动初始化注册为块设备,则也不需要编写,如果是使用SPI则需要编写注册块设备语句。
在SD卡上使用文件系统链接
接下来进行第4、5步的程序编写,先格式化,然后再挂载块设备到DFS目录上,之后就可以开始验证工作了。
void mnt_init(void)
{
rt_thread_mdelay(100);//这段延时必须加上,系统上电过程中存在延时,否则会出现先挂载后注册块设备sd0的情况
mkfs("elm","sd0");//挂在前需格式化
if(dfs_mount("sd0","/","elm",0,0)==0) //挂载文件系统,参数:块设备名称、挂载目录、文件系统类型、读写标志、私有数据0
{
rt_kprintf("dfs mount success\r\n");
}
else
{
rt_kprintf("dfs mount failed\r\n");
}
}
二、验证
挂载文件系统前未加延时的情况:
现象如图,注册块设备失败了,但是读SD卡的内存成功了,这样子的话是不能实现增删改查文件的。根据这个打印信息,明显是先挂载了文件系统没有找到sd0设备(Device(sd0) was not found),然后才初始化注册的块设备读出了内存,但是程序中明明就是在系统初始化完成后在main()函数中才执行的挂载,那问题出在哪里呢?
仿真找了一下,文件系统先挂载了,然后sd0块设备后注册,导致查询不到块设备sd0,这并不是我故意后注册块设备,我仿真查询到SD卡系统初始化的时候,上电过程中在mmcsd_power_up()这个函数中存在延时,导致块设备初始化线程挂起(SDIO驱动SD卡是系统自动注册块设备的),在自己写的初始化中挂载文件系统的语句就先运行了,导致运行不正常,解决方式是在SD卡格式化前加一小段延时。
void mnt_init(void)
{
rt_thread_mdelay(100);//这段延时必须加上,系统上电过程中存在延时,否则会出现先挂载后注册块设备sd0的情况
mkfs("elm","sd0");//挂在前需格式化
if(dfs_mount("sd0","/","elm",0,0)==0) //挂载文件系统,参数:块设备名称、挂载目录、文件系统类型、读写标志、私有数据0
{
rt_kprintf("dfs mount success\r\n");
}
else
{
rt_kprintf("dfs mount failed\r\n");
}
}
挂载文件系统前加了延时后的情况:
使用SDIO驱动SD卡挂载文件系统成功。