之前弄过一个USBX模拟U盘的循环卸载挂载的问题,供参考。
[C] 纯文本查看 复制代码 /*
*********************************************************************************************************
* 函 数 名: OpenUsbStorage
* 功能说明: 打开SD卡的U盘模拟
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
extern TX_SEMAPHORE transfer_semaphore;
extern VOID fx_stm32_sd_driver(FX_MEDIA *media_ptr);
extern uint32_t media_memory[8*1024];
void OpenUsbStorage(void)
{
static uint32_t uiFirstRun = 0;
UINT status = UX_SUCCESS;
ULONG device_framework_fs_length;
ULONG string_framework_length;
ULONG languge_id_framework_length;
UCHAR *device_framework_full_speed;
UCHAR *string_framework;
UCHAR *language_id_framework;
if(uiFirstRun == 0)
{
uiFirstRun = 1;
/* 初始化USBX */
ux_system_initialize(usbx_pool, USBX_MEMORY_SIZE, UX_NULL, 0);
}
/* USB设备协议栈初始化 */
device_framework_full_speed = USBD_Get_Device_Framework_Speed(FULL_SPEED, &device_framework_fs_length);
string_framework = USBD_Get_String_Framework(&string_framework_length);
language_id_framework = USBD_Get_Language_Id_Framework(&languge_id_framework_length);
status = _ux_device_stack_initialize(NULL,
0,
device_framework_full_speed,
device_framework_fs_length,
string_framework,
string_framework_length,
language_id_framework,
languge_id_framework_length, UX_NULL);
if (status != UX_SUCCESS)
{
return;
}
/* 初始化SD卡 */
BSP_SD_Init();
/* 1个USB模拟U盘设备 */
storage_parameter.ux_slave_class_storage_parameter_number_lun = 1;
/* 设置相关参数并注册读写API */
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_last_lba = (ULONG)(uSdHandle.SdCard.BlockNbr - 1);
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_block_length = uSdHandle.SdCard.BlockSize;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_type = 0;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_removable_flag = 0x80;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read = app_usb_device_thread_media_read;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write = app_usb_device_thread_media_write;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status = app_usb_device_thread_media_status;
/* 注册USB模U盘到接口0,配置1*/
status = _ux_device_stack_class_register(_ux_system_slave_class_storage_name, _ux_device_class_storage_entry, 1, 0, (VOID *)&storage_parameter);
if (status != UX_SUCCESS)
{
return;
}
/* 配置USB GPIO, NVIC */
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* 使能USB FS时钟 */
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
/* 配置USB FS中断 */
HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
}
/* 初始化USB */
{
memset(&hpcd_USB_OTG_FS, 0x0, sizeof(PCD_HandleTypeDef));
hpcd_USB_OTG_FS.Instance = USB_OTG_FS;
hpcd_USB_OTG_FS.Init.dev_endpoints = 4;
hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;
hpcd_USB_OTG_FS.Init.dma_enable = DISABLE;
hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE;
hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE;
hpcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE;
hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;
/* 初始化USB */
HAL_PCD_Init(&hpcd_USB_OTG_FS);
/* 设置TX FIFO和RX FIFO */
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 128);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 64);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 128);
/* 注册STM32到USBX协议栈并初始化 */
status = ux_dcd_stm32_initialize((ULONG)USB_OTG_FS, (ULONG)&hpcd_USB_OTG_FS);
if (status != FX_SUCCESS)
{
return;
}
}
/* 给SDIO DMA方式使用 */
tx_semaphore_create(&transfer_semaphore, "sdmmc dma transfer semaphore", 0);
/* 底层使用FileX API */
//fx_media_open(&sdio_disk, "STM32_SDIO_DISK", fx_stm32_sd_driver, 0, media_memory, sizeof(media_memory));
/* 启动USB */
HAL_PCD_Start(&hpcd_USB_OTG_FS);
}
/*
*********************************************************************************************************
* 函 数 名: CloseUsbStorage
* 功能说明: 关闭SD卡的U盘模拟
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void CloseUsbStorage(void)
{
/* 停止USB */
HAL_PCD_Stop(&hpcd_USB_OTG_FS);
/* 复位USB相关配置 */
_ux_dcd_stm32_uninitialize((ULONG)USB_OTG_FS, (ULONG)&hpcd_USB_OTG_FS);
_ux_device_stack_uninitialize();
_ux_device_stack_class_unregister(_ux_system_slave_class_storage_name, _ux_device_class_storage_entry);
/* 关闭USB时钟,中断,并复位SD卡 */
__HAL_RCC_USB_OTG_FS_CLK_DISABLE();
HAL_NVIC_DisableIRQ(OTG_FS_IRQn);
HAL_PCD_DeInit(&hpcd_USB_OTG_FS);
/* 给SDIO DMA方式使用 */
tx_semaphore_delete(&transfer_semaphore);
//fx_media_close(&sdio_disk);
BSP_SD_DeInit();
}
|