ターゲットオブジェクトがレジスタ内で分割されるメモリマップドレジスタインターフェイスを配置するための最も洗練されたインターフェイスでの入力を探しています。
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);
しかし、私は原則としてこのようなマクロの大ファンではありません。他の人のコードを読んでいるときにマクロを追いかけるのは嫌いです。他の人にそのような惨めさを与えることは私から遠く離れています。このオブジェクトの分割された性質をよりエレガントに(理想的にはオブジェクトの単純なメンバーとして)隠すために、構造体/ユニオン/何を持っているかを含む創造的なトリックがあることを望んでいました。