だ明確に文書化グローバルデータは、ISRとメインプログラムと共有されている場合、データのニーズが宣言されることをvolatile
保証メモリの可視性にするために(それが唯一の1バイトのデータで十分、何も大きなニーズも保証アトミックに特別な手配を) 。ここに良いルールがあります:
- ISRの外部でのみ使用される変数は、揮発性であってはなりません。
- ISR内でのみ使用される変数は、揮発性であってはなりません。
- ISRの内部と外部の両方で使用される変数は、揮発性でなければなりません。
しかしvolatile
、変数が1を超えるISRからアクセスされ、ISRの外部で共有されない場合に必要ですか?たとえば、static
変数を使用して内部状態を維持する関数があります。
void func() {
static volatile long counter; // volatile or not?
// Do stuff with counter etc.
}
この関数は、ピン割り込みから、およびTimerOneライブラリからの2つの方法で呼び出されます。
attachInterrupt(0, func, CHANGE);
Timer1.attachInterrupt(func);
ISRに入ると、割り込みは自動的に無効になるため、アトミック性の問題はありませんが、これvolatile
はコンパイラーの質問です。何がキャッシュされ、何がキャッシュされないかです。
もちろん、申し訳ありませんが安全です。
volatile
。生成されるコード以外で変更されないためです。コンパイラは、割り込みが入れ子にならない限り、ISRが線形に実行されると「想定」できます。それは理にかなっている。ありがとう!