5

組み込みシステムで C をプログラミングしています。プロセッサ アーキテクチャは 32 ビット (sizeof(int)は 32 ビット、sizeof(short)は 16 ビット) です。下位 16 ビットのみが使用されるように指定されたメモリ マップド コントロール レジスタ ( ) である 32 ビット変数がありCTRL_REG、符号付き 16 ビット整数値が含まれます (上位ビットへの書き込みは影響しません)。メモリ アクセスは 32 ビットでアラインされている必要があるため、ポインターを数バイトにまたがらせることはできません。また、エンディアンを想定することもできません。符号ビットを必要なビット 15 に残すのではなく、ビット 31 に拡張することによって、自動型昇格が保存しているものを台無しにするのではないかと心配しています。この場所に何かを保管する最良の方法は何ですか?

これが私の元のコードで、これが間違っていることはほぼ確実です。

#define CTRL_REG   *((volatile unsigned int *)0x4000D008u)
short calibrationValue;

CTRL_REG = -2 * calibrationValue;

次に、これを試しましたが、割り当ての時点で整数昇格の対象となる可能性があると思います。

CTRL_REG = (short)(-2 * calibrationValue);

そして、最後に次のように考えました。

CTRL_REG = (unsigned short)(short)(-2 * calibrationValue);

これらのオプションをうまく評価できないのは、calibrationValueたまたま負の値 (各デバイスに固有のキャリブレーション パラメーターであり、一部のデバイスでは正の可能性がある) であるため、テストですべて機能するためです。-2 を掛けた後、終了します。正の値を格納しているため、テストで予想している問題に実際には遭遇しません。

「考えすぎ」というだけでも、よろしくお願いします。

4

4 に答える 4

4

unsigned int の代わりに、unsigned int と 2 つの short signed int の和集合を定義します。

これが、私のARMシステムで「変なハードウェア制御レジスタ」を処理する方法です。かなり頻繁に、奇数ビットがあちこちにあり、「ドントケア」または「1を書き込まないでください」のいずれかです。

Rgds、マーティン

于 2011-09-16T14:46:27.743 に答える
4

-16 (たとえば) が 16 ビットでは '0xFFF0' 、33 ビットでは '0xFFFFFFF0' のように見えることを考えてみてください。符号拡張は、まさに符号ビットを適切な場所に確実に配置したいものです。上位 16 は don't care なので 1 で埋めても良い。したがって、符号付き 32 ビット値を作成し、それを符号なし 32 にキャストしてレジスタに入れます。

  Int32 calreg= -2L * calibrationValue;
   CTRl_REG = (Uint32)calreg;

上位ビットに 0 を書き込む場合は、キャストの前に 0xFFFF でマスクします。

于 2011-09-16T14:47:46.867 に答える
0

上位 16 ビットに書き込まれた値が無視される場合は、型変換に安全に依存できると思います。全体として、上位ビットは気にしません。

#define CTRL_REG   *((volatile signed int *)0x4000D008u)
short calibrationValue;

CTRL_REG = -2 * calibrationValue;

CTRL_REG が符号付き整数として宣言されていることに注意してください。

于 2011-09-16T14:37:55.263 に答える
0
#define SS2L(sh,sl) ( ((sh) <<16) | ((sl) & 0xffff) )

2 つの 16 ビット short を 1 つの 32 ビット long に結合します。

符号なしの型を使用して bitops を実行することをお勧めします。int への昇格はあなたをつかむことができます。上記のマクロにも unsigned へのキャストを追加するかもしれません。

于 2011-09-16T14:41:43.033 に答える