Pat*_*Pat 5 c embedded struct unions bit-fields
我正在寻找最优雅的接口上的输入来放置内存映射的寄存器接口,其中目标对象在寄存器中被分割:
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;
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,访问单个位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;
Run Code Online (Sandbox Code Playgroud)
在这一点上,我已经失去了bitfield抽象试图提供的简单/便利的一大块.我考虑过宏观解决方案:
#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);
Run Code Online (Sandbox Code Playgroud)
但是,作为一般规则,我不是像这样的巨大粉丝,我讨厌在我读别人的代码时追逐它们,而对我来说,给别人带来这样的痛苦.我希望有一个创意技巧涉及结构/联合/你有什么更优雅地隐藏这个对象的分裂性质(理想情况下作为对象的简单成员).
我不认为有一种"好的"方式,实际上我不会依赖于位域...有时候最好只有一堆详尽的宏来做你想做的一切,记录得很好,然后依靠他们封装你的问题......
#define ICI_IT_HI_SHIFT 14
#define ICI_IT_HI_MASK 0xfc
#define ICI_IT_LO_SHIFT 5
#define ICI_IT_LO_MASK 0x02
// Bits containing the ICI_IT value split in the 32-bit EPSR
#define ICI_IT_PACKED_MASK ((ICI_IT_HI_MASK << ICI_IT_HI_SHIFT) | \
(ICI_IT_LO_MASK << ICI_IT_LO_SHIFT))
// Packs a single 8-bit ICI_IT value x into a 32-bit EPSR e
#define PACK_ICI_IT(e,x) ((e & ~ICI_IT_PACKED_MASK) | \
((x & ICI_IT_HI_MASK) << ICI_IT_HI_SHIFT) | \
((x & ICI_IT_LO_MASK) << ICI_IT_LO_SHIFT)))
// Unpacks a split 8-bit ICI_IT value from a 32-bit EPSR e
#define UNPACK_ICI_IT(e) (((e >> ICI_IT_HI_SHIFT) & ICI_IT_HI_MASK) | \
((e >> ICI_IT_LO_SHIFT) & ICI_IT_LO_MASK)))
Run Code Online (Sandbox Code Playgroud)
请注意,为了便于阅读,我没有将类型转换和普通宏内容放入其中.是的,我提到可读性时有讽刺意味......
| 归档时间: |
|
| 查看次数: |
466 次 |
| 最近记录: |