4

32 ビットレジスタから 2 ビット目、5 ビット目、6 ビット目を読み取りたいです。それらを格納するために構造体ビット フィールドを使用することにしました。次のデータ構造は正しいですか?

struct readData
{
    int unwanted:1;
    int reqbit1:1;
    int unwanted1:2;
    int reqbit2:2;
    int unwanted2:26;
};

ビットフィールドがどのように作成されるかはわかりません。ハードウェア レジスタからこの構造体にバイトを直接コピーする API を使用します。その場合、reqbit1 には 2 番目のビットが含まれますか? 私の理解では、コンパイラは最初のビットを int 変数に割り当て、2 番目のビットは別の int 変数に割り当てるため、reqbit1 にはレジスタから読み取られるデータがありません。この状況には、次のユニオンの方が適しているのではないでしょうか?

union readData
{
    struct readBits
    {
        bool unwanted:1;
        bool reqbit1:1;
        xxx unwanted1:2;
        short reqbit2:2;
        xxx unwanted2:26;
    };

    int regValue;
};

これが正しい場合、undeded2 を何と宣言すればよいでしょうか?

4

3 に答える 3

4

通常、次の共用体が使用されます。

union readData {
   struct {
      unsigned int unwanted:1;
      unsigned int reqbit1:1;
      unsigned int unwanted1:2;
      unsigned int reqbit2:2;
      unsigned int unwanted2:26;
   } readBits;
   unsigned int regValue;
};

編集 :

使用法は次のとおりです。

 #define REG_ADDRESS 0x12345678 // e.g.

 union readData* rd = (union readData*)REG_ADDRESS;

 char bit2 = rd->readBits.reqbit1;
 char bits56 = rd->readBits.reqbit2;
于 2013-07-09T06:43:42.253 に答える
2

C標準から:「ユニット内のビットフィールドの割り当て順序(上位から下位、または下位から上位)は実装定義です。」

したがって、順序が重要な場合はビットフィールドを使用しないでください。

代わりに、明示的なマスキングとシフトを使用します。

reqbit1 = (w >> 1) & 1;    
reqbit2 = (w >> 4) & 3;

また

reqbit1 = (w & 0x00000002) >> 1;    
reqbit2 = (w & 0x00000010) >> 4;

そして反対方向へ

w = (reqbit1 << 1) | (reqbit2 << 4);

「不要な」部分には通常、名前が付けられreserved1ます。

于 2013-07-10T19:42:43.887 に答える