2016-04-26 12 views
0

私のプログラム(SoCの統合ARCコアを意味する)にいくつかの変数を特定のアドレスに設定したいとします。私はこの構文を使用します。Cの特定のアドレスへの変数のマッピング

#define PORTBASE 0x00C07F00 

volatile Uint32* Ptr = (Uint32*)PORTBASE; //Uint32 is defined elsewhere 
*Ptr = 0xA5A5A5A5; 

* UINT定義:しかし、A5データが0x00C0_7F00に書き込まれていない

typedef unsigned long Uint32; 

。代わりに、コアはこのアドレスに書き込もうとします:0x00C0_DC00、それはサポートされていないアドレスなので割り込みを引き起こします。 0x00C07F00は、そのアドレスにマップされた特定のレジスタを表します。

住所が変更された理由は誰にも考えられますか?

+0

PORTBASEを変更したことはありませんか? cpuは同じシフトで書き込もうとしますか?ポインターのアドレスがある範囲内に収まるように自動的に変更されるかもしれません。 – sagivd

+0

1)固定ビット幅には標準タイプを使用し、自家製品には標準タイプを使用しないでください。 2)中間変数を使用することは役に立たない。 3)[ask]を参照してください。 – Olaf

+1

標準では「整数は任意のポインタ型に変換できますが、前に指定した場合を除いて、結果は実装定義であり、正しく整列されず、参照される型のエンティティを指していない可能性があり、表現 "(C2011 6.3.2.3/5)。基本的には、実行中のような変換結果からどのような結果が期待できるのか、それが可能であれば結果を得る方法については、コンパイラのドキュメントを参照する必要があります。コンパイラが準拠している場合は、そのドキュメント*が表示されます。 –

答えて

0

あなたの環境(Bare-Metal、Linux、Windows、...)は何ですか?

LinuxのようなOSを使用する場合、アドレスはプロセスポインタに相対的でなければなりません。 Linuxではmmapを使用して住所を翻訳できます。

単純な例はdevmemです。

Bare-Metalアプリケーションでは、前述のコメントの固定標準タイプを使用しています。

+0

'mmap()'への参照は少し不連続です。あなたが作業をリンクした例を作るのは、Linuxの '/ dev/mem'デバイスです。 'mmap()'を使うだけで、より便利になります。したがって、 '/ dev/mem'がCの機能ではなくOSの機能であるので、これをCの解決策と呼ぶのは少し疑わしいです。 –

+0

環境はベアメタルです –

0

ちょっと遊んだ後、私は回避策を見つけましたが、なぜそれが働いたのかは分かりません。 アドレスが定義どおりにキャストしようとしていません。まず変数をconst変数に代入し、その変数をポインタにキャストします:

#define PORTBASE 0x00C07F00 
const Uint32 PortOpCodeAddr = PORTBASE; 
Uint32* volatile const PortOpCode = (Uint32*)PortOpCodeAddr; 
関連する問題