uxCriticalNesting keeps track of how many times we call enter critical, so that we enable interrupt when exiting the last critical section. Example:
taskENTER_CRITICAL()
taskENTER_CRITICAL()
taskEXIT_CRITICAL() // This call will NOT enable interrupts.
taskEXIT_CRITICAL() // This call will enable interrupts.
As you can see, uxCriticalNesting is initialized to a large value (0xaaaaaaaa). This means that the check if( uxCriticalNesting == 0 ) in exit critical will not be true and interrupts will not be enabled. In other words, a call to enter and exit critical will leave interrupts disabled.
At the time of scheduler start, we set uxCriticalNesting to 0 and enable interrupts so that enter/exit critical can work normally afterwards.
This is done to ensure that interrupts remain disabled from the time first FreeRTOS API is called (which internally calls enter/exit critical) till the time scheduler is started.
Thanks Gaurav for the effort - it does make sense how interrupts remain disabled as uxCriticalNesting is already large enough, which is set to 0 only once the scheduler starts.
I have Kernel V10.0.0 and I see the following though I canât find where uxCriticalNesting is set to 0xaaaaaaaa.
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so
assert() if it is being called from an interrupt context. Only API
functions that end in "FromISR" can be used in an interrupt. Only assert if
the critical nesting count is 1 to protect against recursive calls if the
assert function also uses a critical section. */
if ( uxCriticalNesting == 1 )
{
configASSERT( ( SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk ) == 0 );
}
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
configASSERT( uxCriticalNesting );
uxCriticalNesting--;
if ( uxCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
That isnât the version of uxCriticalNesting that the code would be using, since it is marked âstaticâ, such variables can only be used in the translation unit they are defined in.
port_cmsis sounds like a file that is part of the CMSIS wrapper layer provided by your vendor.
There will be another variable by that name declared in the FreeRTOS code, in the port.c for the processor that is part of the FreeRTOS code.