2

マイクロコントローラーをプログラミングするとき、いくつかのフラグをリセットするために読み取る必要があるレジスターが時々あります。これらのレジスタはメモリ マップされ、コード内で volatile へのポインタとして宣言されます。

例として次のスニペットを想定します。

typedef volatile struct _Ifx_SCU
{
   ...
   uint32_t reg;
   ...
}Ifx_SCU;


#define MODULE_SCU ((*(Ifx_SCU*)0xF0036000u))


void foo(void)
{
   ... 

   MODULE_SCU.reg; /* Read required to reset bits in reg */

   ...
}

ここでは、ビットをリセットするためにregを読み取る必要があります。一部のビットをリセットする方法は、読み取る以外にありません。そのため、MISRA ルール チェッカーは、デッド コードがあり、それは正しいと不平を言っています。

私の質問は、「デッドコード」を回避するために**reg 値を読み取って破棄する代替方法は何ですか?** 投稿のメソッドを使用して、揮発性式の結果を void にキャストするため 、非常によく似ています。状況では、まだ MISRA c 2012 ルール違反が発生します。#define MODULE_SCUまたは構造体から何も変更できないため、正しい代替方法を使用することをお勧めします。

このスレッドから読み取ったように、void へのコンパイラーのキャストを黙らせたくありません: void キャストは何をしますか? void にキャストすると、オプティマイザーがその読み取りを最適化して削除する可能性があり、それは望ましくないためです。

スニペットの正確さにあまり注意を払わないでください。質問を説明するためにのみ含めました

4

2 に答える 2

3

オブジェクトを読み取って結果を破棄する正しい方法は次のとおりです。

(void)object;

キャストは実際には必要ありませんが、コンパイラが不平を言うのを防ぐことができます (実際の MISRA についてはわかりません)。参考までに: これは式ステートメントです。

objectが修飾されている場合volatile、このキーワードはコンパイラに副作用があることを伝えるため、たとえコンパイラがそれを認識していなくても、アクセスはコンパイラによって最適化されない可能性があります。キャストはオブジェクトではなく式の結果(「読み取り」)に適用されるため、コメントが示すように修飾子は削除されません。

MISRA チェッカーは、ラインが実際に何かを行うため、文句を言うべきではありませ。(これはvolatile 修飾子によって暗示されます)。とにかくツールが文句を言うなら、それを捨ててください。さらに言えば、これに問題があるように見えるのはこれが初めてではありません。

于 2015-08-11T20:41:34.090 に答える