如何使用CMSIS API将无符号整数转换为枚举

问题描述

我在C程序中将CMSIS API用于ARM Cortex-M CPU。
CMSIS将NVIC_DisableIRQ函数定义为

__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn);

IRQn_Type是typedef enum,例如

typedef enum IRQn
{

  NonMaskableInt_IRQn           = -14,/*  2 Non Maskable Interrupt */
  HardFault_IRQn                = -13,/*  3 HardFault Interrupt */
  .....
  Interrupt0_IRQn               =   0,Interrupt1_IRQn               =   1,Interrupt2_IRQn               =   2,} IRQn_Type;

因此,鉴于我想称呼NVIC_DisableIRQ

NVIC_DisableIRQ( (IRQn_Type )(SCB->ICSR -16);

这使MISRA检查失败

注释9034:无法将'unsigned32'分配给其他基本类型 “枚举(IRQn)” [MISRA 2012规则10.3,必填]

我理解MISRA为什么会抱怨,但这是一个切实可行的解决方案? 我发现是要创建巨大的switch / case,是否有其他解决方案/黑客可用?

解决方法

假设SCB->ICSR -16结果为uint32_t,则不能将其分配给enum变量(10.3),也不能将其强制转换为{{1 }}(10.5)。这是因为枚举具有实现定义的大小和签名。

我想可能有各种肮脏的技巧来躲避MISRA,但这违背了这些规则的合理依据,这些原则归结为:不要在代码中使用带符号的操作数,以使它在各种细微的地方变得混乱。严厉的方法。例如更改默认的编译器枚举类型会导致所有中断更改行为-这是不好-可能会很危险。

问题的根源是enum类型和需要enum的CMSIS函数__NVIC_DisableIRQ。如果用不同的方式编写该代码,则可以使用无符号类型。奇怪的是,草率的,不符合MISRA规范的库仍在2020年推出。

我建议您删除该函数并编写一个自定义函数。这些功能大多数只是简单的单行汇编程序指令的包装器,还是无论如何都要进行寄存器写操作,因此,如果您可以访问该函数的实现,则可能不会花费很多精力。

请注意,MISRA-C(10.5)允许从枚举到无符号的转换,因此,如果您基于enum创建API,则仍然可以通过强制转换来传递枚举值。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...