It's clearly documented that when global data is shared with an ISR and the main program, the data needs to be declared volatile
in order to guarantee memory visibility (and that only suffices for 1-byte data; anything bigger needs special arrangements to guarantee also atomicity). Here we have good rules:
- Variables only used outside an ISR should not be volatile.
- Variables only used inside an ISR should not be volatile.
- Variables used both inside and outside an ISR should be volatile.
But is volatile
needed when the variable is accessed from > 1 ISRs, but not shared outside ISRs? For example, I have a function that maintains internal state using a static
variable:
void func() {
static volatile long counter; // volatile or not?
// Do stuff with counter etc.
}
That function is called in two ways: from pin interrupt, and from TimerOne library:
attachInterrupt(0, func, CHANGE);
Timer1.attachInterrupt(func);
There are no atomicity problems, since when an ISR is entered, interrupts are automatically disabled, but this volatile
is more of a compiler question: what is cached and what is not.
Better safe than sorry, of course...