我正在寻找最优雅的界面上的输入,以放置一个内存映射寄存器接口,其中目标对象在寄存器中被拆分:
union __attribute__ ((__packed__)) epsr_t {
uint32_t storage;
struct {
unsigned reserved0 : 10;
unsigned ICI_IT_2to7 : 6; // TOP HALF
unsigned reserved1 : 8;
unsigned T : 1;
unsigned ICI_IT_0to1 : 2; // BOTTOM HALF
unsigned reserved2 : 5;
} bits;
};
在这种情况下,访问单个位T
或任何reserved
字段都可以正常工作,但读取或写入ICI_IT
需要的代码更像:
union epsr_t epsr;
// Reading:
uint8_t ici_it = (epsr.bits.ICI_IT_2to7 << 2) | epsr.bits.ICI_IT_0to1;
// Writing:
epsr.bits.ICI_IT_2to7 = ici_it >> 2;
epsr.bits.ICI_IT_0to1 = ici_it & 0x3;
在这一点上,我已经失去了位域抽象试图提供的简单性/便利性。我考虑了宏观解决方案:
#define GET_ICI_IT(_e) ((_e.bits.ICI_IT_2to7 << 2) | _e.bits.ICI_IT_0to1)
#define SET_ICI_IT(_e, _i) do {\
_e.bits.ICI_IT_2to7 = _i >> 2;\
_e.bits.ICI_IT_0to1 = _i & 0x3;\
while (0);
但作为一般规则,我不是这样的宏的超级粉丝,我讨厌在阅读别人的代码时追逐它们,而且我绝不会给别人造成这样的痛苦。我希望有一个涉及结构/联合/what-have-you 的创意技巧来更优雅地隐藏这个对象的拆分性质(理想情况下作为对象的简单成员)。