stuartbrown wrote on Tuesday, March 20, 2018:
Hi
I’m in need of some help. I have a FreeRTOS project generated from CubeMX (v4.25.0) targetting a STM32L432. The project is generated for, compiler in and debugged in Atollic TrueStudio, so the tool chain is gcc. When I compile with optimisation level -O2 or -O3 I get hard faults in xQueueGenericReceive() . If I use other levels (-O0, -O1, -Og, -Os, -Of) then it runs fine.
According to the fault analyser in Atollic True Studio, the PC when the hard fault occurs is on this line in queue.c, function xQueueGenericReceive(),
for( ;; )
{
taskENTER_CRITICAL();
{
const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; <--- HARD FAULT HERE
`
I have a screenshot of the disassembly from the Atollic Fault Analyser here , showing the error location to be the following instruction
ldr r6, [r4, #56]
This causes a precise bus fault because r4 contains address 0x32000, so the instruction is trying to access address 0x320038.
I have spent the last few days reading about hardfaults and debugging. But I’m still a bit lost, being new to STM32. I have followed the advice on the FreeRTOS site about Cortex M3/4 processors and interrupt priority and debugging hard faults.
I have config assert defined:
#define configASSERT( x ) if ((x) == 0) { taskDISABLE_INTERRUPTS(); __asm volatile("BKPT #01"); for( ;; ); }
My interrupt config is generated by CubeMX as follows:
#define configPRIO_BITS 4
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
My application is not using any interupts. It is configured without premption, and has 3 tasks that wait on a FreeRTOS queue, blocking indefinitely till there is something to process. The 3 tasks are
- An application task running a state machine. It waits on a queue that contains state machine events.
- A message processing task for handling communications from a PC application. The PC app is not being used when the fault occurs, so this task is simply blocked.
- And finally a task processing bytes from the GPS UART. This is running when the fault occurs. The GPS UART is configured for DMA to a circular buffer, and the buffer is emptied in the idle task hook, where all bytes are read out and pushed into the FreeRTOS queue.
There are 2 timers running, their callbacks push timer expired events into the state machine queue. The state machine logic will start the timers as approriate.
At the time of the hard fault, the application task (HSM) is spinning in a loop waiting for GPS fix, it checks the fix flag and if there is no fix it calls vTaskDelay(). It seems that the error is somehow related to this delay causing a context swtich. The same happens if I replace the delay with a taskYIELD().
Please can someone help me debug this further? I’m really stuck
thanks
Stuart