Question

I want to read the 2nd, 5th and the 6th bit from a 32-bit register. I have decided to use struct bit fields to store them. Is the following data structure correct?

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

I'm not sure about how the bit fields are created. I'm going to use an API that will copy bytes from the h/w register to this structure directly. In that case, will reqbit1 contain the 2nd bit? As per my understanding, the compiler allots the first bit to an int variable and the 2nd bit is alloted to another int variable and so the reqbit1 won't have any data read from the register. Isn't the following union more suitable for this situation?

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

    int regValue;
};

If this is right, what should I declare unwanted2 as?

Was it helpful?

Solution 2

From the C standard: "The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined."

So you shouldn't use bitfields where the order matters.

Use explicit masking and shifting instead:

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

or

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

and for the other direction

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

The "unwanted" parts are typically named reserved1 and so on.

OTHER TIPS

Usually it is used the following union:

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;
};

EDIT :

The usage is:

 #define REG_ADDRESS 0x12345678 // e.g.

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

 char bit2 = rd->readBits.reqbit1;
 char bits56 = rd->readBits.reqbit2;

Why not use sizeof() and check the number of bytes alloted to each of the struct members? The struct members alignment can be found out here

Why copy the h/w register into structure and then work on structure bits? There may be case when the h/w register is updated with a new value but the structure is still not updated.

If you want to read the 2nd, 5th and 6th bit, you can achieve it in the following manner:

#define  myregister  ((unsigned long*)address of register)   
unsigned long ret=0;
ret = myregister & (1<<2);
if(ret)
   { ... }
ret = myregister & (1<<5);
if(ret)
   { ... }                   //... and so on

IMHO, kiss (keep it Simple, silly).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top