也许,每个微控制器程序开发人员都可能至少听说过特殊的编码标准,这些标准旨在帮助提高代码的安全性和可移植性。 MISRA就是这样一种标准。 在本文中,我们将更详细地研究这个标准是什么,它的基本原理以及如何在您的项目中使用它。
我们的许多读者都听说PVS-Studio支持根据MISRA标准对警报进行分类。 目前,PVS-Studio
涵盖了100多个MISRA C:2012和MISRA C ++:2008规则。
本文旨在用一颗石头杀死三只鸟:
- 告诉那些不熟悉该标准的人什么是MISRA;
- 提醒嵌入式世界我们有能力;
- 为了帮助新员工更深入地开展业务,他们还将进一步开发我们的MISRA分析仪;
我希望我能使它有趣。 因此,让我们开始吧!
MISRA的故事
MISRA的历史很久以前就开始了。 然后,在90年代初,英国政府计划以“安全IT”的名义将资金分配给与电子系统安全性相关的各种项目。 建立MISRA(汽车行业软件可靠性协会)项目本身的目的是为开发用于陆地车辆(通常是汽车)中的微控制器的软件创建指南。
MISRA团队得到了州政府的资助,开始工作,并于1994年11月发布了其第一份指南:“
车载软件开发指南 ”。 该指南尚未与特定语言绑定,但我必须承认:这项工作令人印象深刻,并且涉及开发嵌入式软件的所有可能方面。 顺便说一下,本指南的开发者最近为他们
庆祝了这一重要日期
的25周年 。
当国家资助结束时,MISRA的成员决定继续非正式地合作-直到今天。 实际上,MISRA(作为一个组织)是来自各个汽车和飞机制造业的利益相关者社区。 现在这些聚会是:
- 宾利汽车
- 福特汽车公司
- 捷豹路虎
- 德尔福柴油系统
- ORI场米拉
- 千变电
- 伟世通工程服务
- 利兹大学
- 英国里卡多
- 采埃孚TRW
非常强大的市场参与者,不是吗? 毫不奇怪,他们的第一个与语言相关的标准MISRA C已被关键任务嵌入式开发人员广泛接受。 MISRA C ++稍后出现。 逐渐地,对标准的版本进行了更新和完善,以涵盖语言的新功能。 在撰写本文时,当前版本是MISRA C:2012和MISRA C ++:2008。
规则的哲学与范例
MISRA最显着的特点是它对细节的不可思议的关注以及确保安全的极端细致性。 作者不仅将所有想到的C和C ++漏洞集中在一个地方(例如,CERT的作者),而且他们精心制定了这些语言的国际标准,并写下了所有可能的和无法想象的错误方法。 然后他们从上面采用并添加了有关代码可读性的规则-这使在已经很干净的代码中引入新错误变得更加困难。
要了解严重程度,请考虑从标准中获取的一些规则。
一方面,无论您打算做什么项目,都应始终遵循许多良好且合适的规则。 在大多数情况下,它们旨在消除未定义/未指定/与实现有关的行为。 例如:
- 不要使用未初始化变量的值
- 关闭流后不要使用FILE指针
- 所有非void函数必须返回一个值。
- 循环计数器不能为浮点类型
- ...等
另一方面,存在一些规则,这些规则的好处体现在表面上,但是(从普通项目的角度来看)这些规则并不是那么容易犯法的:
- 不要使用goto和longjmp
- 每个开关应以默认值结尾
- 不要编写无法访问的代码
- 不要使用可变功能
- 不要使用地址算术( []和++除外)
- ...
这样的规则也不错,与以前的规则相结合,它们已经在安全性上带来了明显的提高,但是对于负责任的嵌入式系统而言,这是否足够? 它们不仅用于汽车工业,还用于飞机制造,航空航天,军事和医疗。
由于软件错误,我们不希望某些X射线机
以20,000 rad的剂量照射患者 ,因此通常的“每天”规则不再足够。 生命和大量金钱处于危急关头,必须包括细致性。 MISRA的其余规则在这里进行:
- 字面量的后缀“ L”应始终为大写(小写的“ l”可与单位混淆)
- 不要使用逗号运算符(这样会增加出错的机会)
- 不要使用递归(小的微控制器堆栈很容易溢出)
- if , else , for , while , do , switch语句的主体必须用大括号括起来(如果代码未正确对齐,则可能会出错)。
- 不要使用动态内存(因为有可能无法从堆中成功分配它,尤其是在微控制器中)
- ...还有很多这样的规则。
通常,遇到MISRA的人都认为该标准的理念是“禁止这样做并禁止这样做”。 实际上是这样,但仅部分如此。
是的,该标准确实有很多类似的规则,但是其目的不是要禁止一切可能,而是要列出所有所有以某种方式违反代码安全性的方式。 对于大多数规则,您选择是否遵循它们。 我将更详细地解释这一点。
在MISRA C中,规则分为三大类:强制性,必需和建议性。 强制性-这些规则不得以任何借口违反。 例如,此部分包含规则“请勿使用未初始化变量的值”。 所需的规则不太严格:它们允许拒绝的可能性,但前提是必须仔细记录并以书面形式合理说明这些差异。 其余规则包括在“咨询”类别中-这些是不需要遵循的规则。
MISRA C ++稍有不同:此处缺少“必需”类别,并且大多数规则都属于“必需”类别。 因此,实际上,您有权违反任何规则-请记住要记录差异。 还有一个类别的文档-这些是强制性规则(不允许偏差),这些规则与诸如“每次汇编程序的使用都应记录在案”或“插件库必须符合MISRA C ++”之类的常见做法相关联。
还有什么
实际上,MISRA不仅包含一组规则。 实际上,这是一本为微控制器编写安全代码的手册,因此它具有各种用途。 让我们详细看看它们。
首先,该标准对背景进行了相当详尽的描述:为创建标准,选择C或C ++的原因,这些语言的优缺点。
我们非常了解这些语言的优点。 是的,并且通常也有缺点:)什么是高复杂性,标准和语法的不完整规范,使得很容易犯一个错误,然后长时间寻找错误。 例如,您可能会不小心这样写:
for (int i = 0; i < n; ++i); { do_something(); }
仍然有可能一个人不会注意到
多余的分号 ,对吗? 您也可以这样写:
void SpendTime(bool doWantToKillPeople) { if (doWantToKillPeople = true) { StartNuclearWar(); } else { PlayComputerGames(); } }
很好的是,
第一种情况和
第二种情况都容易被MISRA规则捕获(第一种情况是MISRA C:13.4 / MISRA C ++:6.2.1,第二种是MISRA C:13.4 / MISRA C ++:6.2.1)。
除了描述问题外,该标准还包含大量提示,这些提示涉及您在开始之前需要了解的内容:如何设置MISRA开发流程,使用静态分析器检查代码的符合性,需要保留哪些文档以及如何保存填充等等。
最后还有一些应用程序,其中包含:规则的简短列表和摘要表,C / C ++漏洞的小列表,偏离规则的文档示例以及旨在帮助您避免在整个官僚机构中迷路的几个清单。
如您所见,MISRA不仅是一组规则,而且几乎是用于为嵌入式系统编写安全代码的整个基础结构。
在您的项目中使用
想象一个情况:您将为一些非常必要且负责任的嵌入式系统编写程序。 或者您已经有一个程序,但是您需要将其“转移”到MISRA。 如何检查您的代码是否符合标准? 您真的必须手动进行吗?
手动代码验证不是一件容易的事情,而且可能是不可能完成的任务。 每个审阅者不仅必须仔细查看每一行代码,而且还必须内心地了解标准。 恐怖!
因此,建议MISRA开发人员自己使用静态分析来测试您的代码。 实际上,实际上,静态分析是一个自动化的代码检查过程。 您只需在程序上运行分析仪,几分钟后您将收到有关潜在违反标准的报告。 您需要什么,对不对? 您只需要查看日志并修复响应即可。
下一个问题:您从什么时候开始使用MISRA? 答案很简单:越早越好。 理想情况下,甚至在您开始编写代码之前,因为MISRA都假定您在代码的整个生命周期中都遵循该标准。
当然,并非一开始就总是可以编写MISRA。 例如,经常发生一个项目已经部分或完全实施的情况,但是客户希望该项目符合标准。 在这种情况下,您将必须对现有代码进行彻底的重构。
这是陷阱出现的地方。 我什至会说一个水下巨石弹出。 如果您使用静态分析仪并检查“普通”项目是否符合MISRA标准,将会怎样? 剧透:您会感到害怕。
当然,图中的示例被夸大了。 在这里,您可以看到检查一个足够大的项目的结果,实际上这是在微控制器上工作从未想到的。 但是,在检查现有代码时,您可能会看到一,二,五甚至一万次分析器操作。 并且在所有这些堆中,新操作将丢失,这些新操作是发给刚编写或更改的代码的。
怎么办呢? 真的有必要把所有东西都放在一边,坐下来修复所有旧问题吗?
我们知道,第一次检查项目时,经常会出现很多积极的情况,并且已经开发出一种解决方案,可以帮助您立即从分析仪中受益,而无需停止工作。 此解决方案称为“抑制基础”。
基于抑制的是PVS-Studio机制,它可以大量抑制分析器消息。 如果您是第一次检查项目并在那里发现数千个肯定值,则只需将它们添加到抑制数据库中,下次运行分析器时,它将给您零警告。
因此,您可以继续以通常的方式编写和修改代码,同时,您将仅看到有关刚刚引入到项目中的那些错误的警告。 同时,您将在此时此刻从分析仪中获得最大的收益,而不会因旧错误而分心。 只需单击几下即可完成分析仪! 您可以
在此处阅读有关此内容的详细说明。
您可能会问:“等等,如何处理隐藏的响应?”答案很简单:不要忘记它们,而要悄悄地纠正它们。 例如,您可以在版本控制系统中放置抑制基础,并仅允许那些不会增加操作数量的提交。 因此,渐渐地,您的“水下巨石”或早或晚都会被排干,没有任何痕迹。
好的,分析器已经实现,现在我们可以继续了。 接下来要做什么? 清除业务-使用代码。 但是,需要什么才能声明符合该标准? 如何证明您的项目符合MISRA?
事实是,您的代码没有符合MISRA的特殊“证明”。 正如标准本身所规定的那样,合规性代码跟踪应由两方执行:软件客户和软件提供商。 供应商开发符合标准的软件并填写必要的文件。 就客户而言,客户必须确保这些文档中的数据是真实的。
如果您自己既是客户又是自己软件的开发人员,那么遵守标准的责任将仅由您自己承担:)
通常,为了证明项目的一致性,您将需要证明文件。 项目开发人员应准备的文档清单可能会有所不同,但是MISRA提供了一些作为参考。 让我们更详细地考虑这个集合。
要声明符合标准,您需要做一些事情:
- 实际上是一个其代码符合强制性和必需规则的项目
- 指导执行计划
- 所有编译器和静态分析器警告的文档
- 记录所有与必需规则的差异
- 准则合规摘要
首先是合规计划。 这是您最重要的表格,它将表格发送给审查员所有其他文档。 在其第一列中是MISRA规则的列表,其余部分则指出是否已识别出与这些规则的任何差异。 该表如下所示:
该标准建议使用多个编译器以及使用两个或多个静态分析器检查代码是否符合要求来构建项目。 如果编译器或分析器生成与该规则相关的某种警告,则应在表和文档中加以注意:为什么不能消除该操作,该操作是否为假等。
如果无法使用静态分析器检查任何规则,则需要执行代码检查过程。 还应记录此过程,此后,应将此文件的链接添加到合规计划中。
如果事实证明编译器或静态分析器是正确的,或者在代码检查过程中发现实际的代码冲突,则必须对其进行修复或记录。 同样,通过将链接附加到表中的文档。
因此,合规性计划是一个文档,通过它可以找到有关代码中标识的任何偏差的文档。
现在介绍一些偏离规则的文档。 正如我已经提到的,此类文档仅对于必需规则是必需的,因为您不能违反强制性级别规则,并且没有任何文档也不能遵循咨询规则。
如果您决定偏离规则,则文档应包含:
- 规则编号破损
- 确切的偏差位置
- 偏差的有效性
- 偏差不会损害安全性的证据
- 潜在的用户影响
如您所见,这种记录方法使您认真考虑违反行为是否值得。 这样做是专门为了违反Required-rules不好:)
现在介绍遵守规则的摘要。 本文也许是最容易填写的:
在开始使用代码之前,中间一列已填充,而在项目准备好之后,最右边的一列已填充。
提出一个问题是很合理的:如果标准本身已经指定了规则类别,为什么还要指定规则类别? 事实是,该标准允许在更严格的类别中“增加”规则。 例如,客户可能要求您将“咨询”规则移到类别中。 必须在使用代码之前进行这种“增加”,并且对规则的遵守情况摘要可以清楚地指出这一点。
在最后一列中,一切都很简单:仅注意是否使用了规则就足够了,如果使用了规则,则说明存在偏差。
需要整个表,以便您可以快速查看规则具有哪些优先级以及代码是否与它们匹配。 如果您突然对知道拒绝的确切原因感兴趣,可以随时参考合规计划并找到所需的文档。
因此,您按照MISRA规则仔细地编写了代码。 您制定了合规计划,并记录了可以记录的所有内容,并填写了合规摘要。 如果这是真的,那么您现在已经收到非常讨厌,非常易读且非常可靠的代码,而现在您讨厌:)
您的程序现在将放在哪里? 在MRI机器上? 在普通的速度传感器中还是在某些太空卫星的自动驾驶系统中? 是的,您经历了严重的官僚主义道路,但是这些都是琐事。 当现实生活受到威胁时,怎么能一丝不苟?
如果您能够成功并能够取得胜利,那么我衷心祝贺您:您编写了高质量的安全代码。 谢谢你
标准的未来
最后,我想谈一谈标准的未来。
MISRA目前正在发展。 例如,在2019年初,宣布了“ MISRA C:2012年第三版(第一次修订)”-对2012年新规则进行了更新和补充。 同时,他们宣布了即将发布的MISRA C:2012年修订案2-C11 Core(2012年标准),该规则将添加首次涵盖2011 C和C版本的规则。
不要停滞不前,MISRA C ++。 如您所知,最新的MISRA C ++标准可以追溯到2008年,因此它涵盖的语言的最早版本是C ++ 03。 因此,还有另一个类似于MISRA的标准,称为AUTOSAR C ++。 它最初被认为是MISRA C ++的延续,旨在涵盖该语言的更高版本。 与其策划者不同,AUTOSAR C ++每年更新两次,目前支持C ++ 14。 计划进一步升级到C ++ 17,然后再升级到C ++ 20,依此类推。
我从其他一些标准开始? 事实是,不到一年前,两个组织都宣布将其标准统一为一个。 现在,MISRA C ++和AUTOSAR C ++将成为一个单一的标准,现在它们将一起开发。 我认为这对于使用C ++微控制器编写的开发人员来说是个好消息,对于静态分析器的开发人员来说也同样是个好消息。 仍然有很多喜欢的工作! :)
结论
今天,我们对MISRA有了很多了解:我们阅读了MISRA的历史,研究了规则的例子和标准的哲学,考虑了在项目中使用MISRA所需的一切,甚至展望了未来。 希望您现在更好地了解MISRA是什么以及如何烹饪!
按照旧的传统,我将在此处留下指向我们的PVS-Studio静态分析仪的链接。 它不仅可以发现与MISRA标准的偏差,还可以发现
大量的错误和漏洞。 如果您有兴趣亲自尝试PVS-Studio,请
下载演示版本并检查您的项目。
我的文章到此结束。 祝所有读者新年快乐,周末愉快!
网站连结
- Georgy Gribkov-“ 以最高速度实现安全性-如何为嵌入式系统编写可靠的C / C ++代码 。”
- PVS-Studio是静态代码分析器 。
- PVS-Studio与KEIL 5合作 。

如果您想与讲英语的读者分享这篇文章,请使用翻译链接:George Gribkov。
什么是MISRA及其烹饪方法 。