当前位置: 首页 > news >正文

STM32 通过USB的Mass Storage Class读写挂载的SD卡出现卡死问题

问题描述:
使用stm32cubemx生成的sdio和usb Mass Storage Class的代码后,在USB_DEVICE\App\usbd_storage_if.c文件里面的接口调用以下函数出现卡死问题:
SD_Driver.disk_initialize(0);
SD_Driver.disk_read(lun, buf, blk_addr, blk_len)
SD_Driver.disk_write(lun, buf, blk_addr, blk_len);

解决办法:
1、STORAGE_Init_FS里面不直接调用disk_initialize,在MX_SDIO_SD_Init里面直接初始化sd卡,

2、读写sd卡的函数改为dma的读写接口:
HAL_SD_ReadBlocks_DMA(&hsd, buf, blk_addr, blk_len)
HAL_SD_WriteBlocks_DMA(&hsd, buf, blk_addr, blk_len)


USB_DEVICE\App\usbd_storage_if.c文件的具体代码如下:

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : usbd_storage_if.c* @version        : v1.0_Cube* @brief          : Memory management layer.******************************************************************************* @attention** Copyright (c) 2025 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "usbd_storage_if.h"/* USER CODE BEGIN INCLUDE */
#include "sdio.h"
#include "sd_diskio.h"
#include "log_debug.h"
/* USER CODE END INCLUDE *//* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*//* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*//* USER CODE END PV *//** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY* @brief Usb device.* @{*//** @defgroup USBD_STORAGE* @brief Usb mass storage device module* @{*//** @defgroup USBD_STORAGE_Private_TypesDefinitions* @brief Private types.* @{*//* USER CODE BEGIN PRIVATE_TYPES *//* USER CODE END PRIVATE_TYPES *//*** @}*//** @defgroup USBD_STORAGE_Private_Defines* @brief Private defines.* @{*/#define STORAGE_LUN_NBR                  1/* USER CODE BEGIN PRIVATE_DEFINES *//* USER CODE END PRIVATE_DEFINES *//*** @}*//** @defgroup USBD_STORAGE_Private_Macros* @brief Private macros.* @{*//* USER CODE BEGIN PRIVATE_MACRO *//* USER CODE END PRIVATE_MACRO *//*** @}*//** @defgroup USBD_STORAGE_Private_Variables* @brief Private variables.* @{*//* USER CODE BEGIN INQUIRY_DATA_FS */
/** USB Mass storage Standard Inquiry Data. */
const int8_t STORAGE_Inquirydata_FS[] = {/* 36 *//* LUN 0 */0x00,0x80,0x02,0x02,(STANDARD_INQUIRY_DATA_LEN - 5),0x00,0x00,0x00,'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product      : 16 Bytes */' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ','0', '.', '0' ,'1'                      /* Version      : 4 Bytes */
};
/* USER CODE END INQUIRY_DATA_FS *//* USER CODE BEGIN PRIVATE_VARIABLES *//* USER CODE END PRIVATE_VARIABLES *//*** @}*//** @defgroup USBD_STORAGE_Exported_Variables* @brief Public variables.* @{*/extern USBD_HandleTypeDef hUsbDeviceFS;/* USER CODE BEGIN EXPORTED_VARIABLES *//* USER CODE END EXPORTED_VARIABLES *//*** @}*//** @defgroup USBD_STORAGE_Private_FunctionPrototypes* @brief Private functions declaration.* @{*/static int8_t STORAGE_Init_FS(uint8_t lun);
static int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size);
static int8_t STORAGE_IsReady_FS(uint8_t lun);
static int8_t STORAGE_IsWriteProtected_FS(uint8_t lun);
static int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
static int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
static int8_t STORAGE_GetMaxLun_FS(void);/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION *//* USER CODE END PRIVATE_FUNCTIONS_DECLARATION *//*** @}*/USBD_StorageTypeDef USBD_Storage_Interface_fops_FS =
{STORAGE_Init_FS,STORAGE_GetCapacity_FS,STORAGE_IsReady_FS,STORAGE_IsWriteProtected_FS,STORAGE_Read_FS,STORAGE_Write_FS,STORAGE_GetMaxLun_FS,(int8_t *)STORAGE_Inquirydata_FS
};/* Private functions ---------------------------------------------------------*/
/*** @brief  Initializes the storage unit (medium) over USB FS IP* @param  lun: Logical unit number.* @retval USBD_OK if all operations are OK else USBD_FAIL*/
int8_t STORAGE_Init_FS(uint8_t lun)
{/* USER CODE BEGIN 2 *///需要提取初始化sd卡,这里初始化sd卡会卡死if(HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER){log_debug("STORAGE_Init_FS\n");return USBD_OK;}log_debug("STORAGE_Init_FS fail\n");return USBD_FAIL;/* USER CODE END 2 */
}/*** @brief  Returns the medium capacity.* @param  lun: Logical unit number.* @param  block_num: Number of total block number.* @param  block_size: Block size.* @retval USBD_OK if all operations are OK else USBD_FAIL*/
int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
{/* USER CODE BEGIN 3 */HAL_SD_CardInfoTypeDef info;if(HAL_SD_GetCardState(&hsd) ==  HAL_SD_CARD_TRANSFER){HAL_SD_GetCardInfo(&hsd, &info);*block_num = info.LogBlockNbr;*block_size = info.LogBlockSize;//log_debug("SD_GetCardInfo: %d, %d\r\n", *block_num, *block_size);return  USBD_OK;}log_debug("STORAGE_GetCapacity_FS Fail !!!\n");return  USBD_FAIL;/* USER CODE END 3 */
}/*** @brief   Checks whether the medium is ready.* @param  lun:  Logical unit number.* @retval USBD_OK if all operations are OK else USBD_FAIL*/
int8_t STORAGE_IsReady_FS(uint8_t lun)
{/* USER CODE BEGIN 4 */if(HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER){return USBD_OK;}log_debug("STORAGE_IsReady_FS Fail !!!\n");return USBD_FAIL;/* USER CODE END 4 */
}/*** @brief  Checks whether the medium is write protected.* @param  lun: Logical unit number.* @retval USBD_OK if all operations are OK else USBD_FAIL*/
int8_t STORAGE_IsWriteProtected_FS(uint8_t lun)
{/* USER CODE BEGIN 5 *///log_debug("STORAGE_IsWriteProtected_FS: %d\r\n", lun);return (USBD_OK);/* USER CODE END 5 */
}/*** @brief  Reads data from the medium.* @param  lun: Logical unit number.* @param  buf: data buffer.* @param  blk_addr: Logical block address.* @param  blk_len: Blocks number.* @retval USBD_OK if all operations are OK else USBD_FAIL*/
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{/* USER CODE BEGIN 6 */int8_t ret = USBD_FAIL;  if( HAL_SD_ReadBlocks_DMA(&hsd, buf, blk_addr, blk_len) == HAL_OK )// if( HAL_SD_ReadBlocks(&hsd, buf, blk_addr,  blk_len, HAL_MAX_DELAY) == HAL_OK ){ret = USBD_OK;//while(HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY){};while( HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER ){};} else {ret = USBD_FAIL;log_debug("STORAGE_Read_FS Fail !!!\n");} return ret;/* USER CODE END 6 */
}/*** @brief  Writes data into the medium.* @param  lun: Logical unit number.* @param  buf: data buffer.* @param  blk_addr: Logical block address.* @param  blk_len: Blocks number.* @retval USBD_OK if all operations are OK else USBD_FAIL*/
int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{/* USER CODE BEGIN 7 */int8_t ret = USBD_FAIL; if( HAL_SD_WriteBlocks_DMA(&hsd, buf, blk_addr, blk_len) == HAL_OK )// if( HAL_SD_WriteBlocks(&hsd, buf, blk_addr, blk_len, HAL_MAX_DELAY) == HAL_OK ){ret = USBD_OK;//while(HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY){};while( HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER ){};}  else {ret = USBD_FAIL;log_debug("STORAGE_Write_FS Fail !!!\n");}return ret;/* USER CODE END 7 */
}/*** @brief  Returns the Max Supported LUNs.* @param  None* @retval Lun(s) number.*/
int8_t STORAGE_GetMaxLun_FS(void)
{/* USER CODE BEGIN 8 */
//   log_debug("STORAGE_GetMaxLun_FS: %d\r\n", STORAGE_LUN_NBR);return (STORAGE_LUN_NBR - 1);/* USER CODE END 8 */
}/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION *//* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION *//*** @}*//*** @}*/


文章转载自:

http://pNT8FMWr.nwrzf.cn
http://hqrFJXdG.nwrzf.cn
http://tIuDapAT.nwrzf.cn
http://TFcbf56S.nwrzf.cn
http://f0lowfJ1.nwrzf.cn
http://996tcxyy.nwrzf.cn
http://zzB0C09x.nwrzf.cn
http://ywlbKIFr.nwrzf.cn
http://ezmJ5iuI.nwrzf.cn
http://JeYUwbZq.nwrzf.cn
http://zdnq1I3P.nwrzf.cn
http://evKsiaeC.nwrzf.cn
http://iyCjClzB.nwrzf.cn
http://octmf1aY.nwrzf.cn
http://sHdgLFT3.nwrzf.cn
http://k37RvIyq.nwrzf.cn
http://nvl14zUj.nwrzf.cn
http://hPVzUNuj.nwrzf.cn
http://0ywWiLHu.nwrzf.cn
http://Yw2Fhd9Z.nwrzf.cn
http://Rof5N3PW.nwrzf.cn
http://0wIs9ceX.nwrzf.cn
http://T3nx5AIe.nwrzf.cn
http://4rR3pVPy.nwrzf.cn
http://gfmKLU5z.nwrzf.cn
http://BJm5sKF8.nwrzf.cn
http://wyZrZL9k.nwrzf.cn
http://7TzYFyaW.nwrzf.cn
http://qXrqIdX0.nwrzf.cn
http://eC0kcis7.nwrzf.cn
http://www.dtcms.com/a/387041.html

相关文章:

  • 【Nginx开荒攻略】Nginx基本服务配置:从启动到运维的完整指南
  • 《漫威争锋》公布开发者愿景视频:介绍1.5版本的内容
  • Isight许可管理与其他软件集成的方法
  • 论文提纲:学术写作的“蓝图”,如何用AI工具沁言学术高效构建?
  • 快速解决云服务器的数据库PhpMyAdmin登录问题
  • 知识更新缺乏责任人会带来哪些风险
  • 容器化部署番外篇之Nexus3搭建私有仓库09
  • 计算机视觉(opencv)实战二十四——扫描答题卡打分
  • 居住证申请:线上照片回执办理!
  • Roo Code 的差异_快速编辑功能
  • 【深度学习】基于深度学习算法的图像版权保护数字水印技术
  • mcp初探
  • 深入C++对象生命周期:从构造到析构的奥秘
  • 视频上传以及在线播放
  • Powershell and Python are very similar
  • 鸿蒙Next离线Web组件实战:轻松实现离线加载与缓存优化
  • deepseek原理
  • 力扣复盘 之“移动零”
  • 任务管理系统常用平台整理:适合多项目团队
  • docker安装华为openGauss数据库
  • AI的设计图,神经网络架构
  • abaqus仿真完后如何把受力曲线显示出来
  • 核心硬件面试题目详解和回答策略之1
  • [MySQL]Order By:排序的艺术
  • Android创建新的自定义系统分区实现OTA内容修改
  • Linux内存管理章节十三:打通外设与内存的高速通道:深入Linux DMA与一致性内存映射
  • DIV居中
  • 扩散模型对齐:DMPO 让模型更懂人类偏好
  • nvidia jetson nano 连接蓝牙音响
  • 用Postman实现自动化接口测试和默认规范