Since taskYIELD can be called from outside critical section, and since taskYIELD typically calls vTaskSwitchContext, then vTaskSwitchContext may end up being called from outside critical section.
This appears to be the case in the GCC ATMega323 port, for example (cf. below).
Could you explain if it's OK for vTaskSwitchContext to occur outside critical section?
Regards.
~~~~ void vPortYield( void ) attribute ( ( naked ) ); void vPortYield( void ) { portSAVECONTEXT(); vTaskSwitchContext(); portRESTORECONTEXT();
asm volatile ( "ret" );
} ~~~~
This is a VERY old thread and VERY specific to the FreeRTOS port. In the AVR portSAVE_CONTEXT() disables interrupts so vTaskSwitchContext() is protected.
OK, I see that interrupts are disabled at the beginning of portSAVE_CONTEXT (cli instruction, I guess).
So in general ports, interrupts should be (re)disabled around start of vPortYield, and not assume that they are already disabled?
Each port has a different mechanism for yielding to a different task, and each case has to be considered on its own.
More often than not, yielding is done using a standard or software interrupt, in which cases the hardware will either itself disable interrupts on interrupt entry, or otherwise the interrupt priority mechanism and/or asm code is used to manage interrupt nesting to ensure the context switch can occur cleanly.
Also, some ports can/must yield in a critical section and the RTOS must save/restore the critical section nesting as part of the task context, while other ports (Cortex-M and RX for example) can't possibly yield from a critical section.
You are looking at a very basic port (as its a basic microcontroller), in which yielding is performed using a function call, and in that case interrupts are disabled manually. This is not really a critical section - the RTOS manages the yield, so is responsible for ensuring interrupts are left in the correct state when a task starts to run.