我熟悉在处理器之间通信时使用位字段的问题 - 请参阅C/C++:强制位字段顺序和对齐以及为什么字节序会影响问题。
但我的问题是关于使用位字段来指定一字节寄存器中的位布局:安全吗?
作为一个具体示例,我正在使用具有字节宽控制寄存器的设备,记录如下:
D7(最高位) | D6 | D5 | D4 | D3:D2 | D1 | D0(最低有效位) |
---|---|---|---|---|---|---|
V偏置 | 模式 | 触发 | 3 线 | 故障代码 | 故障 | 50 赫兹 |
定义以下结构似乎很自然:
typedef struct {
unsigned int vbias : 1;
unsigned int mode : 1;
unsigned int trigger : 1;
unsigned int wire_3 : 1;
unsigned int fault_code : 2;
unsigned int fault : 1;
unsigned int hz_50 : 1
} control_reg_t;
所以问题是:由于我只在给定的处理器中使用这个结构——它不会通过线路传输等——有什么理由不使用这种方法?
如果您坚持使用单一硬件实现并且使用相同的编译器和相同的编译器标志集,您应该获得一致的行为。
话虽这么说,字段的布局将取决于相关机器的字节序。如果您使用的是大端字节序,那么您拥有的就可以了。如果您使用的是小端,则需要反转字段。
例如,如果您使用 gcc,则可以使用以下内容:
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
typedef struct {
unsigned int hz_50 : 1
unsigned int fault : 1;
unsigned int fault_code : 2;
unsigned int wire_3 : 1;
unsigned int trigger : 1;
unsigned int mode : 1;
unsigned int vbias : 1;
} control_reg_t;
#elseif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
typedef struct {
unsigned int vbias : 1;
unsigned int mode : 1;
unsigned int trigger : 1;
unsigned int wire_3 : 1;
unsigned int fault_code : 2;
unsigned int fault : 1;
unsigned int hz_50 : 1
} control_reg_t;
#else
#error "unknown endianness"
#endif