Skip to main content
Visitor II
September 17, 2024
Solved

USBX Device MSC in Standalone mode

  • September 17, 2024
  • 2 replies
  • 4444 views

I'm trying to get USBX Device MSC to work in Standalone mode (without RTOS).  I loosely followed @B.Montanari 's example in https://community.st.com/t5/stm32-mcus/how-to-implement-usbx-in-standalone-mode/ta-p/614435, and also referred to a CubeMX example for Device MSC which does use an RTOS (STM32Cube_FW_U5_V1.6.0\Projects\STM32U575I-EV\Applications\USBX\Ux_Device_MSC).  I'm running this on an STM32U5 dev kit.

There are no errors, Windows recognizes the USB MSC device, and a drive shows up.  But something isn't working quite right, since Windows tells me to insert a disk, won't format the volume, and doesn't seem to recognize its size.

I'm not quite sure yet where things are going wrong, but I thought I'd see if this configuration is expected to work or if I'm overlooking any other examples before digging further...

    This topic has been closed for replies.
    Best answer by PRuss

    This was apparently caused by a bug in the USBX source.  Once I fixed it, things seem to be working.

    It looks like _ux_device_class_storage_disk_wait just passes the return value of ux_slave_class_storage_media_read (and other similar functions) directly to _ux_device_class_storage_task_disk.  Here this return value is compared against UX_STATE_NEXT to check for success.  

    However, comparing some additional samples and other places in the code, ux_slave_class_storage_media_read is expected to return UX_SUCCESS if successful.

    BTW, while debugging through the code I also found a couple of bugs in _ux_utility_debug_log (as-is it won't even compile with the UX_ENABLE_DEBUG_LOG switch).

     

    This makes me wonder whether Standalone mode and other non-mainstream features are getting much use or test time.

    2 replies

    Technical Moderator
    September 17, 2024

    Hello @PRuss ,

    Try to increase the heap size or configure the USB library to use static allocation as recommended in this FAQ: USB device not recognized.

    PRussAuthor
    Visitor II
    September 20, 2024

    Thanks for the reply.  I did increase both the heap and stack significantly, but I'm still having the same issue.

    Explorer
    January 16, 2025

    Hello @PRuss 

    I'm also trying to get USBX MSC to work in standalone mode for one of my projects. However, I can't get it to work. In my main loop, I call the ux_device_stack_tasks_run function, which allows me to detect my device when I plug it into Windows. 

     /* USER CODE BEGIN WHILE */
     while (1)
     {
     /* USER CODE END WHILE */
    
     /* USER CODE BEGIN 3 */
     ux_device_stack_tasks_run();
     //_ux_device_class_storage_tasks_run(storage);
     }
     /* USER CODE END 3 */
    UINT MX_USBX_Device_Init(VOID)
    {
     UINT ret = UX_SUCCESS;
     UCHAR *device_framework_high_speed;
     UCHAR *device_framework_full_speed;
     ULONG device_framework_hs_length;
     ULONG device_framework_fs_length;
     ULONG string_framework_length;
     ULONG language_id_framework_length;
     UCHAR *string_framework;
     UCHAR *language_id_framework;
    
     UCHAR *pointer;
    
     /* USER CODE BEGIN MX_USBX_Device_Init0 */
    
     /* USER CODE END MX_USBX_Device_Init0 */
     pointer = ux_device_byte_pool_buffer;
    
     /* Initialize USBX Memory */
     if (ux_system_initialize(pointer, USBX_DEVICE_MEMORY_STACK_SIZE, UX_NULL, 0) != UX_SUCCESS)
     {
     /* USER CODE BEGIN USBX_SYSTEM_INITIALIZE_ERROR */
     return UX_ERROR;
     /* USER CODE END USBX_SYSTEM_INITIALIZE_ERROR */
     }
    
     /* Get Device Framework High Speed and get the length */
     device_framework_high_speed = USBD_Get_Device_Framework_Speed(USBD_HIGH_SPEED,
     &device_framework_hs_length);
    
     /* Get Device Framework Full Speed and get the length */
     device_framework_full_speed = USBD_Get_Device_Framework_Speed(USBD_FULL_SPEED,
     &device_framework_fs_length);
    
     /* Get String Framework and get the length */
     string_framework = USBD_Get_String_Framework(&string_framework_length);
    
     /* Get Language Id Framework and get the length */
     language_id_framework = USBD_Get_Language_Id_Framework(&language_id_framework_length);
    
     /* Install the device portion of USBX */
     if (ux_device_stack_initialize(device_framework_high_speed,
     device_framework_hs_length,
     device_framework_full_speed,
     device_framework_fs_length,
     string_framework,
     string_framework_length,
     language_id_framework,
     language_id_framework_length,
     UX_NULL) != UX_SUCCESS)
     {
     /* USER CODE BEGIN USBX_DEVICE_INITIALIZE_ERROR */
     return UX_ERROR;
     /* USER CODE END USBX_DEVICE_INITIALIZE_ERROR */
     }
    
     /* Initialize the storage class parameters for the device */
     storage_parameter.ux_slave_class_storage_instance_activate = USBD_STORAGE_Activate;
     storage_parameter.ux_slave_class_storage_instance_deactivate = USBD_STORAGE_Deactivate;
    
     /* Store the number of LUN in this device storage instance */
     storage_parameter.ux_slave_class_storage_parameter_number_lun = STORAGE_NUMBER_LUN;
    
     /* Initialize the storage class parameters for reading/writing to the Flash Disk */
     storage_parameter.ux_slave_class_storage_parameter_lun[0].
     ux_slave_class_storage_media_last_lba = USBD_STORAGE_GetMediaLastLba();
    
     storage_parameter.ux_slave_class_storage_parameter_lun[0].
     ux_slave_class_storage_media_block_length = USBD_STORAGE_GetMediaBlocklength();
    
     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 = STORAGE_REMOVABLE_FLAG;
    
     storage_parameter.ux_slave_class_storage_parameter_lun[0].
     ux_slave_class_storage_media_read_only_flag = STORAGE_READ_ONLY;
    
     storage_parameter.ux_slave_class_storage_parameter_lun[0].
     ux_slave_class_storage_media_read = USBD_STORAGE_Read;
    
     storage_parameter.ux_slave_class_storage_parameter_lun[0].
     ux_slave_class_storage_media_write = USBD_STORAGE_Write;
    
     storage_parameter.ux_slave_class_storage_parameter_lun[0].
     ux_slave_class_storage_media_flush = USBD_STORAGE_Flush;
    
     storage_parameter.ux_slave_class_storage_parameter_lun[0].
     ux_slave_class_storage_media_status = USBD_STORAGE_Status;
    
     storage_parameter.ux_slave_class_storage_parameter_lun[0].
     ux_slave_class_storage_media_notification = USBD_STORAGE_Notification;
    
     /* USER CODE BEGIN STORAGE_PARAMETER */
    
     /* USER CODE END STORAGE_PARAMETER */
    
     /* Get storage configuration number */
     storage_configuration_number = USBD_Get_Configuration_Number(CLASS_TYPE_MSC, 0);
    
     /* Find storage interface number */
     storage_interface_number = USBD_Get_Interface_Number(CLASS_TYPE_MSC, 0);
    
     /* Initialize the device storage class */
     if (ux_device_stack_class_register(_ux_system_slave_class_storage_name,
     ux_device_class_storage_entry,
     storage_configuration_number,
     storage_interface_number,
     &storage_parameter) != UX_SUCCESS)
     {
     /* USER CODE BEGIN USBX_DEVICE_STORAGE_REGISTER_ERROR */
     return UX_ERROR;
     /* USER CODE END USBX_DEVICE_STORAGE_REGISTER_ERROR */
     }
    
     /* USER CODE BEGIN MX_USBX_Device_Init1 */
    
     /* Initialize the USB Peripheral */
     MX_USB_OTG_FS_PCD_Init();
    
     HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);
     HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, USBD_MAX_EP0_SIZE / 4);
     HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, USBD_MSC_EPIN_FS_MPS / 2);
     /* Link the USB drivers with the USBX DCD and check if it return error */
     if(ux_dcd_stm32_initialize((ULONG)USB_OTG_FS, (ULONG)&hpcd_USB_OTG_FS) != UX_SUCCESS)
    
     {
     Error_Handler();
     }
     if(ux_dcd_stm32_initialize((ULONG)USB_OTG_FS, (ULONG)&hpcd_USB_OTG_FS) != UX_SUCCESS)
     {
     Error_Handler();
     }
     /* Start the PCD Peripheral */
     HAL_PCD_Start(&hpcd_USB_OTG_FS);
     /* USER CODE END MX_USBX_Device_Init1 */
    
     return ret;
    }

    However, I never get as far as the USBD_STORAGE_Read or USBD_STORAGE_Write functions. As far as I can see, this is because I don't call the _ux_device_class_storage_tasks_run function.
    If this is the problem, how can I retrieve the storage class instance?

    Thanks for your help