在 CMSIS 中,为什么位域位置是 'unsigned int' 而掩码基数是 'unsigned long int'?

问题描述

以下是来自 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

解决方法

  1. 位位置:寄存器中的位置不能超过 31,C 中的任何整数类型都可以容纳它。甚至没有理由让该职位未签名。

  2. 面具。由于 C 标准要求的最小 unsigned int 大小不足以容纳 32 位值,因此必须将其声明为 unsigned long。 CMSIS 作者不知道您将使用的编译器,因此他们使用最小足够类型。

,

没有明显的原因。我非常怀疑这些库是否应该与 8 或 16 种苦味剂共享,这将是唯一合理的解释。

Cortex M 将是 32 位,带有 32 位 int 和 32 位 long。最重要的是 32 位硬件外设寄存器。因此,即使 long 是 64 位,将掩码移出寄存器边界也是毫无意义的。

U 后缀足以防止未定义的行为在有符号操作数上左移。其他草率的库使用有漏洞的 1 << n 样式,因此 1UL 可能是纠正该错误的快速修复程序 - 1U 本来可以正常工作。