1

各「行」に受信メッセージが含まれる 2-D 整数配列 (8x8) があります。この配列の要素、incomingMessageBuffers[1][0:7] を、定義済みのビットフィールドを持つ構造体にマッピングすることに関心があります。これは、マスクとシフトの方法を使用するよりも高速であることが判明する可能性があります。ビットフィールドの順序付けはコンパイラに依存することは知っていますが、この事実とは無関係であると思われるため、観察された動作が見られる理由を理解したいと思います。

MYSTRUCT にマップしようとしているメモリ

 - incomingMessageBuffer [1][0:7]  
    0. 0x1544 
    1. 0x0000 
    2. 0x0008 
    3. 0x3400 
    4. 0x0012 
    5. 0x8100 
    6. 0x0000 
    7. 0x0000

MYSTRUCT 定義:

struct MYSTRUCT{
   unsigned int PACKET0:16;
   unsigned int PACKET1:16;
   unsigned int PACKET2:16;

   unsigned char PACKET3_LOW:8;
   unsigned int MYINTEGER:16;
   unsigned char PACKET4_HIGH:8;

   unsigned char PACKET5_LOW:8;
   unsigned char MYBIT:1;
   unsigned char EXTRABITS:3;
   unsigned char MYNIBBLE:4;

   unsigned int PACKET6:16;
   unsigned int PACKET7:16; }

マッピングのための私のコードと望ましい結果の例:

volatile struct MYSTRUCT *Message           
Message = &incomingMessageBuffer[1][0];     

myInteger = (Message->MYINTEGER);           
myBit = (Message->MYBIT);       
myNibble = (Message->MYNIBBLE);

Expected values:
myInteger = 0x1234
myBit = 0x01;
myNibble = 0x08;

代わりに、これは PACKET0、1、および 2 に正しくマップされますが、次のメンバー割り当ては正しくありません。このタイプの定義の慣習についての私の理解から...

struct
{
    type [member_name] : width ;
};

type は member_name 型 (つまり、PACKET6、MYBIT など) を定義しています。型のサイズが幅よりも大きい場合、member_name の余分な上位ビットはゼロで埋められます。構造を次のように定義しない限り、期待される値が割り当てられていないため、これは正しくないと思います。

struct MYSTRUCT_2{
    unsigned int PACKET0:16;
    unsigned int PACKET1:16;
    unsigned int PACKET2:16;

    unsigned char PACKET3_LOW:8;
    unsigned long int MYINTEGER:16; //Notice long int here
    unsigned char PACKET4_HIGH:8;

    unsigned char PACKET5_LOW:8;
    unsigned char MYBIT:1;
    unsigned char EXTRABITS:3;
    unsigned char MYNIBBLE:4;

    unsigned int PACKET6:16;
    unsigned int PACKET7:16;
}

次に、構造体メンバーのマスキングを使用して変数を割り当てます。

volatile struct MYSTRUCT *Message           
Message = &incomingMessageBuffer            

myInteger = (Message->MYINTEGER)&0xFFFF         
myBit = (Message->MYBIT)&0x01           
myNibble = (Message->MYNIBBLE)&0x0F         

では、MYINTEGER のサイズを定義するだけの場合、MYINTEGER を unsigned long int として宣言すると、ビット マッピングに従って正しい割り当てが行われるのはなぜでしょうか?

どんな助けでも大歓迎です。

4

1 に答える 1