用于从H / W寄存器读取的位字段

我想从32位寄存器读取第2,第5和第6位。 我决定使用struct位字段来存储它们。 以下数据结构是否正确?

struct readData { int unwanted:1; int reqbit1:1; int unwanted1:2; int reqbit2:2; int unwanted2:26; }; 

我不确定如何创建位字段。 我将使用一个API,它将字节从h / w寄存器直接复制到此结构。 在那种情况下,reqbit1会包含第二位吗? 根据我的理解,编译器将第一位分配给一个int变量,第二位分配给另一个int变量,因此reqbit1将不会从寄存器中读取任何数据。 以下联盟不适合这种情况吗?

 union readData { struct readBits{ bool unwanted:1; bool reqbit1:1; xxx unwanted1:2; short reqbit2:2; xxx unwanted2:26; }; int regValue; }; 

如果这是对的,我应该将不想要的2声明为什么?

根据C标准:“单位内的位域分配顺序(从高阶到低阶或从低阶到高阶)是实现定义的。”

所以你不应该使用秩序重要的位域。

使用显式屏蔽和转换:

 reqbit1 = (w >> 1) & 1; reqbit2 = (w >> 4) & 3; 

要么

 reqbit1 = (w & 0x00000002) >> 1; reqbit2 = (w & 0x00000010) >> 4; 

而另一个方向

 w = (reqbit1 << 1) | (reqbit2 << 4); 

“不需要的”部分通常被命名为reserved1 ,依此类推。

通常使用以下联合:

 union readData { struct { unsigned int unwanted:1; unsigned int reqbit1:1; unsigned int unwanted1:2; unsigned int reqbit2:2; unsigned int unwanted2:26; } readBits; unsigned int regValue; }; 

编辑:

用法是:

  #define REG_ADDRESS 0x12345678 // eg union readData* rd = (union readData*)REG_ADDRESS; char bit2 = rd->readBits.reqbit1; char bits56 = rd->readBits.reqbit2; 

为什么不使用sizeof()并检查分配给每个struct成员的字节数? 结构成员对齐可以在这里找到

为什么要将h / w寄存器复制到结构中然后处理结构位? 可能存在使用新值更新h / w寄存器但结构仍未更新的情况。

如果要读取第2位,第5位和第6位,可以通过以下方式实现:

 #define myregister ((unsigned long*)address of register) unsigned long ret=0; ret = myregister & (1<<2); if(ret) { ... } ret = myregister & (1<<5); if(ret) { ... } //... and so on 

恕我直言,亲吻(保持简单,愚蠢)。