I have a very minimal ISR routine where I read a variable name and I decrement it if > 0.
That variable is also read by another function.
From feedback from a previous post of mine here I understand that (expecially) because that variable is 32-bit wide I don’t need to lock the section as critical.

Two questions:

  1. is that still valid if that variable is inside a structure? I assume so, but perhaps not?
  2. if I use the taskENTER_CRITICAL / taskEXIT_CRITICAL inside the ISR, does it take a long time?

Thank you

Unless two Things might modify the variable you don’t need to protect the modification. All readers will get either the old or new value as the write will be atomic.

Thank you Richard,
for future reference if I need it, how can I find out how many instructions the taskENTER_CRITICAL / taskEXIT_CRITICAL take?

Compile it and look at the disassembly? The number of instructions will depend on the compiler and the optimisation level.

Thank you Richard,
for some reason I thought that RTOS was intentionally designed to not be affected by optimization that change the number of instructions of functions that are used in time-critical purposes. That’s obviously not the case. Thanks for clarifying.

The operation of the RTOS wouldn’t be affected by things like that. The key point is that how many machines instructions that operation takes WILL be very dependent on the processor architecture (what instructions are needed) and a bit on how the compiler converts the code given to do that into actual machine instructions. For many ports it will call in line assembly, so the compiler is unlikely to change much (but maybe for the function prolog/epilog). Others might use an ‘intrinsic’ which might be a bit more variable.

Hi Ric,

you need to understand that w/ ISRs vs. tasks, mutual exclusion is asymmetric. If the concurrent read to the variable decremented by your ISR resides in a task or an ISR with an interrupt priority lower than the ISR that decrements it, you’re always safe (regardless of whether the increment/decrement is atomic or not) because the ISR will never be interrupted by the concurrent code and so execute the decrement “pseudo atomic” (meaning not necessarily in a single instruction but without danger of the value becoming incoherent).

A task (or lower-PRI ISR) that would need to modify (not just read, as richard_damon pointed out) the variable concurrently would have to employ an interrupt suspension mechanism to prevent data corruption, but note that the FreeRTOS critical section might not suffice here (if the ISR resides above configMAX_SYSCALL_INTERRUPT_PRIORITY, it will not be disabled by the critical section).

My answer is still correct. If just a single writer, than a ‘word’ sized variable will be updated atomically, so doesn’t need protection.

If bigger than an atomic memory access, or might be updated by multiple writers, you need to protect the access. (If bigger than atomic, you need to protect for both reads and writes, if still atomic sized, just the writes).

taskENTER_CRITICAL/taskEXIT_CRITICAL, and the FromISR versions, are fast, likely just a couple of assembly instructions, as for most machines this is a simple process, because it sort of needs to be.