基于STM32CubeMX SDIO DMA + FATFS
在此基础增加MSC大容量存储。
软件架构框图
FATFS及MSC共用SDIO接口。
USB配置
参数均默认。
中断配置
这里特别注意,sdio的dma中断优先级需要高于usb global中断,因为usb发送接收回调均在global中断中实现,如果global中断优先级更高将导致sdio dma中断无法抢占,以致于一直处于busy状态。
如果使用了freertos,配置如下:
代码修改
修改USB_DEVICE\App\usbd_storage_if.c,实现SDIO调用接口。
1. 包含头文件:#include "sdio.h"
2.实现STORAGE_GetCapacity_FS函数:
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;
return USBD_OK;
}
return USBD_FAIL;
/* USER CODE END 3 */
}
3.实现STORAGE_Read_FS函数:
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 6 */
UNUSED(lun);
UNUSED(buf);
UNUSED(blk_addr);
UNUSED(blk_len);
int8_t ret = USBD_FAIL;
//if (HAL_SD_ReadBlocks(&hsd, buf, blk_addr, blk_len, HAL_MAX_DELAY) == HAL_OK)
if(HAL_SD_ReadBlocks_DMA(&hsd, buf, blk_addr, blk_len) == HAL_OK)
{
ret = USBD_OK;
while (HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY)
;
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
;
}
return ret;
/* USER CODE END 6 */
}
4.实现STORAGE_Write_FS函数:
int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
{
/* USER CODE BEGIN 7 */
UNUSED(lun);
UNUSED(buf);
UNUSED(blk_addr);
UNUSED(blk_len);
int8_t ret = USBD_FAIL;
// if (HAL_SD_WriteBlocks(&hsd, buf, blk_addr, blk_len, HAL_MAX_DELAY) == HAL_OK)
if(HAL_SD_WriteBlocks_DMA(&hsd, buf, blk_addr, blk_len) == HAL_OK)
{
ret = USBD_OK;
while (HAL_SD_GetState(&hsd) == HAL_SD_STATE_BUSY)
;
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
;
}
return ret;
/* USER CODE END 7 */
}