STM32H7 hard faults in FreeRTOS when connecting USB mouse

Hello All,

We’ve been struggling with getting hard faults originating in FreeRTOS generated code, but triggered by initialization of a USB optical mouse.

Environment:
MCU STM32H7B3NIHx
STM32CubeMX 6.8.1
IAR EW IDE 8.50.9
FreeRTOS 10.3.1
CMSIS 2.00

We decided to start from scratch with a new STM32CubeMX project with nothing enabled but UBS_HS_OTG and USB_Host. The application ran great and mouse actions were accurately received. When FreeRTOS was enabled a hard fault was generated when the mouse was plugged in.

Stack Trace:
HardFault_Handler

uxListRemove
xTaskRemoveFromEventList
xQueueGenericSendFromISR
osMessageQueuePut
USBH_LL_PortEnabled
HAL_HCD_PortEnabled_Callback
HCD_Port_IRQHandler
HAL_HCD_IRQHandler
OTG_HS_IRQHandler

HAL_GetTick
HAL_Delay
USB_ResetPort
HAL_HCD_ResetPort
USBH_LL_ResetPort
USBH_Process
USBH_Process_OS
prvTaskExitError

There is very little custom code involved here, and execution doesn’t make it past USB device initialization, so my code never runs. This is all USB_Host_Library and FreeRTOS generated code. Please advise as to next steps or things to try.

Thanks!
Doug

Hi Doug,

What is the USB interrupt priority? And how does that compare to configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY (defined in FreeRTOSConfig.h)?

Other things to check:

  • Is configASSERT() defined? During development, it should be.
  • Is configCHECK_FOR_STACK_OVERFLOW set to 2?

Hi Jeff,

Thanks for the input. As far as the USB interrupt priority, I found this in usbh_conf.h:
'#define USBH_PROCESS_PRIO osPriorityNormal

In the priority enumeration osPriorityNormal is valued at 24. Is this the priority you’re asking about? The other settings you asked about are below. I will change configCHECK_FOR_STACK_OVERFLOW to 2 and retest.

#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
#define configCHECK_FOR_STACK_OVERFLOW 0

Thanks again,
Doug

Hi Doug, the interrupt priority I was asking about is for the USB_OTG_HS device, not the task priority for the USB task USBH_Process_OS(). You could search the codebase for a call to NVIC_SetPriority() for OTG_HS_IRQn I think, probably in usbd_conf.c. That’s where you’ll find the interrupt priority. However, the good news is you have configASSERT() defined well, and you are using kernel v10+, so if your interrupt priority was too high, FreeRTOS would have asserted to tell you about the configuration error. So you probably don’t have an interrupt-priority issue.

Hopefully turning on stack-overflow detection will find the issue.

A couple more ideas for you in the meantime:

  • Data corruption on the main stack. Do you have any variables or data structures declared in the scope of main(), and are those variables used after FreeRTOS starts? This is forbidden. See FAQ #3 on this page.
  • Main stack overflow. The kernel doesn’t detect main-stack overflow, no matter how you set configCHECK_FOR_STACK_OVERFLOW. The “main stack” is used during interrupt handling. It seems ST’s USB software operates primarily from within interrupt handlers. It may be using too much stack for your config. You can look at your linker map file to see how much space (if any) is actually being reserved for the main stack. It’s possible the linker file depends on luck.
1 Like

Hi Jeff,

I found the call you were asking about:
HAL_NVIC_SetPriority(OTG_HS_IRQn, 5, 0);
So it looks like it’s set the same as configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY.

Good news is that turning on stack overflow protection showed that the USBH_Queue was overflowing. Increasing the stack size corrected the problem. No more hard fault. I just need to tinker with it to find out how much stack space we actually need.

Thanks so much!
Doug

1 Like

Thank you for taking the time to report back and mark a solution :slight_smile: