EnterCritical and volatile

I just wanted to make sure that the enter critical is only relevant when a variable is accessed/changed by ISR and not when it is accessed/changed by other tasks. That is because - when doing context switching - freeRTOS takes care of completing any variables reading/mods that are not atomic in order to save a “stable” value to the stack before the context switch.

Is that correct?

Or does the freeRTOS scheduler, being obviously controlled by interrupt/s, just switches regardless of where it is including if it is in the middle of changing a variable of size different than the platform basic type/width?

Also, and kid of related… in cases where a variable can be changed by multiple tasks does volatile need to be used?

Thank you

Sorry, that is not correct.
If FreeRTOS is configured for preemptive multitasking, the switch occurs on an interrupt. The interrupt can occur at any point in the update of a variable including a partial update.
The possibility of a partial update depends heavily upon the data type of the variable and the CPU architecture you are using but the partial updates can happen in ways that you were not expecting.

If you want to be sure that your variable is being read while its data is valid you must either wrap that variable with a mutex or use taskENTER_CRITICAL and taskEXIT_CRITICAL to prevent interrupts and context switches while the update is happening.

For added fun and practice with critical sections play deadlock empire

It’s the sole purpose of a preemptive scheduler to preempt an executing thread or task at any point. There is no magic completion of some actions or code of the task which is preempted. The scheduler isn’t and can’t be aware of the meaning of the code which was currently executed on preemption.
Be warned that you should know exactly what you’re doing when sharing task stack variables e.g. by sending their address/pointer to another task.
Better start with sharing global variables. Even better avoid it :wink:
Please see the C/C++ standard or the net for the definition and meaning of the C/C++ keyword volatile.
Simple resp. CPU native variables (e.g. a 32 bit integer on a 32 bit MCU) can be shared atomically by declaring them volatile (read: this variable might get changed from outside the current code known to the compiler).
On the other hand there are atomic standard data types provided by recent compilers supporting newer C/C++ standards (C/C++11).
Complex data structures a might be protected by mutexes or critical sections. That’s their purpose and the reason why every multitasking OS comes with mutexes and often with critical sections.