2016-10-28 5 views
2

メモリマップレジスタを読み書きするベアメタルプログラム(ドライバ)があります。 例えば:メモリアクセス(MISRA 2008)を扱うときにポインタからキャスト整数への回避に最適な方法

void foo_read(uint64_t reg_base, uint32_t *out_value) 
{ 
    *out = READREG(reg_base + FOO_REG_OFFSET); 
} 
  • reg_baseがFOO_REG_OFFSETがレジスタ(#define FOO_REG_OFFSET 0x00000123)からオフセットされているメモリマップされたデバイスのベースアドレス(64ビット アドレス)
  • あります。レジスタ "foo"は32ビット "ワイド"です。

READREGは次のように定義されています。

#define READREG(address) (*(uint32_t*)(address)) 

あなたはMISRA 2008ポインタ(5-2-7/5-2-8であるにunsigned long long型からキャストに満足していない推測できるとおり報告)。私の質問は、メモリにアクセスしてMISRAの警告を取り除く最良の/適切な方法は何ですか?ポインタにキャストする前にuintptr_tにキャストしようとしましたが、This didn't helpです。

ありがとうございます。

+2

かなり明白な質問です。 reg_base'は実際にはポインタなので、 'uint8_t *'と入力してみてください。 – hidefromkgb

+1

@hidefromkgb:または 'uint32_t *'、 'reg_base'が本当に整数である必要があるのなら、なぜ' uintptr_t'ではなく 'uint64_t'を使うのですか? (MISRAはおそらくそれを好まないでしょうが、 'intptr_t'や' uintptr_t'はポインタ値を保持する整数にとって最も論理的な型です)。 –

+1

@KeithThompson、wouldn \ 't' uint32_t * 'FOO_REG_OFFSETに4を掛けます。 'reg_base'に追加しますか? – hidefromkgb

答えて

1

ここにいくつかの事OK - まず、READ_REGのためのあなたの定義が欠落しているvolatile - それがあるべき何か第二

#define READREG(address) (*(uint32_t volatile *)(address)) 

ように - と、これはCPU固有もちろんです - 一般的に言えば、奇数アドレス(オフセット0x123)から32ビット値を読み取ることはできません。最低でも遅く(複数のバスサイクル)、多くのアーキテクチャではプロセッサ例外が発生します。 (ところで、2つの値をポインタにキャストされる前に追加されますので、そのポインタ演算は、ここに遊びに来ませんのでご注意ください。)

はあなたの元の質問に答えるために:何が最善か

をメモリにアクセスし、まあMISRAを取り除く 警告

を取得する/適切な方法 - あなたは(このケースでは、我々はすべてそこにしてきたにあなたが持っている...)MISRAルールに違反ですあなたは警告を受けるでしょう。

だから、慎重に体系化され、容易に識別できる方法で警告を抑止する必要があります。私の意見では、オープンソースであるQuantum Platform(QP)イベント駆動型フレームワークのコードよりも良い例と説明はありません。具体的に:

  • は、これはどのように扱われるかの例についてはQP's MISRA Compliance行列をチェックしてください - 例えば、ちょうどQ_UINT2PTR_CASTマクロ
  • 用PDFを検索QPの実際のソースコードをチェックアウト - 例えば、macro that wraps/encapsulates such "int to ptr" castsを(このようにして、簡単に識別でき、1つの場所で警告を抑制/抑制することができます)
  • 最後に、PC-Lint設定ファイルqpc.lntをチェックして、警告は単一の場所で抑制されます。これは、this app noteのセクション6で説明されています。3:

6.3ルール5-2-8タイプを無効にする(REQ)整数型またはポインタと

オブジェクトが がポインタ型のオブジェクトに変換してはなりません。

特定のハードコードされたハードウェアアドレスに直接アクセスするには、 が必要な場合、QP/C++アプリケーションはルール5-2-8から逸脱する可能性があります。 QP/C++ フレームワークは、この偏差をマクロQ_UINT2PTR_CAST()にカプセル化します。 #define QK_ISR_EXIT() . . . \ *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = \

私はなどMISRA警告suppresions、コンプライアンスの問題、について話をする時間がありませんが、上記のあなたが必要なすべてを提供します: 次のコードスニペットは、このマクロの使用事例を提供します。

P.S.どのMISRAガイドラインを参照しているのかわかりません.Cについては、2004 & 2012ガイドラインがあります.C++については、2008年のガイドラインがあります(私はそれがほぼ2017です)。

+0

#define FOO_REG_OFFSET 0x00000123は単なる例でした。もちろん私は奇数のオフセットはありません。 – AndreiSS

+0

@AndreiSS - もちろんあなたはしません。あなたはまた、この質問のための受け入れられた答えを持っていません。 – Dan

関連する問題