Usage Fault (hard fault) within portYIELD_WITHIN_API

adiman1984 wrote on Monday, August 15, 2016:

I’ve been having some weird hard faults (usage faults) with a freeRTOS project running on an STM32F405 processor. I’m using GCC with Eclipse.

The issue I’m seeing is that I get a hard fault when a tasks blocks (queue, delay, etc.) and there is nothing else to run. I verified that my main task runs and then blocks on a queue, which then causes a contect switch to a lower-priority task. If this lower-priority task encounters a delay (vTaskDelay) or blocks on a semaphore, or queue, I get a hard fault. I even tried removing everything else and only run a single task with an empty structure and a time delay (vTaskDelay). Again, as soon as the delay is encountered, it fails.

I found that the exception occurs in the portYIELD_WITHIN_API function, specifially at the assembly line “dsb sy”. The link register points to the end of the xTaskResumeAll() function, which doesn’t really make sense to me…

I have configASSERT defined, stack overflow checking is turned on (2), system clock is propperly setup and is correct (verified), the systick ISR fires, and there isn’t an interrupt priority issue (no other ISRs active and no API calls from ISRs).

Any ideas what could cause this? Are there any specific initializations that are needed for the STM32F4 processors and/or the associated peripherals that I’m not aware of? I’ve been using freeRTOS successfully for 2 years on TI’s Tiva microcontrollers, which have a Cortex-M4 processor as well, so I’m well aware of all the pitfals of freeRTOS on ARM M4.

Any help would be greatly appreciated.

richard_damon wrote on Tuesday, August 16, 2016:

If nothing else is ready to run, then the idle task should run. Could you have code in an idle hook that blocks (that is a no-no), or perhaps the creation of the idle task failed.

adiman1984 wrote on Thursday, August 18, 2016:

Ok, did some verification and the idle task is successfully created and is NOT the problem.

Digging into this a bit deeper showed that I had an issue with interrupt priorities (yes, Richard Barry is right with his statement that almost all issues are related to interrupt priorities). Although I ported my code from another Cortex M4 project, it was using a different driver library and so the priorities in FreeRTOSConfig.h were wrong. Once I fixed this it started working.

While I do understand the issue with the interrupt priorities, I do not understand why it worked for a while. I did see context switches, systick interrupts, etc. There were NO other interrupts in my system except for the three that freeRTOS uses (SVCall, SysTick, and PendSV). The hard fault ALWAYS occurred when there was NOTHING else ready to run (except for the idle task).

In particular, I’m really curious why the hard fault occurred when executing the data synchronization barrier (DSB SY) command. If someone cares to explain how this is sensitive to interrupt priorities, I would be very interested.