I need to create a structure with bitfields to encapsulate some data coming from hardware. Assuming I use compiler-specific mechanisms to enforce packing and ordering, is it possible to create a structure similar to the following (not syntactically correct):
typedef struct _BYTE_OF_DATA
{
uint8_t Reserved1 : 2;
struct
{
uint8_t BitWithSomeMeaning : 1;
uint8_t BitWithSomeOtherMeaning : 1;
} BitsWithMeaning;
uint8_t Reserved2 : 4;
} BYTE_OF_DATA, *PBYTE_OF_DATA;
static_assert(sizeof(BYTE_OF_DATA) == 1, "Incorrect size");
Which can then be accessed as follows:
BYTE_OF_DATA byteOfData;
byteOfData.Reserved1 = 1;
byteOfData.BitsWithMeaning.BitWithSomeOtherMeaning = 0;
The exact scheme I have described above will not work, because I guess the struct BitsWithMeaning
needs to start at a byte boundary. I was wondering if there is some other trick by which I can achieve this "nesting" of bitfields.
To elaborate on my previous comment something along these lines should allow the access style you desire. Albeit in a far from elegant way:
typedef union _BYTE_OF_DATA {
struct {
uint8_t Reserved1 : 2;
uint8_t : 2;
uint8_t Reserved2 : 4;
};
struct {
uint8_t : 2;
uint8_t BitWithSomeMeaning : 1;
uint8_t BitWithSomeOtherMeaning : 1;
uint8_t : 4;
} BitsWithMeaning;
} BYTE_OF_DATA, *PBYTE_OF_DATA;
Personally I would much prefer traditional field mask and position constants and mangle the registers manually. My experience is that accessing volatile I/O bitfields in this style invariably leads to inefficient and race-prone code.
You should use an union in this case
typedef union _BYTE_OF_DATA {
uint8_t data;
struct {
uint8_t padding1 : 2;
uint8_t BitWithSomeMeaning : 1;
uint8_t BitWithSomeOtherMeaning : 1;
uint8_t padding 2 : 4;
} BitsWithMeaning;
} BYTE_OF_DATA, *PBYTE_OF_DATA;
static_assert(sizeof(BYTE_OF_DATA) == 1, "Incorrect size");
So you can fill data in one shot :
BYTE_OF_DATA myByte;
myByte.data = someotherbyte;
And get bit with meaning :
int meaning1 = myByte.BitWithSomeMeaning;
int meaning2 = myByte.BitWithSomeOtherMeaning;
Or do the opposite :
myByte.data = 0; // Put all fields to 0
myByte.BitWithSomeMeaning = 1;
myByte.BitWithSomeOtherMeaning = 0;
int data = myByte.data;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With