6

AVR32 に割り込みサービス ルーティングがあります。割り込みをキャンセルするには、割り込みステータス レジスタから読み取る必要があります。ただし、読み取りの結果は使用しません。私はむしろ asm 命令を使用したくありませんが、gcc がダミー変数への読み取りを最適化してしまうのではないかと懸念しています。正しい方法は何ですか?

現在私は持っています:

uint32_t tmp = *(volatile uint32_t *)INTERRUPT_STATUS_REG_ADDRESS;

tmp も揮発性であるべきですか? tmp を使用しないと gcc が読み取りをスキップするのではないかと心配しています。

4

1 に答える 1

6

(volatile uint32_t*) へのポインタ キャストを介して割り込みステータス レジスタを読み取ると、この式 (指定されたアドレスの変数) を読み取ると副作用が生じるため、常にこの式を評価する必要があることがコンパイラに伝えられます。

tmp 変数は揮発性ではないため、コンパイラーはレジスターの値を変数に格納することを自由に最適化できます。

C標準の5.1.2.3章(ここを参照)は十分に関連していると思います。

さらに、第 6.7.3 章では次のように説明しています。

volatile 修飾された型を持つオブジェクトは、実装に不明な方法で変更されたり、その他の未知の副作用を持つ可能性があります。したがって、そのようなオブジェクトを参照する式は、5.1.2.3 で説明されているように、抽象マシンの規則に従って厳密に評価されます。さらに、すべてのシーケンス ポイントで、オブジェクトに最後に格納された値は、前述の未知の要因によって変更された場合を除き、抽象マシンによって規定された値と一致するものとします。116) volatile 修飾された型を持つオブジェクトへのアクセスを構成するものは実装定義です。

実際には tmp を省略して、次のように書くことができます:

*(volatile uint32_t *)INTERRUPT_STATUS_REG_ADDRESS;

これは、INTERRUPT_STATUS_REG_ADDRESS にある uint32_t レジスタを読み取るだけです。

于 2014-10-21T07:50:31.030 に答える