Reputation: 1
The protocol is:
(four byte hour/minute/second field, for example (12:13:56 110))
bit00~bit01: 00
bit02~bit11: millisecond (110)
bit12~bit15: second-1s (6)
bit16~bit18: second-10s (5)
bit19~bit22: minute-1s (3)
bit23~bit25: minute-10s (1)
bit26~bit29: hour-1s (2)
bit30~bit31: hour-10s (1)
How should I define the upper structure?
I've tried to define this:
struct xxx_time
{
unsigned int pad:2;
unsigned int second0:4;
unsigned int second1:3;
unsigned int minute0:4;
unsigned int minute1:3;
unsigned int hour:4;
unsigned int hour1:2;
};
Is it right to define it this way? Is there any better way?
Upvotes: 0
Views: 128
Reputation: 122483
I think it's fine, except that you forgot the millisecond field.
struct xxx_time
{
unsigned int pad:2;
unsigned int milisecond:10;
unsigned int second0:4;
unsigned int second1:3;
unsigned int minute0:4;
unsigned int minute1:3;
unsigned int hour:4;
unsigned int hour1:2;
};
Also, if pad
field is really just for padding(you won't manipulate them), you can use an unnamed field:
struct xxx_time
{
unsigned int :2;
unsigned int milisecond:10;
//...
}
Remember that almost everything about bit-fields is implementation-dependent.
Upvotes: 1
Reputation: 4829
Your layout would work with the recent gcc compilers (and compatibles, e.g. icc).
Also, for big-endian machines you need to "invert" the struct:
struct xxx_time {
#ifdef WORDS_BIGENDIAN
unsigned int hour1:2;
unsigned int hour:4;
unsigned int minute1:3;
unsigned int minute0:4;
unsigned int second1:3;
unsigned int second0:4;
unsigned int milisecond:10;
unsigned int:2;
#else
...
#endif
};
The notes about implementation-defined behaviour still apply, so you should probably check what the compiler produces.
Seeing as C11 (and also gnu99) allow anonymous structures this is easily done with a union, with no changes to code (only declarations with the struct type have to be changed):
union xxx_time_u {
uint32_t ival;
struct {
#ifdef WORDS_BIGENDIAN
unsigned int hour1:2;
...
#else
unsigned int:2
...
#endif
};
};
Upvotes: 0
Reputation: 31404
The memory layout of bit fields in structs is compiler defined. There is no guarantee that the compiler will layout the structs fields in the order that you have them listed. For example the pad field may not be the first two bits in the struct. See Memory layout of struct having bitfields and Why bit endianness is an issue in bitfields?.
So no you cannot use a struct with bit fields to map a defined underlying memory layout. You will have to use bit shifts and masks to read and write your buffer with the given memory layout.
Upvotes: 1
Reputation: 26
I think it depend on what you want to do using these data. One goal of data structure is to better or effective to store and access data to serve system processing.
For example, if you want to know and process the hour, minute, you wrote is ok. if you only care about whole time, the one time variable is ok.
It is depend on your requirement how to use these data.
Upvotes: 0