Es ist klar dokumentiert, dass beim Teilen globaler Daten mit einem ISR und dem Hauptprogramm die Daten deklariert werden volatile
müssen, um die Speichersichtbarkeit zu gewährleisten (und dies reicht nur für 1-Byte-Daten aus; alles, was größer ist, erfordert spezielle Vorkehrungen, um auch die Atomizität zu gewährleisten). . Hier haben wir gute Regeln:
- Variablen, die nur außerhalb eines ISR verwendet werden, sollten nicht flüchtig sein.
- Variablen, die nur innerhalb eines ISR verwendet werden, sollten nicht flüchtig sein.
- Variablen, die sowohl innerhalb als auch außerhalb eines ISR verwendet werden, sollten volatil sein.
Aber wird volatile
benötigt , wenn die Variable aus zugegriffen wird> 1 ISRs, aber nicht außerhalb ISRs geteilt? Zum Beispiel habe ich eine Funktion, die den internen Status mithilfe einer static
Variablen beibehält :
void func() {
static volatile long counter; // volatile or not?
// Do stuff with counter etc.
}
Diese Funktion wird auf zwei Arten aufgerufen: vom Pin-Interrupt und von der TimerOne-Bibliothek :
attachInterrupt(0, func, CHANGE);
Timer1.attachInterrupt(func);
Es gibt keine Atomprobleme, da bei der Eingabe eines ISR Interrupts automatisch deaktiviert werden. Dies volatile
ist jedoch eher eine Compiler-Frage: Was wird zwischengespeichert und was nicht.
Natürlich sicherer als leid ...
volatile
, da sie nur durch den generierten Code geändert wird. Der Compiler kann "annehmen", dass der ISR linear ausgeführt wird, und dies tut er, solange Interrupts nicht verschachtelt sind. Das macht Sinn. Vielen Dank!