In a freeRT0S project created with Stm32cubemX (freeRTOS v. 9.0.0 CMSIS-RTOS v.1.02) my program gives a hardfault when the following line is called from my one and only task (created with priority osPriorityNormal:
However, if I call the exact same function with the same parameters before the task is started then it returns normally.
The call stack only shows PendSV_Handler before the hard fault.
I implemented the prvGetRegistersFromStack to copy the registers, but I’m struggling to understand what I’m looking at. $pc just gives the address of the line prvGetRegistersFromStack.
The project was generated with cubemx with mostly default values for freeRTOS. I have read the warning about interrupt levels and I don’t it applies here since I have only started one task and aren’t calling any freeRTOS functions from ISR.
There is also some SPI DMA going on in the background, but I don’t believe the issue is related to this.
If I don’t call the arm_cfft_f32 funtion, the program appears to continue working just fine.
I’d be grateful for any ideas of where to start looking.
So just to eliminate any other cause, I created a new Cubemx project with only freeRTOS (so no DMA etc.) and addded in the FFT function to a single task.
Again, the FFT function completes normally if called outside the task (before the task is started). If called inside the task then I again get a hard fault at xPortPendSVHandler.
The timebase source is TIM7 this time. Last time it was TIM1.
So I put a breakpoint in vApplicationStackOverflowHook() and I end up there. So it looks like I’ve got some stack overflow. Thanks for helping me narrow it down somewhat. I have no idea what’s causing the stack overflow, though!
__weak void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName)
{
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is
called if a stack overflow is detected. */
asm("bkpt 255");
}
Out of desperation I increased the configMINIMAL_STACK_SIZE from 128 to 2048 and I no longer get the hard fault. I’m confused, though. I thought this stack size was for the idle task which is doing nothing in my case. I wonder whether it’s just kicking the problem down the road, though.
First, set configCHECK_FOR_STACK_OVERFLOW to 2, not 1, it is then much
more reliable.
configMINIMAL_STACK_SIZE is only used by the kernel to dimension
the size of the stack used by the Idle task, but lots of the standard
demo tasks use the same constant to make them portable across multiple
architectures.