2024-12-13 07:39 AM - edited 2024-12-13 08:22 AM
I have a STM32H7 and I use USB MSC. I do not use an RTOS.
If I plug in my USB thumb drive I append a counter to a file and close it.
This works.
If I remove the thumb drive very quickly at precisely the wrong moment I get a hardfault.
if Appli_state == APPLICATION_READY I set a flag and call f_open in the main loop. But then the USB drive is already gone, but there is no NULL pointer check.
We call the USBH_Process() and USBH_MSC_AppProcess() in a timer interrupt and have modified it to have non-blocking delays. I wonder if this could be the cause or if there is an actual bug in the driver that misses to check the USB drive is not available.
The following modification made to USBH_MSC_RdWrProcess() fixes the problem of hardfaults.
static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_t lun)
{
USBH_StatusTypeDef error = USBH_BUSY;
USBH_StatusTypeDef scsi_status = USBH_BUSY;
if (phost->pActiveClass == NULL)
{
error = USBH_FAIL;
return error;
}
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
Edit: I found an old thread that mentions the same problem:
Another modification I made is to call an idle handler in busy waiting loops. This is not the cause of the issue, but it does address the issue mentioned by @NAgha.1 in that topic:
while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
{
if (((phost->Timer - timeout) > (10000U * length)) || (phost->device.PortEnabled == 0U))
{
return USBH_FAIL;
}
// start of modification
else
{
// prevent blocking other processes from main context
usbIdleLoop();
}
// end of modification
}
main:
void usbIdleLoop()
{
//does non-usb things
}
int main(){
...
while(1)
{
usbIdleLoop();
usbApplication();//does fat-fs things with usb and calls usbIdleLoop in loops that were previously busy waiting to prevent blocking
}
}