自1972年Dennis MacAlistair Ritchie在美国贝尔实验室创造C语言以来,它已成为当今最流行的编程语言之一。C语言以其使用的灵活性、功能的丰富性而广受欢迎,但同时也因其宽松的语法和不严格的数据类型给开发的产品带来了安全隐患。
1989年,ANSI发布了C89标准,标志着C语言标准化的重要一步。随后,C99标准在1999年发布,引入了多项新特性,如几类新的数据类型和更强大的字符串处理功能。
随着嵌入式系统在汽车行业的广泛应用,英国政府于90年代初启动了“SafeIT”研究计划,旨在为道路车辆电子系统的嵌入式软件开发制定安全指南。这份文件具有重要意义,代表了行业共识,也是汽车行业第一种功能安全方法,比国际层面的ISO 26262工作开始早了大约10年。
由汽车工业软件可靠性协会(Motor Industry Software Reliability Association,即MISRA)制定的一套针对于C语言的编码规范,作为响应该指南的产物,为汽车行业提供了一种功能安全方法,MISRA C由此诞生。
MISRA C规范包括一系列规则和指导原则,分为强制规范(Mandatory guidelines)、要求规范(Required guidelines)和建议规范(Advisory guidelines)。这些规范覆盖了编程实践、代码设计等多个方面,旨在帮助开发者编写出更加安全和可靠的代码。
MISRA C规范包含以下核心原则:
1、未定义行为的限制(Undefined Behavior)
MISRA C通过制定规则来限制数组越界、指针解引用等未定义行为。例如,规则指导开发者避免使用未初始化的指针,以及确保数组索引不会超出其界限。
例如:Dir 4.12 Dynamic memory allocation shall not be used.
代码如下:
void f ( void )
{
char *p = ( char * ) malloc ( 10 );
char *q;
free( p );
q = p; /* 未定义行为 —— 此时p的值不确定 */
p = ( char * ) malloc ( 20 );
free( p );
p = NULL /* 将释放的指针赋值为NULL —— 此时p的值为确定 */
}
注:右滑可查看完整代码
2、类型安全(Type Safety)
MISRA C强制类型匹配和显式类型转换,以增强代码的类型安全性。例如,它要求在进行隐式类型转换时必须进行适当的检查,以避免数据丢失或意外行为。
C语言不要求强制检查所有的显示转换,允许不兼容的类型之间进行转换。
比如在不考虑数据容量的情况下,整型数据间的隐式转换可以参考下面的表格。
(Note:si——有符号32位;ui——无符号32位;uc——无符号8位)
表达式 | 变格 | 符号 平衡 | 变换 | 说明 |
si = si + si; | ||||
si = uc + uc; | 是 | uc的符号变格为有符号32位 | ||
ui =si + ui; | 是 | si的符号平衡为无符号32位 | ||
ui = ui + uc; | 是 | 是 | uc的符号变格为有符号32位再平衡为无符号32位 | |
ui = si; | 是 | si的符号变换为无符号32位 | ||
ui = uc + uc; | 是 | 是 | uc的符号变格为有符号32位后结果变换为无符号32位 | |
si = si +ui; | 是 | 是 | si的符号平衡为无符号32位后结果变换为有符号32位 | |
si = ui +uc; | 是 | 是 | 是 | uc的符号变格为有符号32位,平衡为无符号32位后结果为有符号32位 |
3、资源管理(Resource Management)
MISRA C强调正确管理内存分配和释放,避免内存泄漏。它提供了关于动态内存分配的最佳实践,包括何时使用以及如何正确释放内存。
分配内存的常用的标准库函数是malloc,对应释放内存的是free。
例如:Rule 22.2 A block of memory shall only be freed if it was allocated by means of a Standard Library function。
void fn ( void )
{
int a;
free(&a); /* NG——此内存空间不是有库函数分配 */
}
void g ( void )
{
char *p = ( char *)malloc(512);
char *q = p; /* 两个指针指向同一空间 */
free( p ); /* OK——通过p指针,内存第1次释放 */
free( q ); /* NG——通过q指针,内存第2次释放 */
}
注:右滑可查看完整代码
4、函数与宏的使用(Function and Macro Usage)
MISRA C推荐优先使用函数而非宏,以减少错误。它还规定了函数的返回类型和参数使用,以增强代码的可读性和可维护性。例如,建议使用返回类型为void的函数来执行操作,而不是返回状态码。
例如:Dir 4.9 A function should be used in preference to a function-like where they are interchangeable.
另外,在代码调试的时候,函数可以进行单步调试,有利于发现问题,反而宏就没有这个优势了。
5、控制流(Control Flow)
MISRA C对控制流语句使用有严格规定,限制“goto”语句,鼓励使用结构化控制语句如“if”、“while”和“for”循环。
例如:Rule 15.1 The goto statement should be used
在开发设计时,所有的数据流都已经明确的情况下,则可以禁止引入“goto”。
6、错误处理(Error Handling)
MISRA C提供错误处理指导,帮助开发者以一致和可预测的方式处理错误。例如,它建议使用标准化的错误代码和清晰的错误处理流程。
7、可移植性(Portability)
MISRA C鼓励使用可移植的代码实践,避免依赖特定编译器或平台特性。这包括使用标准库函数和避免平台特定的扩展。
8、代码风格与格式化(Coding Style and Formatting)
虽然主要关注安全性和可靠性,MISRA C也提供了代码风格和格式化的建议,以提高代码的可读性。这包括命名约定、缩进和注释的使用。
1978年,一门新型开发语言同样诞生于美国贝尔实验室,这门开发语言就是C++。
说到MISRA C++的发展历史,AUTOSAR C++是一个绕不过去的关键点。
众多汽车厂商于2003年组建了AUTOSAR开发联盟,发布了汽车开放系统架构(Automotive Open Software Architecture,即AUTOSAR)和经典平台(Classic Platform),后期为了满足高度自动驾驶和汽车互联应用的快速发展,于2017年发布了第一个版本的自适应平台(Adaptive Platform),至此也决定了C++的领先地位。
随着汽车系统的复杂化加深,C++已经处于曾经C语言的高度。但多数人认为,C++不应该用于关键系统。因此,一套类似于“MISRA C”、适用于C++的指导于2008年发布。这就是MISRA C++的初版,也就是MISRA C++:2008。
AUTOSAR C++:14规范是基于MISRA C++:2008进行补充完善的,填补 C++11和C++14 在关键和安全相关软件中使用时缺乏适当编码标准的空白。
MISRA C++:2023 是 MISRA C++ 标准的下一个版本,它将整合 AUTOSAR C++:14 规范,并支持 C++ 的最新版本,是汽车行业和其他使用嵌入式系统行业的最佳标准之一。
MISRA C++ 标准包含一系列的规则和指导原则,它们分为不同的类别,如强制性、推荐性等。这些规则帮助开发者避免使用可能导致不安全或不可预测行为的语言特性,同时鼓励使用那些能够提高代码质量和可维护性的编程实践。
整合了 AUTOSAR C++:14规范,共有 179 条准则。
规则按照性质分为两类:Rule(规则)和 Directive(指令),包含 175 条 Rule 和 4 条 Directive。
支持C++的最新特性,同时确保代码的安全性和可靠性。
MISRA C++标准的使用可以提高嵌入式系统的安全性和可移植性,特别是在那些对安全性要求极高的应用中。通过遵循这些指南,开发者可以减少编程错误,提高代码质量,确保软件系统的稳定性和可靠性。
静态测试是软件测试的一种方法,它不涉及程序的执行,而是通过分析源代码来检测潜在的错误和代码质量问题。MISRA C、MISRA C++与静态测试紧密相关,因为 MISRA C、MISRA C++标准提供了一套规则和指南,静态测试工具可以使用这些规则来自动检测代码是否符合 MISRA C、MISRA C++标准。
使用静态测试工具来执行MISRA C、MISRA C++标准的检查可以带来以下好处:
1. 早期发现缺陷:在编码阶段就能发现潜在的问题,减少后期修复的成本和复杂性。
2. 提高代码质量:确保代码遵循行业认可的最佳实践,提高软件的整体质量和可靠性。
3. 符合行业标准:对于需要遵守特定行业安全标准的项目,如汽车行业的 ISO 26262,静态测试可以帮助确保代码符合这些标准。
4. 自动化:自动化的代码分析可以节省时间,减少人为错误,提高开发效率。
5. 一致性:确保整个项目或团队遵循统一的编码标准,提高代码的一致性和可维护性。
总的来说,MISRA C、MISRA C++与静态测试的结合为嵌入式系统的软件开发提供了一种高效且可靠的质量保证方法,有助于提升软件安全性并减少风险。
目前市场上静态测试工具有很多,PC-lint Plus是Vector公司出品的一套全面的、轻量级的C/C++代码静态分析工具。
在MISRA C方面,PC-lint Plus提供对MISRA C:2012规范及上一代版本MISRA C:2004规范的支持,在MISRA C++方面,PC-lint Plus提供AUTOSAR C++规范及后续的MISRA C++规范的支持。
这种支持通过标准PC-lint Plus消息和专用于特定MISRA规则的可选性来实现。如果大家有该方面的需求,可以直接留言或联系邮箱market@dotrustech.com。
东信创智一直深耕于电子电气架构开发、车载总线通信与诊断测试、整车控制系统XIL仿真测试平台、控制系统及整车功能测试服务、嵌入式软件开发与集成服务等多个领域,致力于为客户提供安全可靠的研发工具和“本地化、快速化、定制化、产品化”的解决方案。东信创智不但在汽车电子传统领域的经验和能力一直处于行业前列,如CAN/LIN/Ethernet开发与测试、控制系统功能测试、整车功能验证测试、控制系统HIL仿真平台、AUTOSAR软件开发与服务等,而且在新兴技术的探索方面持续不断的提前投入研发,如ADAS智驾仿真、HMI测试验证、SOA架构开发、V2X测试验证、OTA测试验证、信息安全与功能安全等,均取得了可喜的成果。东信创智拥有多支“敢于挑战、乐于进取、善于拼搏、忠于客户”的经验丰富的技术服务团队,同众多合作伙伴一道整合全球优质资源,为客户提供“高效、高质、高价值”的产品与服务。