在 CMSIS 中,为啥位域位置是“unsigned int”,而掩码基数是“unsigned long int”?
Posted
技术标签:
【中文标题】在 CMSIS 中,为啥位域位置是“unsigned int”,而掩码基数是“unsigned long int”?【英文标题】:in CMSIS, why are bitfield positions 'unsigned int' but the mask base 'unsigned long int'?在 CMSIS 中,为什么位域位置是“unsigned int”,而掩码基数是“unsigned long int”? 【发布时间】:2021-08-27 03:24:06 【问题描述】:这是来自 ST CMSIS 标头的示例:
#define USART_ISR_TC_Pos (6U)
#define USART_ISR_TC_Msk (0x1UL << USART_ISR_TC_Pos)
在 CMSIS 标头中,位域位置 (_Pos
) 以 unsigned int
类型的十进制整数常量的形式给出,未移位的掩码为 unsigned long int
。
为什么它们都没有指定为unsigned long int
?
【问题讨论】:
可能是因为如果您使用的是 64 位系统,则位置在 0..63 之内,适合unsigned int
范围,而 <<
的结果可能会超出 unsigned int
的范围,因此它应该是UL
(可以是32位或64位,取决于系统)。
<<
的右边只是要移位的位数,人类更喜欢十进制(“第 4 位”)。但是你可以在任何基础(八进制,十六进制)中做到这一点。当然这应该是一个正数。
unsigned int
需要能够至少保持 2^16。这可能有点短视,但我无法想象一台机器不足以描述unsigned long
中的位数。并且在移位操作中使用任何大于位数的值都会导致未定义的行为。因此,即使是 unsigned char
也足够了。
【参考方案1】:
位位置:寄存器中的位置不能超过31,C中的任何整数类型都可以保存。甚至没有理由不签署该职位。
面具。由于 C 标准要求的最小unsigned int
大小不足以容纳 32 位值,因此必须将其声明为 unsigned long。 CMSIS 作者不知道您将使用的编译器,因此他们使用 minimal 充分类型。
【讨论】:
【参考方案2】:没有明显的原因。我非常怀疑这些库是否打算与 8 或 16 苦味剂共享,这是唯一合理的解释。
Cortex M 将是 32 位,32 位 int
和 32 位 long
。最重要的是 32 位硬件外围寄存器。因此,即使long
是 64 位,将掩码移到寄存器范围之外也是毫无意义的。
U
后缀足以防止未定义的行为在有符号操作数上左移。其他草率的库使用错误的 1 << n
样式,所以也许 1UL
是纠正该错误的快速修复 - 1U
本来可以正常工作。
【讨论】:
以上是关于在 CMSIS 中,为啥位域位置是“unsigned int”,而掩码基数是“unsigned long int”?的主要内容,如果未能解决你的问题,请参考以下文章