Macro to mark the start of a critical code region. Preemptive context
Must ulCriticalNesting be context-switched?
A couple questions related to critical sections and ulCriticalNesting, w.r.t. FreeRTOS 8.1.x specifically:
1)
task.h’s documentation for taskENTER_CRITICAL states:
Macro to mark the start of a critical code region. Preemptive context
Macro to mark the start of a critical code region. Preemptive context
Must ulCriticalNesting be context-switched?
[Which architecture did you port to? Have you uploaded your port to the FreeRTOS Interactive site?]
There is no one answer – it is completely dependent on the port. Different CPU architectures have different characteristics, features and restrictions, so the port works with what the architecture happens to provide.
Generally, older or simpler architectures will context switch the critical nesting count because they do context switch from within a yield in some synchronous way (trap, function call, whatever) – where ever that yield is made. Newer or more complex architectures will often use an asynchronous pended interrupt (or software pend) which means they will not context switch from within a critical section, but will context switch immediately that a critical section is exited if the context switch is pending at that time. When a context switch cannot occur in a critical section there is no point saving the nesting depth as part of the task’s context.
The core (non portable layer) FreeRTOS code is written to function correctly either way.
Back to your first question – a preemptive context switch is any context switch that is not requested directly by a task – in other words, any context switch that the task cannot predict is going to happen (hence the task is preemptive). Any interrupt can cause that, not just a timer interrupt.
Regards.
Must ulCriticalNesting be context-switched?
I’m running on both an ARM7TDMI and an ARM Cortex R5 with different ports. The ports aren’t uploaded to the FreeRTOS interactive site at present; that would require some negotiations with lawyers which hasn’t happened yet; we’re not distributing the ports outside the organization in either source or binary form at present.
In the port I made, portYIELD maps to a SWI/SVC instruction; a synchronous exception. FWIW, IIRC I based this port on Source/portable/GCC/ARM7_AT91FR40008 simply because that was the first GCC-based port in the directory listing! It sounds like in this case, ulCriticalNesting must be context-switched, since yielding is immediate.
I assume you’ll tell me that in the ARM Cortex R4 port I mentioned (Source/portable/CCS/ARM_Cortex-R4/), yielding is implemented by a SW interrupt (that is masked inside a critical section) rather than an exception, hence the switch is deferred until after the critical section is executed?
Must ulCriticalNesting be context-switched?
You would actually be better off copying the FreeRTOS/Source/portable/GCC/ARM_CA9 code, maybe barring the interrupt controller code in that port (which may or may not be ok for your chip depending on whether it is using a GIC or not).
Regards.