Hangups when lower priority ISRs are enabled

pbleyer wrote on Saturday, July 28, 2012:


Are there any restrictions when using interrupts that have a priority lower than configKERNEL_INTERRUPT_PRIORITY, besides that they can’t call FreeRTOS functions?

For a particular reason, I am attempting to run my USB ISR on a Cortex-M3 device with a priority lower than the kernel, but I am getting HardFaults after a while when my tasks call vTaskDelay. I am almost certain that my USB ISR is not calling any FreeRTOS API functions. The crashes even happen if the ISR executes doing nothing at all (just returning). If I raise the USB IRQ priority to that of the kernel, then the code resumes normal functionality without crashing, so I am assuming there are no issues with the interrupt configuration itself.

Any advice is appreciated. Thanks.

davedoors wrote on Saturday, July 28, 2012:

Almost the first sentence on the section about configKERNEL_INTERRUPT_PRIORITY on this page http://www.freertos.org/a00110.html is “configKERNEL_INTERRUPT_PRIORITY should be set to the lowest priority.” although I cant know for sure why that is.

pbleyer wrote on Saturday, July 28, 2012:

Hi davedoors. Thank you for your reply.

Yes, saw that but unfortunately it is not clear what context is implied in the statement - if it refers to FreeRTOS or the complete system environment. I am assuming that if the kernel runs at a priority higher than other orthogonal ISRs in the system, they won’t affect when the kernel interrupts execute in a nested fashion. In fact, that is the main purpose of nested interrupts.

I am still debugging the system to get more insight on what is happening.

pbleyer wrote on Tuesday, August 14, 2012:

I have had some time this week to continue looking into the issue.

The fault happens when vTaskDelay tries to yield back calling portYIELD_WITHIN_API(), which causes a PendSV interrupt to be sent to perform the context switch. Since there is a lower level priority interrupt pending and the kernel is not aware of this, the environment is not restored and the PC is loaded from and invalid stack and thus the HardFault happens with the FORCED flag and INVPC flags set in the HFSR and CFSR registers, respectively.

It seems that the instruction that the kernel must be run at the lowest priority of the *full* system (ie including handlers that don’t call the API) is true, since vPortYieldFromISR is not expecting that the kernel interrupt is running nested within a lower priority handler.

I am still trying to figure out if a clean fix is possible.