Skip to main content
Visitor II
October 13, 2022
Question

USBH_MSC_Read Problem is Stuck in while Loop?

  • October 13, 2022
  • 1 reply
  • 1595 views

Hello

USBH_MSC_Read function uses a while loop and USBH_MSC_RdWrProcess to USB mass storage.

  

while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
 {
 if (((phost->Timer - timeout) > (10000U * length)) || (phost->device.is_connected == 0U) )
 {
 MSC_Handle->state = MSC_IDLE;
 return USBH_FAIL;
 }
 }
 MSC_Handle->state = MSC_IDLE;

This part of the blocks the application for more than 3 or 4 seconds in some usb mass storages

I investigated the USB_MSC_Bot process and it was understood that most of the time in USBH_MSC_BOT_Process in the BOT_DATA_IN_WAIT

application URB_Status is equal to USBH_URB_NOTREADY which is not handled in the BOT_DATA_IN_WAIT

I used a counter until the end of USBH_MSC_Read and USBH_URB_NOTREADY was counted for 45000 time until the loop ended

I have searched most of the post related to this issue but most of them were unanswered and no useful fix was released

 #USB​ 

#STM32F7​ 

#STM32F4​ ​ 

    This topic has been closed for replies.

    1 reply

    Visitor II
    October 18, 2022

    Hi,

    if it is an F7 and you are using FW_F7 V1.17.0 try to set 1025 as USBH_MAX_DATA_BUFFER from Cubemx (USB_HOST->Parameter Setting).

    Give me a feedback if it works. Thanks.

    Ciao.

    October 23, 2022
    USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
     uint8_t lun,
     uint32_t address,
     uint8_t *pbuf,
     uint32_t length)
    {
     uint32_t timeout;
     
     /*****************************************************************************
     * @brief :ExtTimeout variable controls a dynamic timeout for USB USBH_MSC_RdWrProcess
     * @note : Hanging in this while loop will occur in the event of Slow USB 
     * @note : Hanging in this while loop will occur in the event of EMI problems 
     * Maximum Timeout = USB_MSC_READ_TIMEOUT_MAX
     * Timeout Step = USB_MSC_READ_TIMEOUT_STEP
     * Defualt Timeout = USB_MSC_READ_TIMEOUT
     ****************************************************************************/
     static uint32_t ExtTimeout = USB_MSC_READ_TIMEOUT ;
     USBH_StatusTypeDef USB_RdStatus = USBH_BUSY;
     MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
     
     if ((phost->device.is_connected == 0U) ||
     (phost->gState != HOST_CLASS) ||
     (MSC_Handle->unit[lun].state != MSC_IDLE))
     {
     return USBH_FAIL;
     }
     
     MSC_Handle->state = MSC_READ;
     MSC_Handle->unit[lun].state = MSC_READ;
     MSC_Handle->rw_lun = lun;
     
     (void)USBH_MSC_SCSI_Read(phost, lun, address, pbuf, length);
     
     timeout = phost->Timer;
     
     //=================================
     // Add For prevent infinity loop
     uint32_t tickstart = HAL_GetTick();
     
     do
     {
     USB_RdStatus = USBH_MSC_RdWrProcess(phost, lun);
     if ( USB_RdStatus == USBH_FAIL)
     {
     MSC_Handle->state = MSC_IDLE;
     ExtTimeout =USB_MSC_READ_TIMEOUT;
     return USBH_FAIL;
     }
     if (((phost->Timer - timeout) > (10000U * length)) || (phost->device.is_connected == 0U) || ((HAL_GetTick() - tickstart) > ExtTimeout) )
     {
     if ( ExtTimeout < USB_MSC_READ_TIMEOUT_MAX )
     {
     ExtTimeout = ExtTimeout + USB_MSC_READ_TIMEOUT_STEP;
     }
     else
     {
     ExtTimeout =USB_MSC_READ_TIMEOUT;
     }
     MSC_Handle->state = MSC_IDLE;
     return USBH_FAIL;
     }
     }
     while(USB_RdStatus == USBH_BUSY);
     ExtTimeout =USB_MSC_READ_TIMEOUT;
     MSC_Handle->state = MSC_IDLE;
     
     return USBH_OK;
     
    // while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
    // {
    // if (((phost->Timer - timeout) > (10000U * length)) || (phost->device.is_connected == 0U) || ((HAL_GetTick() - tickstart) > ExtTimeout) )
    // {
    // if ( ExtTimeout < USB_MSC_READ_TIMEOUT_MAX )
    // {
    // ExtTimeout = ExtTimeout + USB_MSC_READ_TIMEOUT_STEP;
    // }
    // else
    // {
    // ExtTimeout =USB_MSC_READ_TIMEOUT;
    // }
    // MSC_Handle->state = MSC_IDLE;
    // return USBH_FAIL;
    // }
    // }
     
    }

    Thanks for your response I have set

    USBH_MAX_DATA_BUFFER = 1025

    and it did not have any effect on this issue.

    I have spent a little time and developed a dynamic timeout for this part of the code.

    But it only helps

    It is not a solid solution. This is my modified code: