I’d like to describe a bad scenario we encountered during our project using the uxCriticalNesting variable. In our design, we use Cortex-M3 and the free RTOS version is v7.1.0.
In the enter critical section function called in a task, the first instruction executed is a DISABLE interrupts. In our case, a higher priority interrupt occured just right after the disable interrupt instruction. In the interrupt handler, an enter and exit critical section was called. In the exit critical section from the handler, the interrupts were enabled again because the nesting counter was set to 1.
When the handler interrupt completed, it returns in the critical section in the task with nesting counter to 0 and** interrupt enabled**… So, the next instruction is the nesting counter increment to 1 and sometimes a switch context can occur in this critical section. In another task, if an other critical section is called, disable interrupt instruction is called and the nesting counter set to 2, and when exit critical section function is called, the nesting decrements to 1 and the interrupts remains disabled.
The task will not be interrupted by other task and the system is still frozen for ever!
An other situation, if higher interrupt priority occurs in a critical section, we called xSemaphoreGiveFromISR(). In that function, we noticed that it enables the interrupts. So, we can provoke context switch in the task’s critical section area and maybe corrupt the protected resource.
In brief, the FreeRTOS configMAX_SYSCALL_INTERRUPT_PRIORITY is actually set to 191. We can see in that case higher priority can break our system.
Is there any document available to be aware about some rules about critical section? It’s hard to reproduce the problem, but it can happen!