misra-c笔记(准备嵌入式实习)
Misra-C编码规范
前言
为了解决嵌入式 C 语言开发中常见的安全性和可靠性问题,汽车产业软件可靠性协会 (MISRA) 发布了 MISRA C 编码标准。
MISRA C (Motor Industry Software Reliability Association C) 是汽车工业 C 编码标准的缩写,由 MISRA 协会发布。其目标是为嵌入式系统中的 C 语言开发提供一套严格的编码规范,旨在:
- 提升代码可靠性 (Reliability): 减少因编码错误导致的程序缺陷,提高系统运行的稳定性。
- 提升代码可读性 (Readability): 统一代码风格,使代码更易于理解和维护,降低维护成本。
- 提升代码可移植性 (Portability): 减少对特定编译器或硬件平台的依赖,增强代码在不同环境下的适应性。
- 提升代码可维护性 (Maintainability): 规范的代码结构和风格,降低代码维护和升级的难度。
- 提升代码安全性 (Safety): 避免潜在的安全漏洞,保障系统运行的安全。
一、指令 (Directives)
Dir1.1 实现定义行为文档化
1 | Any implementation-defined behavior on which the output of the program depends shall be documented and understood |
要知道程序这么运作和输出是有意的,而不是偶然产生了。就是要让所有的程序动作都能被程序员所理解,让我们的箱子白化。对嵌入式程序而言,这点尤为重要。
要求: 应该用文档记录并了解程序输出依赖的任何实现定义行为。
解释: C 语言标准中有一些行为是“实现定义”的 (implementation-defined),这意味着这些行为的具体实现由编译器或平台决定。不同的编译器或平台可能会对这些行为有不同的实现,导致代码的行为在不同环境下不一致。为了确保代码的可移植性和可预测性,应该将程序依赖的任何实现定义行为记录在文档中,并确保开发团队充分理解这些行为。
示例:
- 整数类型的大小 (int, long 等) 在不同平台上可能是不同的。
- 有符号整数的右移操作可能是算术右移 (保留符号位) 或逻辑右移 (不保留符号位)。
- 结构体成员的对齐方式可能因编译器和平台而异。
Dir 2.1 零编译错误:
Dir2.1 所有的源文件不应该有任何编译错误
- 要求: 所有源文件必须没有任何编译错误。
- 解释: 这是代码质量最基本的要求。存在编译错误的代码无法生成可执行程序,更谈不上功能和性能。在开发过程中,应该及时修复所有编译错误,确保代码始终处于可编译状态。
Dir 3.1 需求可追溯性
Dir3.1 所有的代码都应该可追溯到需求文档
代码需要按照需求开发,并且代码需要与需求文档一一匹配。如果有代码不在需求文档中,那么要么改代码,要么改需求文档。
- 要求: 所有代码应该可以追溯至文件化的需求。
- 解释: 可追溯性是指代码和需求之间建立清晰的对应关系。良好的可追溯性可以帮助开发人员理解代码的设计意图,验证代码是否满足需求,并在需求变更时快速定位受影响的代码。
- 示例:
- 可以在代码注释中注明该代码段对应的需求编号或需求描述。
- 可以使用需求管理工具来维护代码和需求之间的映射关系。
Dir 4.1 运行时故障最小化
- 要求: 运行时故障必须最小化。
- 解释: 运行时故障是指程序在运行过程中发生的错误,例如空指针解引用、数组越界、除零错误等。这些故障会导致程序崩溃或产生不可预测的结果。在代码设计阶段就应考虑各种可能的错误情况,并采取措施预防运行时故障的发生,例如进行输入验证、边界检查、错误处理等
Dir 4.2 所有汇编语言的使用应当用文档记录
- 要求: 建议所有汇编的使用应当用文档记录。
- 解释: 虽然在某些情况下, 为了提高性能或访问底层硬件, 可能需要使用汇编语言。 但是, 汇编语言的可读性, 可维护性和可移植性都比较差。 因此,MISRA C建议详细记录汇编代码的用途, 功能和接口, 以便其他开发人员理解和维护。
Dir 4.3 汇编语言必须封装、隔离
- 要求: 汇编语言必须封装、隔离。
- 解释: 为了减少汇编语言对代码可维护性和可移植性的影响, 应该将汇编代码封装在独立的函数或模块中, 并与 C 代码隔离。 这样可以限制汇编代码的作用范围, 降低代码的复杂性, 并方便后续的维护和移植。
Dir 4.4 建议代码部分不应当注释掉
要求: 建议代码部分不应当注释掉。
解释:
不合规代码示例:
1
2
3/*
x = y + z; // 这段代码暂时不需要
*/合规代码示例:
1
2
3
x = y + z; // 使用预处理指令
解释:不应该用
// ...或者/* ... */注释代码。而应该用
#ifdef ...#endif等预编译指令。
二、Misra-C 规则
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Aylmer's Blog!
评论