在前一篇文章“STM32H743 使用 SDMMC 接口读写 eMMC 存储器”的基础上,加入 USB Mass Storage Class 功能,实现 eMMC 的虚拟 U 盘功能。
一、开发平台
- 开发环境:MDK5.30
- 移植驱动:STM32Cube_FW_H7_V1.9.0
- 硬件平台:STM32H743VITX + eMMC(型号:MTFC4GACAJCN-1M WT)
二、STM32CubeMX 配置
2.1 USB_OTG_FS 选择 Device_Only 模式,参数默认

2.2 中间件 USB_DEVICE 选择 USB Mass Storage Class,参数默认

三、添加 eMMC 读写功能测试代码
需要用户实现的只有 USB 虚拟 U 盘相关的函数,都在 usbd_storage_if.c 文件中。需要实现以下几个函数,其中中文注释的四个为必须实现的,其它的可选。
USBD_StorageTypeDef USBD_Storage_Interface_fops_FS = { STORAGE_Init_FS, STORAGE_GetCapacity_FS, //获取 U 盘容量 STORAGE_IsReady_FS, //判断 U 盘状态 STORAGE_IsWriteProtected_FS, STORAGE_Read_FS, //读 U 盘数据 STORAGE_Write_FS, //写 U 盘数据 STORAGE_GetMaxLun_FS, (int8_t *)STORAGE_Inquirydata_FS };
因为 SD 卡扇区读写等相关的驱动函数系统已经自动生成,这里只需要调用相关函数即可。四个函数的实现如下:
获取容量函数:
/** * @brief . * @param lun: . * @param block_num: . * @param 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_MMC_CardStateTypeDef State; State = HAL_MMC_GetCardState(&hmmc2); if(State == HAL_MMC_CARD_TRANSFER) { HAL_MMC_GetCardCID(&hmmc2,&SD_CardCID); *block_num = hmmc2.MmcCard.BlockNbr; *block_size = hmmc2.MmcCard.BlockSize; return (USBD_OK); } else while(1); /* USER CODE END 3 */ }
判断 U 盘状态函数:
/** * @brief . * @param lun: . * @retval USBD_OK if all operations are OK else USBD_FAIL */ int8_t STORAGE_IsReady_FS(uint8_t lun) { /* USER CODE BEGIN 4 */ uint8_t state = 0; state = HAL_MMC_GetState(&hmmc2) ; if(HAL_MMC_STATE_READY != state) { return USBD_FAIL ; } return (USBD_OK); /* USER CODE END 4 */ }
U 盘读数据函数:
/** * @brief . * @param lun: . * @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 */ if(HAL_OK != HAL_MMC_ReadBlocks(&hmmc2,(uint8_t *)buf, blk_addr , blk_len, 1000)) { return USBD_FAIL ; } return (USBD_OK); /* USER CODE END 6 */ }
U 盘写数据函数:
/** * @brief . * @param lun: . * @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 */ if(HAL_OK != HAL_MMC_WriteBlocks(&hmmc2, (uint8_t *)buf, blk_addr , blk_len, 1000)) { return USBD_FAIL ; } return (USBD_OK); /* USER CODE END 7 */ }
修改完之后就可以编译下载了,连接 USB 线至 PC,可以看到电脑弹出了 U 盘符号。此时,会询问是否格式化的弹窗:

选择是,格式化时间大约 20 秒(4G),具体由 eMMC 的大小决定。
最后,就可以直接往 U 盘读写文件了,目前测试的速度只有 400KB 左右,速度待优化。

附件仅博主测试所用,暂不提供下载
扫码关注尚为网微信公众号

每天学习电路设计和嵌入式系统的专业知识,关注一波,没准就用上了。
原创文章,作者:sunev,如若转载,请注明出处:https://www.sunev.cn/embedded/938.html