STM32F4 hard fault when calling arm_cfft_f32 from a task

wonkowill wrote on Wednesday, February 13, 2019:

Hello.

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:

arm_cfft_f32(&arm_cfft_sR_f32_len2048, SampleBufferFloat, ifftFlag, doBitReverse);

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.

Many thanks.

wonkowill wrote on Wednesday, February 13, 2019:

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.

rtel wrote on Wednesday, February 13, 2019:

Starting with the basics - do you have configASSERT() defined (with the latest version of FreeRTOS, which contains many more asserts()), and do you have stack overflow detection turned on? https://www.freertos.org/Stacks-and-stack-overflow-checking.html

wonkowill wrote on Wednesday, February 13, 2019:

Hi. Yes, I have the following defined:

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

#define configCHECK_FOR_STACK_OVERFLOW 1

I’m using the latest available version of CubeMX. I see that there is a v10 of freeRTOS. I will attempt to install it over the CubeMx version.

wonkowill wrote on Wednesday, February 13, 2019:

I installed the latest version. No change other than now in the call stack I have a call to vTaskSwitchContext visible below PendSV_Handler.

When I go to it, it’s taskCHECK_FOR_STACK_OVERFLOW(); I’m not sure how to interpret this.

wonkowill wrote on Wednesday, February 13, 2019:

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");
}

wonkowill wrote on Wednesday, February 13, 2019:

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.

rtel wrote on Wednesday, February 13, 2019:

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.