RT-Thread 驱动SD卡

添加SDIO模块,报错dfs_fs.h: No such file or directory

刚开始打开SDIO模块,编译会出现各种路径问题,本来以为是文件包含路径出现错误,最后发现是虚拟文件系统没打开,点开组件中DFS和Fatfs组件就不会再出错。

配置过程

  1. 使用STM32CubeMX 配置SDIO
    在这里插入图片描述
  2. 新建RT-Thread工程
    按照board.h中的步骤配置好SDIO
/** if you want to use sdio you can use the following instructions.
 *
 * STEP 1, open sdio driver framework support in the RT-Thread Settings file
 *
 * STEP 2, define macro related to the sdio
 *                 such as    BSP_USING_SDIO
 *
 * STEP 3, copy your sdio init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
 *                 such as     void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
 *
 * STEP 4, modify your stm32xxxx_hal_config.h file to support sdio peripherals. define macro related to the peripherals
 *                 such as     #define HAL_SD_MODULE_ENABLED
 *
 * STEP 5, config your device file system or another applications
 *
 */

首先打开SDIO的驱动和DFS,Fatfs组件
在这里插入图片描述
第二步打开board.h中的
#define BSP_USING_SDIO

第三步复制刚刚STM32CubeMX 生成的代码到board.c的最后

/**
* @brief SD MSP Initialization
* This function configures the hardware resources used in this example
* @param hsd: SD handle pointer
* @retval None
*/
void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hsd->Instance==SDIO)
  {
  /* USER CODE BEGIN SDIO_MspInit 0 */

  /* USER CODE END SDIO_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_SDIO_CLK_ENABLE();

    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOD_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.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /* USER CODE BEGIN SDIO_MspInit 1 */

  /* USER CODE END SDIO_MspInit 1 */
  }

}

/**
* @brief SD MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hsd: SD handle pointer
* @retval None
*/
void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd)
{
  if(hsd->Instance==SDIO)
  {
  /* USER CODE BEGIN SDIO_MspDeInit 0 */

  /* USER CODE END SDIO_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_SDIO_CLK_DISABLE();

    /**SDIO GPIO Configuration
    PC8     ------> SDIO_D0
    PC9     ------> SDIO_D1
    PC10     ------> SDIO_D2
    PC11     ------> SDIO_D3
    PC12     ------> SDIO_CK
    PD2     ------> SDIO_CMD
    */
    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
                          |GPIO_PIN_12);

    HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);

  /* USER CODE BEGIN SDIO_MspDeInit 1 */

  /* USER CODE END SDIO_MspDeInit 1 */
  }

}

第四步打开stm32f4xx_hal_conf.h中的
#define HAL_SD_MODULE_ENABLED
在这里插入图片描述
代码

/*
 * Copyright (c) 2006-2023, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-03-14     RT-Thread    first version
 */

#include <rtthread.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include "board.h"
#include "dfs_fs.h"
#include "stm32f4xx_hal_sd.h"

#define BLOCK_START_ADDR 0 /* Block start address */
#define NUM_OF_BLOCKS 1 /* Total number of blocks */
#define BUFFER_WORDS_SIZE ((BLOCKSIZE * NUM_OF_BLOCKS) >> 2)

uint8_t Buffer_Tx[512],Buffer_Rx[512] = {0};
uint32_t i;
SD_HandleTypeDef *hsd;
rt_device_t sd_dev;

void fill_buffer(rt_uint8_t *buff, rt_uint32_t buff_length)
{
    rt_uint32_t index;
    /* 往缓冲区填充随机数 */
    for (index = 0; index < buff_length; index++)
    {
        buff[index] = ((rt_uint8_t)rand()) & 0xff;
    }
}

int main(void)
{
    rt_pin_mode(GET_PIN(H, 9), PIN_MODE_OUTPUT);//这是我板子的控制台串口开关
    rt_pin_write(GET_PIN(H, 9),PIN_HIGH);
    rt_pin_mode(GET_PIN(H, 14), PIN_MODE_OUTPUT);//这是SD卡的开关
    rt_pin_write(GET_PIN(H, 14),PIN_HIGH);
    rt_thread_mdelay(100);

    rt_kprintf("=========start============\n");

    rt_size_t ret;
    struct rt_device_blk_geometry geo;
    rt_uint8_t *write_buff, *read_buff;
    rt_uint8_t block_num;

    /*查找并获取设备句柄*/
    sd_dev = rt_device_find("sd0");
    if (sd_dev == RT_NULL)
    {
        rt_kprintf("=======find device sd0 failed!=======\n");
        return RT_ERROR;
    }
    rt_thread_mdelay(100);

    ret = rt_device_open(sd_dev, RT_DEVICE_FLAG_RDWR);
    if (ret != RT_EOK)
    {
        rt_kprintf("open device sd0 failed!\n");
        return ret;
    }
    rt_memset(&geo, 0, sizeof(geo));

    /* 获取块设备信息 */
    ret = rt_device_control(sd_dev, RT_DEVICE_CTRL_BLK_GETGEOME, &geo);
    if (ret != RT_EOK)
    {
        rt_kprintf("control device sd0 failed!\n");
        return ret;
    }
    rt_kprintf("device information:\n");
    rt_kprintf("sector  size : %d byte\n", geo.bytes_per_sector);
    rt_kprintf("sector count : %d \n", geo.sector_count);
    rt_kprintf("block   size : %d byte\n", geo.block_size);

    /* 准备读写缓冲区空间,大小为一个块 */
    read_buff = rt_malloc(geo.block_size);
    if (read_buff == RT_NULL)
    {
        rt_kprintf("no memory for read buffer!\n");
        return RT_ERROR;
    }
    write_buff = rt_malloc(geo.block_size);
    if (write_buff == RT_NULL)
    {
        rt_kprintf("no memory for write buffer!\n");
        rt_free(read_buff);
        return RT_ERROR;
    }
    /* 填充写数据缓冲区,为写操作做准备 */
    fill_buffer(write_buff, geo.block_size);
    /* 把写数据缓冲的数据写入SD卡中,大小为一个块,size参数以块为单位 */
    block_num = rt_device_write(sd_dev, 0, write_buff, 1);
    if (1 != block_num)
    {
        rt_kprintf("write device sd0 failed!\n");
    }

    /* 从SD卡中读出数据,并保存在读数据缓冲区中 */
    block_num = rt_device_read(sd_dev, 0, read_buff, 1);
    if (1 != block_num)
    {
        rt_kprintf("read sd0 device failed!\n");
    }

    /* 比较写数据缓冲区和读数据缓冲区的内容是否完全一致 */
    if (rt_memcmp(write_buff, read_buff, geo.block_size) == 0)
    {
        rt_kprintf("Block test OK!\n");
    }
    else
    {
        rt_kprintf("Block test Fail!\n");
    }
    /* 释放缓冲区空间 */
    rt_free(read_buff);
    rt_free(write_buff);

    return RT_EOK;
}

运行结果
在这里插入图片描述
注:2023.3.14 SD卡学习笔记

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RT-Thread是一个实时操作系统,可以在不同的硬件平台上运行。在使用RT-Thread操作系统时,可以使用SD接口实现对SD数据的读和写。 具体实现的步骤如下: 1. 创建基本工程,包括创建Bootloader和相关组件的配置。 2. 在STM32F4芯片系列中,只支持SD 2.0协议,即SDSDHC。不支持SDXC协议,同时也只支持读取512大小的数据块。因此,在选择SD时需要注意其兼容性和数据块大小的设置。 3. SD具有物理结构,需要了解其具体规格和连接方式,以确保正确的使用和操作。 4. 在使用RT-Thread操作系统时,可以根据具体的开发板和硬件平台选择合适的驱动和框架,如使用FSMC总线驱动TFT显示屏、SPI驱动W25Qxx Nor flash等。 总之,RT-Thread操作系统提供了对SD的支持,可以通过配置和选择合适的驱动和框架来实现对SD数据的读和写操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [RT-Thread Studio驱动SD](https://blog.csdn.net/weixin_37875741/article/details/109733737)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [rt-thread驱动篇(07)---STM32F429单片机SD驱动添加](https://blog.csdn.net/m0_37845735/article/details/124548387)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [RT-Thread1.2.0.rar_STM32 RT-Thread_STM32 SPI TF_STM32的SDIO例程_s](https://download.csdn.net/download/weixin_42659252/86145822)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值