Volatile for variables from different tasks

Hi,
I always define a variable if it can be changed by the ISR because the compiler cannot predict if it changed.

But… what if:

  1. it is defined inside a task and NOT modified by an ISR but it can be modified by another task?
  2. what if it is Global would that change anything?
  3. What about if I already protected (when required) with inside taskENTER/EXIT_CRITICAL()?

Thank you as always :slight_smile:

If the variable might be changed by another thread needs something to force the compiler to spill the value to memory, and retrieve a new value from memory.

For the typical single core processor that FreeRTOS targets, volatile will suffice. It might not be good enough on a multi-core CPU or for DMA as volatile might not force a cache flush to transfer data between other masters.

If full program optimization is known not to be (and never will be) present, then calling a function outside the translation unit will normally be good enough, but whole program optimizations can break this.

Beyond this, C11 defined some memory barriers in stdatomic.h and many compilers offer their own.

The critical section code may well have such a barrier included as part of the hardware API (I think ARM has the presence of one as part of its API)

This is in interesting question, and I expect to see a couple of interesting answers here :slight_smile:

Richard Damon beats me, he was quicker :slight_smile: Yet I will post my text.

Volatile means that the value of a variable may change any moment, either from an ISR or from another task, that makes no difference.

When a variable has the volatile attribute, the compiler will do a fetch in each occasion where it is mentioned. Without the attribute, the value may be stored temporarily in a register, in order to save a fetch from RAM.

A critical section is needed for read/modify/write operations:

    volatile size_t txHead;
    size_t txSize;

    taskENTER_CRITICAL();
    txHead += txSize;
    taskEXIT_CRITICAL();

it is defined inside a task and NOT modified by an ISR but it can be modified by another task?

What do you mean with “defined inside a task” ? Is it a static variable?

But it doesn’t matter where it is changed, in an ISR or in another task.

what if it is Global would that change anything?

Global or static will not make a difference for volatile.

If you would make all static/global variables “volatile”, your application would become less efficient. It is like compiling without optimisations.

Without “volatile”, a task might not see that a variable has been updated while it is running.

Thank you @richard-damon and @htibosch :slight_smile: