I am converting a vxWorks application to Linux.
Previously, I had a union
with a word
and a struct
so that when I accessed the members of the struct
, I could use the word's
layout to build my struct
members.
However, I don't recall how I figured this out and it works on the vxWorks box. On my vxWorks instance, the layout is:
typedef union Status
{
struct fields
{
uint32_t byteA : 1; // <31>
uint32_t blank : 23; // <30:8>
uint32_t bytesN : 8; // <7:0>
} fields;
uint32_t word;
}
I've already ran into some endian issues while porting from vxWorks to Linux. So figuring out the layout of uint32_t
on linux is important.
From your comment to the other answer, you want whatever is stuffed into the word
member of the union
to appear in the fields.bytesN
member. To achieve this you must either have some kind of pre-build process that lays out the field
bit fields appropriately after detecting machine endianness, or create 2 structures, one for big endian and the other for little endian.
typedef union Status
{
struct fieldsBE
{
uint32_t byteA : 1; // <31>
uint32_t blank : 23; // <30:8>
uint32_t bytesN : 8; // <7:0>
} fieldsBE;
struct fieldsLE
{
uint32_t bytesN : 8; // <7:0>
uint32_t blank : 23; // <30:8>
uint32_t byteA : 1; // <31>
} fieldsLE;
uint32_t word;
};
int main()
{
bool isBigEndian = DetectEndianness(); // returns true if big endian
Status status;
status.word = 40;
if( isBigEndian ) {
uint8_t bytesN = status.fieldsBE.bytesN;
} else {
uint8_t bytesN = status.fieldsLE.bytesN;
}
}
Of course, if you only want to support little endian in your port use the layout of fieldsLE
instead of the original layout you've shown.