Skip to main content
October 13, 2022
Question

USBH_MSC_Read Problem is Stuck in while Loop?

  • October 13, 2022
  • 1 reply
  • 2219 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

Gianluca Costa
Associate 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: