6

次のシナリオでは、一時的な volatile 修飾子が正しい動作をもたらすかどうか疑問に思っていました。ISR が配列内の値を収集し、十分な値が収集されると、準備完了を通知するとします。

int array[10]; // observe no volatile here
int idx = 0;   // neither here
volatile bool ready = false; // but here

これがISRの擬似コードです

ISR() {
  if (idx < 10)
     array[idx++] = ...;
  ready = (idx >= 10);
}

がシグナルされた後に読み取り専用になることを保証できると仮定し、特定のメソッドのみを介して要素にアクセスします。array ready

int read(int idx) {
  // temporary volatile semantics
  volatile int *e = (volatile int*)(array + idx);
  return *e;
}

cpp-referenceに従って許可されているようです

非揮発性値から揮発性型へのキャストは効果がありません。volatile セマンティクスを使用して不揮発性オブジェクトにアクセスするには、そのアドレスを volatile へのポインタにキャストし、そのポインタを介してアクセスする必要があります。

完全を期すために、メインルーチンは次のことを行います

void loop() {
   if (ready) {
     int val = read(0); // Read value 
     // do something with val.
   }
}

このようなシナリオでは、内部からの配列への書き込みが実際にRAMで実行されるarrayことを保証するために必要な配列要素から正しい値を読み取るか、配列要素で揮発性であると期待する必要がありますか?ISR()

なぜ volatile が C で必要なのかに注意してください。この特殊なケースで volatile が必要かどうかについては詳しく説明しません。

4

1 に答える 1

1

への書き込みarray[]は経由volatileではないため、それが観察可能な動作であることに依存することはできません。はい、コンパイラは の非キャッシュ読み取りを発行する必要がありますがarray、それは全体像の半分にすぎません。

あなたはそれが影響を受けているかのように秩序volatileについて話している- それはそうではない.

于 2016-10-28T09:16:13.540 に答える