我正在使用“ IAR RL78”和“ RL78-R5F10BGG”微控制器。我还在IAR中启用了MISRA C 2004。
我想将我的功能之一定义为“内联”。该内联函数应该在各种c文件中使用。因此,我在其中之一
中定义了该函数头文件,并在需要该功能的所有c文件中包含该头文件。但是我的问题是由于编译后的MISRA C 8.5规则。它说:
Error [Pm123]:标头文件中没有对象或函数的定义(MISRA C 2004规则8.5)
以下是common.h标头中内联函数的定义:
static inline int16u SET_BIT(int16u int16uVar, int16u int16uBitIndex);
#pragma inline=forced
static inline int16u SET_BIT(int16u int16uVar, int16u int16uBitIndex)
{
int16uVar |= ( (int16u)1u << (int16uBitIndex) );
return int16uVar ;
}
怎么了?
有什么办法可以解决这个问题?
MISRA-C:2004不涵盖C99,因此您根本无法使用inline
。
并且因此,即使在内联函数中,有关头文件中的函数定义的规则也会被触犯。您无法通过所发布的代码来符合MISRA-C:2004的要求-您将不得不与一些必需规则产生偏差。
我的建议是升级到MISRA-C:2012,在此情况下有明确的例外(规则5.9):
例外具有内部链接的inline函数可以在多个翻译单元中定义,只要所有这些定义都在每个翻译单元中包含的同一header file中进行。
MISRA-C:2012还要求所有内联函数必须声明为static
(规则8.10)。
MISRA-C:2012在几乎所有方面都是一个更好的文档。 IAR也获得了对2012版本的支持,其MISRA检查器应该是与特定MCU无关的单独插件。
与您的实际问题无关(int16u)1u <<
完全是错误和危险的。
如果您实际上必须具有带符号的类型(大多数情况下没有),那么您必须first对无符号类型进行转换,然后转换为带符号的类型。
这不仅符合MISRA-C的要求,还可以解决当您将数据移入符号位时,在8位和16位MCU上调用未定义行为的明显C错误。
正确的代码应为int16uVar |= (int16u)(1u << int16uBitIndex);
,我相信这也满足了MISRA-C:2004有关在操作后强制转换为基础类型的要求。
也请注意,通常不赞成创建自己的“车库标准”整数类型-由于使用的是C99,因此应使用stdint.h
,而不能使用其他任何东西。这也是MISRA-C:2012的建议。