掌握嵌入式编程:减少错误、提升安全性的实战习惯
过去十年间,嵌入式软件规模从几十万行激增至典型车辆中的一亿行以上。32位处理器的普及和大容量内存的应用解锁了前所未有的功能,但也放大了威胁安全与安保的隐蔽Bug风险。
为保持领先,开发者必须采取系统性方法,在错误进入代码库前就加以预防。有两类主要错误值得特别关注:
- 编码错误 —— 如数组越界访问。可通过静态分析检测。
- 应用错误 —— 只有在根据需求验证软件行为时才能发现。
实施严格的编码标准(如MISRA C/C++),结合需求驱动测试,提供了强有力的“预防胜于治疗”策略。这能减少调试时间、压缩进度,最终保护投资回报率。
为何预防至关重要
人为失误不可避免——工程师赶工期、疏忽细节、或误解复杂数据流。但当软件规模和互联性增长时,这些简单的疏漏可能级联为关键故障。严谨的编码标准有助于在问题浮现前检测并消除许多隐患。
在C/C++生态系统中,约80%的缺陷源自对语言中仅20%特性的误用。通过禁止或限制这些有问题的构造,标准能显著提升代码质量。
考虑有符号整数右移产生的未定义行为:不同编译器结果可能不同,导致程序行为不一致。同样,读取环形缓冲区的函数在某些编译器上可能返回意外顺序的值。这些细微差别如下图所示。

图1. C/C++构造的编译器相关行为. 来源: LDRA

图2. 环形缓冲区示例中的未指定行为. 来源: LDRA
利用MISRA C/C++
MISRA于1998年首发,面向汽车行业,至今仍是嵌入式C/C++编码的黄金标准。它规定了:
- 每条规则的存在理由,附带详细例外情况。
- 未定义、未指定和实现定义行为的清晰示例。
- 哪些规则是“可判定的”(工具可验证),哪些是“不可判定的”指导。
2016年,MISRA扩展至安全关键代码,新增14条指令。例如,指令4.14明确禁止可能导致未定义行为的构造,从而强化安全态势。

图3. MISRA关于未定义和未指定行为的指导. 来源: LDRA

图4. 指令4.14在防止未定义行为中的作用. 来源: LDRA
从代码到应用:需求与测试的作用
即使代码无瑕疵,若不满足预期目的也会失败。需求追踪和单元级测试对于验证软件按设计运行至关重要。
双向追踪将每个函数链接回其底层需求,并向上关联至系统级目标。这种映射能尽早暴露缺失或多余的功能。

图5. 从函数到系统需求的双向追踪. 来源: LDRA
一旦定义了底层需求,测试用例自然浮现。运行这些测试——理想情况下使用自动化单元测试工具——确认代码履行了其契约。

图9. 自动化单元测试结果. 来源: LDRA
培养新的编码习惯
现代嵌入式开发要求全局视角:
- 实施经验证的编码标准(MISRA、CERT等)。
- 跟踪指标——缺陷密度、代码覆盖率、合规率。
- 强制执行需求追踪和自动化回归测试。
这些实践交付更清洁、更易维护的代码,简化功能添加,降低长期维护成本——无论在安全关键还是非关键领域均受益。
若想保持竞争优势,采纳这些习惯并非可选。一个需要不断救火的代码库与一个平滑演进的代码库,区别往往仅在于一套严谨的流程。
原文来自EDN.
嵌入式
- GE Digital发布预测性资产管理软件,推动维护从反应式转向主动式
- 精通 CMMS 培训:激活团队与强化留存的实战框架
- Saelig发布Impact-D 100AL:高性能紧凑型嵌入式PC,15年长生命周期与丰富I/O
- 保障软件供应链安全的三大实证步骤
- 文本字符串:嵌入式软件中的隐藏漏洞
- SOAFEE:赋能软件定义汽车平台的云原生架构
- Pixus 推出增强结构强度的坚固型 6U OpenVPX 面板
- Kontron 发布 COM HPC:新一代高性能嵌入式计算标准
- Congatec 推出 10 款基于 Intel Coffee Lake H 处理器的 COM Express Type-6 模块
- congatec 推出面向上游/中游油气的坚固嵌入式边缘服务器
- 保障物联网开源软件安全:缓解软件风险
- DevOps赋能嵌入式软件:跨越硬件异构与交付加速的工程实践