MISRA-C2012
6 分钟阅读
概述
XWOS的代码,大致遵循 MISRA-C:2012 规范进行编写,但有些 MISRA-C:2012 的规则不利于 编写操作系统,XWOS的代码趋向于选择更优的性能以及尝试使用更新的语言特性。
本文将详细描述 MISRA-C:2012 检查的方法,以及 MISRA-C:2012 规范的符合程度。
MISRA-C:2012 规范的检查方法
使用 cppcheck 工具的 misra 插件。
cppcheck -I. -I$(XWOS_ARCH_DIR) -I$(XWOS_CPU_DIR) -I$(XWOS_SOC_DIR) -I$(XWOS_BRD_DIR) \
--force --addon=misra --cppcheck-build-dir=$(CPPCHECK_OUT) \
--template=gcc --inline-suppr --suppressions-list=xwbs/util/cppcheck/misra-c2012-suppressions.txt
-i ignore_path src_path
MISRA-C:2012 规范的符合程度
全局禁用的规则
-
uninitvar- 禁用原因:误报。实际上未初始化变量,编译器会当成错误来处理。
-
misra-c2012-1.4: Emergent language features shall not be used- 禁用原因:作为一个长期持续维护的项目,XWOS在新版本中会偏向于引入新的语言特性。
-
misra-c2012-2.3: A project should not contain unused type declarations- 禁用原因:操作系统作为一个 生态系统 的基本环境,其中定义的类型、宏、函数、符号等可能在各种衍生项目中被用到。
-
misra-c2012-2.4: A project should not contain unused tag declarations- 禁用原因:操作系统作为一个 生态系统 的基本环境,其中定义的类型、宏、函数、符号等可能在各种衍生项目中被用到。
-
misra-c2012-2.5: A project should not contain unused macro declarations- 禁用原因:操作系统作为一个 生态系统 的基本环境,其中定义的类型、宏、函数、符号等可能在各种衍生项目中被用到。
-
misra-c2012-3.1: The character sequences/*and//shall not be used within a comment- 禁用原因:XWOS内使用doxygen来抓取注释生成文档,文档中如果出现URL,必然会出现
//,例如https://...,除此种情况,禁止在注释中出现//。
- 禁用原因:XWOS内使用doxygen来抓取注释生成文档,文档中如果出现URL,必然会出现
-
misra-c2012-5.9: Identifiers that define objects or functions with internal linkage should be unique- 禁用原因:包含
static inline内联函数的头文件多处使用时,内联函数被认为重复定义。
- 禁用原因:包含
-
misra-c2012-8.7: Functions and objects should not be defined with external linkage if they are referenced in only one translation unit- 禁用原因:XWOS提供的API并不一定被自己使用,对于 MISRA-C2012 规范的检查工具,可能会因为只检查到一次符号而报错。
-
misra-c2012-8.9: An object should be defined at block scope if its identifier only appears in a single function- 禁用原因:有些数据定义为全局,是为了链接时放在特定的段。
-
misra-c2012-11.3: A cast shall not be performed between a pointer to object type and a pointer to a different object type- 禁用原因
-
- XWOS中各类型的原子操作和位操作是根据位宽转换为8位、16位、32位、64位基本类型来实现的;
-
- 动态内存管理;
-
- C语言面向对象。
-
- 禁用原因
-
misra-c2012-11.4: A conversion should not be performed between a pointer to object and an integer type- 禁用原因
-
- 在指令和寄存器级别的代码;
-
xwcc_derof()宏的实现;
-
- 动态内存管理;
-
- C语言面向对象。
-
- 禁用原因
-
misra-c2012-11.5: A conversion should not be performed from pointer to void into pointer to object- 禁用原因
-
- 动态内存管理;
-
- 通讯协议协议的变长消息;
-
- 回调函数的用户参数是个泛型指针。
-
- 禁用原因
-
misra-c2012-11.6: A cast shall not be performed between pointer to void and an arithmetic type- 禁用原因
-
- XWOS将
-1至-4095的指针值当作错误码指针。但是指针是一个无符号整数。 因此是以补码形式表示。-1即0xFFFFFFFF,-4095即0xFFFFF001。
- XWOS将
-
- 动态内存管理。
-
- 禁用原因
-
misra-c2012-15.1: The goto statement should not be used- 禁用原因:XWOS只在下面两种情况下使用
goto。-
- XWOS内某些比较核心的算法(例如红黑树),会使用
goto来提高效率。
- 1.1. 因为这类代码在整个内核中被大量使用,效率是优先考虑的重点;
- 1.2. 这类代码被验证得最充分,稳定性与安全性最高。
- XWOS内某些比较核心的算法(例如红黑树),会使用
-
- XWOS使用
goto来处理出错时的代码返回。
- 2.1. 如果代码中包含了大量的操作,每个操作都有返回值,若使用
if...else...将使得嵌套特别深。使用goto能使得代码更美观易读; - 2.2. 如果代码中包含了大量的操作,每个操作都有对应的反操作,操作与反操作需要像 “栈” 结构一样先进后出,使用
if...else...很容易 遗漏反操作或将反操作的顺序搞错,但使用goto就可完美解决这一问题。
- XWOS使用
-
- 禁用原因:XWOS只在下面两种情况下使用
/* 如果包含大量操作,使用 `if...else...` 将使得代码行过长,
* 并且anti_operationX() 很容易写错位置或者遗漏。
*/
int func1(void)
{
rc = operation1();
if (0 == rc) {
rc = operation3();
if (0 == rc) {
rc = operation8();
if (0 == rc) {
rc = operation2();
if (0 == rc) {
rc = operation6();
if (0 == rc) {
rc = operation5();
if (0 == rc) {
} else {
anti_operation6();
}
} else {
anti_operation2();
}
} else {
anti_operation8();
}
} else {
anti_operation3();
}
} else {
anti_operation1();
}
} else {
}
return rc;
}
/* 使用 `goto` 将避免 `if...else...` 上述的两个问题。*/
int func2(void)
{
rc = operation1();
if (rc < 0) {
goto err_operation1;
}
rc = operation3();
if (rc < 0) {
goto err_operation3;
}
rc = operation8();
if (rc < 0) {
goto err_operation8;
}
rc = operation2();
if (rc < 0) {
goto err_operation2;
}
rc = operation6();
if (rc < 0) {
goto err_operation6;
}
rc = operation5();
if (rc < 0) {
goto err_operation5;
}
return rc;
anti_operation5();
err_operation5:
anti_operation6();
err_operation6:
anti_operation2();
err_operation2:
anti_operation8();
err_operation8:
anti_operation3();
err_operation3:
anti_operation1();
err_operation1:
return rc;
}
-
misra-c2012-17.1: The features of <stdarg.h> shall not be used- 禁用原因:不应该完全禁止语言特性。
-
misra-c2012-18.8: Variable-length array types shall not be used- 禁用原因:变长数组是C99标准引入的特性,XWOS在新版本中会偏向于引入新的语言特性。
-
misra-c2012-19.2: The union keyword should not be used- 禁用原因:
- 编写操作系统时不可避免地需要将内存地址转换为不同类型的指针,使用
union可以避免直接对void *进行转换,提高可读性。
- 编写操作系统时不可避免地需要将内存地址转换为不同类型的指针,使用
- 禁用原因:
-
misra-c2012-20.9: All identifiers used in the controlling expression of#ifor#elifpreprocessing directives shall be#define’d before evaluation- 禁用原因:检测工具会误报,但XWOS的代码是遵循此规则的。
-
misra-c2012-21.1: **#defineand#undefshall not be used on a reserved identifier or reserved macro name**- 禁用原因:C语言将任何以
_开头的符号作为保留,但有些符号来自于编译器的扩展语法,例如__attribute__((x)),通常将它们定义为两个_开头的宏来使用, 以显示它们和正常的变量、函数、宏的区别。
- 禁用原因:C语言将任何以
-
misra-c2012-21.3The memory allocation and deallocation functions of<stdlib.h>shall not be used- 禁用原因:完全禁止动态内存管理不利于引入高级语言。 仅当安全等级非常高时才禁止动态内存管理,相应的一些功能也不可被使用,例如Lua语言。
-
misra-c2012-21.6: The Standard Library input/output functions shall not be used- 禁用原因:
stdio.h的函数在XWOS内被重新定义过。
- 禁用原因:
-
misra-c2012-21.10: The Standard Library time and date functions shall not be used- 禁用原因:
time.h的函数在XWOS内被重新定义过。
- 禁用原因:
部分文件禁用的规则
-
misra-c2012-2.7: There should be no unused parameters in functions- 禁用原因:此头文件中包含CPU架构指令级别的函数,这些函数使用内联汇编语法编写,
在C语法层面看起来有些参数未使用,实际上这些参数是根据
EABI规则通过寄存器在使用。- 适用范围:
xwcd/soc/arm/v6m/armv6m_isa.hxwcd/soc/arm/v7m/armv7m_isa.hxwcd/soc/powerpc/e200x/e200x_isa.hxwcd/soc/riscv/nuclei/riscv_isa.h
- 适用范围:
- 禁用原因:此头文件中包含CPU架构指令级别的函数,这些函数使用内联汇编语法编写,
在C语法层面看起来有些参数未使用,实际上这些参数是根据
-
misra-c2012-5.7: A tag name shall be a unique identifier- 禁用原因:匿名结构体被认为
tag name重复是误报。- 适用范围:
xwcd/soc/arm/v6m/armv6m_isa.hxwcd/soc/arm/v7m/armv7m_isa.hxwcd/soc/powerpc/e200x/e200x_isa.hxwcd/soc/riscv/nuclei/riscv_isa.hxwcd/ds/uart/common.hxwcd/ds/uart/controller.hxwcd/ds/soc/chip.hxwos/lib/xwbop.cxwos/mp/skd.hxwos/up/skd.hxwos/mp/thd.hxwos/up/thd.hxwos/mp/sync/obj.hxwos/up/sync/obj.hxwos/mm/mempool/objcache.hxwos/mm/mempool/page.hxwmd/isc/xwssc/protocol.hxwmd/libc/newlibac/lock.cxwmd/libc/picolibac/lock.c
- 适用范围:
- 禁用原因:libc要求定义的符号
- 适用范围:
xwmd/libc/newlibac/lock.cxwmd/libc/picolibac/lock.c
- 适用范围:
- 禁用原因:匿名结构体被认为
-
misra-c2012-5.8: A tag name shall be a unique identifier- 禁用原因:结构体内部的成员名是在结构体的namespace内的,不会和外面符号发生冲突。
- 适用范围:
xwmd/isc/xwssc/hwifal.hxwos/mm/mempool/i_allocator.hxwmd/libc/picolibcac/mem.cxwos/mm/mempool/page.h
- 适用范围:
- 禁用原因:对LIBC中的标准函数进行重写。
- 适用范围:
xwmd/libc/picolibcac/fops.c
- 适用范围:
- 禁用原因:结构体内部的成员名是在结构体的namespace内的,不会和外面符号发生冲突。
-
misra-c2012-8.4: A compatible declaration shall be visible when an object or function with external linkage is defined- 禁用原因:误报
- 适用范围:
xwos/ospl/xwosplcb.c
- 适用范围:
- 禁用原因:Rust语言的
ffi不是在C语言层面进行链接。- 适用范围:
xwmd/xwrust/ffi/*.c
- 适用范围:
- 禁用原因:误报
-
misra-c2012-8.5: An external object or function shall be declared once in one and only one file- 禁用原因:
xwos/ospl/soc/*.h是操作系统移植层的代码,对符号再次定义,起到汇总与强调的作用。提示用户移植时需要提供这些符号的定义。- 适用范围:
xwos/ospl/soc/*.hxwos/lib/xwbop.hxwos/lib/lfq.h
- 适用范围:
- 禁用原因:误报
- 适用范围
xwmd/libc/newlibac/*.cxwmd/libc/picolibcac/*.c
- 适用范围
- 禁用原因:
-
misra-c2012-8.6: An identifier with external linkage shall have exactly one external definition- 禁用原因:误报
- 适用范围
xwmd/libc/newlibac/*.cxwmd/libc/picolibcac/*.c
- 适用范围
- 禁用原因:误报
-
misra-c2012-8.14: The restrict type qualifier shall not be used- 禁用原因:对LIBC中的标准函数进行重写。
- 适用范围:
xwmd/libc/newlibac/string.cxwmd/libc/picolibcac/string.cxwmd/libc/newlibac/time.cxwmd/libc/picolibcac/time.c
- 适用范围:
- 禁用原因:对LIBC中的标准函数进行重写。
-
misra-c2012-9.2: The initializer for an aggregate or union shall be enclosed in braces- 禁用原因:误报
- 适用范围:
xwmd/libc/newlibac/fops.cxwmd/libc/picolibcac/fops.c
- 适用范围:
- 禁用原因:误报
-
misra-c2012-9.3: Arrays shall not be partially initialized- 禁用原因:误报
- 适用范围:
xwmd/libc/newlibac/fops.cxwmd/libc/picolibcac/fops.c
- 适用范围:
- 禁用原因:误报
-
misra-c2012-10.8: The value of a composite expression shall not be cast to a different essential type category or a wider essential type- 禁用原因:宏定义的表达式是复合的表达式,不得不使用强制类型转换
- 适用范围:
xwos/mm/mempool/page.c
- 适用范围:
- 禁用原因:宏定义的表达式是复合的表达式,不得不使用强制类型转换
-
misra-c2012-11.1: Conversions shall not be performed between a pointer to a function and any other type- 禁用原因:操作系统抽象层到实现层的必要转换
- 适用范围:
xwos/osal/thd.hxwos/osal/swt.h
- 适用范围:
- 禁用原因:操作系统抽象层到实现层的必要转换
-
misra-c2012-12.3: The comma operator should not be used- 禁用原因:XWOS的链表(
xwos/lib/bclst.h)中的迭代操作宏不得不使用逗号表达式来定义。- 适用范围:
xwos/mp/skd.cxwos/up/skd.c
- 适用范围:
- 禁用原因:XWOS的链表(
-
misra-c2012-14.2: A for loop shall be well-formed- 禁用原因:XWOS的链表(
xwos/lib/bclst.h)中的迭代操作过于复杂,使用宏定义来简化代码。- 适用范围:
xwos/mp/skd.cxwos/up/skd.c
- 适用范围:
- 禁用原因:XWOS的链表(
-
misra-c2012-15.2: The goto statement shall jump to a label declared later in the same function- 禁用原因:这部分代码是XWOS低中断延迟的关键代码,必须优先考虑实时性和性能,因此不得不用
goto来实现。- 适用范围:
xwos/mp/tt.cxwos/up/tt.c
- 适用范围:
- 禁用原因:误报。
- 适用范围:
xwmd/isc/xwssc/mif.c
- 适用范围:
- 禁用原因:这部分代码是XWOS低中断延迟的关键代码,必须优先考虑实时性和性能,因此不得不用
-
misra-c2012-15.4: There should be no more than one break or goto statement used to terminate any iteration statement- 禁用原因:这部分代码是XWOS低中断延迟的关键代码,必须优先考虑实时性和性能,因此不得不用
goto来实现。- 适用范围:
xwos/mp/tt.cxwos/up/tt.c
- 适用范围:
- 禁用原因:使用率较高的代码只使用一个
break或goto影响效率。- 适用范围:
xwos/up/skd.cxwos/mp/sync/evt.cxwos/up/sync/evt.cxwmd/isc/xwssc/hwifal.cxwmd/isc/xwssc/protocol.c
- 适用范围:
- 禁用原因:这部分代码是XWOS低中断延迟的关键代码,必须优先考虑实时性和性能,因此不得不用
-
misra-c2012-15.5: A function should have a single point of exit at the end- 禁用原因:函数参数检测的代码被定义为一个宏,其中包含了一个
return。- 适用范围:
xwmd/isc/xwssc/mif.c
- 适用范围:
- 禁用原因:函数参数检测的代码被定义为一个宏,其中包含了一个
-
misra-c2012-17.2: Functions shall not call themselves, either directly or indirectly- 禁用原因:这部分代码是XWOS独创的开中断调度技术的关键代码,不得不使用递归函数来实现。此处代码被验证得非常充分,稳定性与安全性不用担心。
- 适用范围:
xwos/mp/skd.cxwos/up/skd.c
- 适用范围:
- 禁用原因:这部分代码是XWOS独创的开中断调度技术的关键代码,不得不使用递归函数来实现。此处代码被验证得非常充分,稳定性与安全性不用担心。
-
misra-c2012-17.7: The value returned by a function having non-void return type shall be used- 禁用原因:C库函数
memset(),memcpy()等有返回值,但这里并不使用它们。- 适用范围:
xwos/mp/rtrq.cxwos/up/rtrq.cxwos/mp/sync/evt.cxwos/up/sync/evt.cxwmd/isc/xwcq/xwcq.cxwmd/isc/xwssc/hwifal.cxwmd/isc/xwssc/mif.cxwmd/isc/xwssc/protocol.cxwmd/libc/newlibac/mif.cxwmd/libc/picolibcac/mif.cxwmd/libc/newlibac/mem.cxwmd/libc/picolibcac/mem.c
- 适用范围:
- 禁用原因:确定不使用返回值的地方,使用
cppcheck-suppress [misra-c2012-17.7]标注。- 适用范围:
xwos/init.cxwos/mp/lock/mtx.cxwos/up/lock/mtx.cxwos/mp/lock/spinlock.cxwos/up/lock/seqlock.cxwmd/isc/xwssc/mif.cxwmd/isc/xwssc/protocol.cxwos/mm/mempool/objcache.cxwos/mm/mempool/allocator.cxwos/mm/mempool/page.c
- 适用范围:
- 禁用原因:C库函数
-
misra-c2012-17.8: A function parameter should not be modified- 禁用原因:为了追求效率以及内存使用率,不遵循此规则。
- 适用范围:
xwos/lib/xwbop.cxwos/mm/bma.cxwos/mm/mempool/objcache.cxwos/mm/mempool/page.cxwos/mm/mempool/allocator.cxwos/mp/lock/mtx.cxwos/up/lock/mtx.cxwmd/isc/xwssc/protocol.cxwmd/libc/newlibac/string.cxwmd/libc/picolibcac/string.c
- 适用范围:
- 禁用原因:为了追求效率以及内存使用率,不遵循此规则。
-
misra-c2012-20.7: Expressions resulting from the expansion of macro parameters shall be enclosed in parentheses- 禁用原因:这部分代码使用宏来模拟C++的函数模板,其中作为类型名的参数不能使用括号封闭起来。
- 适用范围:
xwos/lib/xwaop.hxwos/lib/xwbop.h
- 适用范围:
- 禁用原因:这部分代码使用宏来定义数组,其中作为数组名参数不能使用括号封闭起来。
- 适用范围:
xwos/mm/bma.hxwos/mm/mempool/allocator.hxwmd/isc/xwssc/mif.hxwmd/isc/xwcq/mif.h
- 适用范围:
- 禁用原因:这部分代码使用宏来模拟C++的函数模板,其中作为类型名的参数不能使用括号封闭起来。
-
misra-c2012-20.10: The#and##preprocessor operators should not be used- 禁用原因:这部分代码使用宏来模拟C++的函数模板,必须使用到
#和##。- 适用范围:
xwos/lib/xwaop.hxwos/lib/xwbop.h
- 适用范围:
- 禁用原因:这部分代码使用宏来模拟C++的函数模板,必须使用到
-
misra-c2012-20.12: A macro parameter used as an operand to the#or##operators, which is itself subject to further macro replacement, shall only be used as an operand to these operators- 禁用原因:这部分代码使用宏来模拟C++的函数模板。
- 适用范围:
xwos/lib/xwaop.hxwos/lib/xwbop.h
- 适用范围:
- 禁用原因:这部分代码使用宏来模拟C++的函数模板。
-
misra-c2012-21.2A reserved identifier or macro name shall not be declared- 禁用原因:对LIBC中的标准函数进行重写。
- 适用范围:
xwmd/libc/newlibac/string.cxwmd/libc/picolibcac/string.cxwmd/libc/picolibcac/fops.cxwmd/libc/picolibcac/mem.c
- 适用范围:
- 禁用原因:对LIBC中的标准函数进行重写。
-
misra-c2012-21.4The standard header file<setjmp.h>shall not be used- 禁用原因:不应该完全禁止语言特性,XWOS对
<setjmp.h>提供了支持 。- 适用范围:
xwmd/libc/newlibac/setjmp.cxwmd/libc/picolibcac/setjmp.c
- 适用范围:
- 禁用原因:不应该完全禁止语言特性,XWOS对