作为一名初级 C 程序员,我想知道在设备中设置控制位的最佳易读且易理解的解决方案是什么。有没有标准?有可以模仿的示例代码吗?谷歌没有给出任何可靠的答案。
For example, I have a control block map:
我看到的第一种方法是简单地设置所需的位。需要一大堆评论解释,看起来不太专业。
DMA_base_ptr[DMA_CONTROL_OFFS] = 0b10001100;
我看到的第二种方法是创建一个位字段。我不确定这是否是我应该坚持的,因为我从未遇到过以这种方式使用它(与我提到的第一个选项不同)。
struct DMA_control_block_struct
{
unsigned int BYTE:1;
unsigned int HW:1;
// etc
} DMA_control_block_struct;
其中一种选择比另一种更好吗?有没有我看不到的选项?
任何建议将不胜感激
位字段的问题在于,C 标准并未规定它们的定义顺序与它们的实现顺序相同。所以你可能没有设置你认为的位。
第 6.7.2.1p11 节C标准 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf states:
实现可以分配任何大的可寻址存储单元
足以容纳一个位字段。如果还有足够的空间,则生成一个位字段
结构中紧跟另一个位字段的应该是
打包到同一单元的相邻位中。如果空间不足
保留,是否将不适合的位字段放入
下一个单元或与相邻单元重叠的单元是
实现定义的。位域的分配顺序
一个单位(高阶到低阶或低阶到高阶)是
实现定义的。可寻址存储的对齐方式
单位未指定。
举个例子,看看下面的定义struct iphdr
,它表示 IP 标头,来自 Linux 上的 /usr/include/netinet/ip.h 文件:
struct iphdr
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int ihl:4;
unsigned int version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
unsigned int version:4;
unsigned int ihl:4;
#else
# error "Please fix <bits/endian.h>"
#endif
u_int8_t tos;
...
您可以在此处看到位域根据实现以不同的顺序放置。您也不应该使用此特定检查,因为此行为依赖于系统。该文件是可以接受的,因为它是系统的一部分。其他系统可以以不同的方式实现这一点。
所以不要使用位域。
执行此操作的最佳方法是设置所需的位。但是,为每个位定义命名常量并对要设置的常量执行按位或操作是有意义的。例如:
const uint8_t BIT_BYTE = 0x1;
const uint8_t BIT_HW = 0x2;
const uint8_t BIT_WORD = 0x4;
const uint8_t BIT_GO = 0x8;
const uint8_t BIT_I_EN = 0x10;
const uint8_t BIT_REEN = 0x20;
const uint8_t BIT_WEEN = 0x40;
const uint8_t BIT_LEEN = 0x80;
DMA_base_ptr[DMA_CONTROL_OFFS] = BIT_LEEN | BIT_GO | BIT_WORD;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)