什么是米斯拉以及如何烹饪

图2

也许每个微控制器软件开发人员都听说过特殊的编码标准,以帮助提高代码的安全性和可移植性。 MISRA是此类标准之一。 在本文中,我们将仔细研究此标准是什么,其概念以及如何在您的项目中使用它。

我们的许多读者都听说PVS-Studio支持根据MISRA标准对其警告进行分类。 目前,PVS-Studio 涵盖了100多个MISRA C规则:2012和MISRA C ++:2008。

本文旨在用一颗石头杀死三只鸟:

  1. 告诉MISRA对尚未熟悉此标准的人来说是什么;
  2. 提醒嵌入式开发世界我们能做什么;
  3. 帮助我们公司的新员工全面熟悉它,他们还将在将来开发我们的MISRA分析仪。

我希望我能使它有趣。 让我们开始吧!

米斯拉的历史


MISRA的历史很久以前就开始了。 在1990年代初期,“安全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拉德的剂量照射患者 ,因此通常的“日常”规则还不够。 随着人们的生活和巨额资金的流逝,细致性是必不可少的。 这是MISRA其余规则起作用的地方:

  • 文字后缀“ L”必须始终为大写(小写字母“ l”可以与1混淆)
  • 不要使用“逗号”运算符(它会增加出错的机会)
  • 不要使用递归(小的微控制器堆栈很容易溢出)
  • ifelseforwhiledoswitch的语句主体必须用大括号括起来(当代码未正确对齐时,可能会出错)。
  • 不要使用动态内存(因为有可能不从堆中释放它,尤其是在微控制器中)
  • ...以及许多其他规则。

经常会发生这种情况,以至于首次遇到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规则捕获(1- MISRA C:13.4 / MISRA C ++:6.2.1; 2- MISRA C:13.4 / MISRA C ++:6.2.1)。

该标准既包含对问题的描述,也包括对执行某项任务之前必须了解的知识的提示:如何根据MISRA建立开发流程; 如何使用静态分析器检查代码是否符合要求; 一个人必须维护什么文件,如何填写它们等等。

最后的附录还包括:规则的简短列表和摘要,C / C ++漏洞的小列表,规则偏差文档的示例以及一些有助于梳理所有这些官僚机构的清单。

如您所见,MISRA不仅是一组规则,而且几乎是用于为嵌入式系统编写安全代码的整个基础结构。

在项目中的用法


想象一下场景:您将为非常需要且负责任的嵌入式系统编写程序。 或者您已经有一个程序,但是您需要将其“移植”到MISRA。 那么,如何检查代码是否符合标准? 您真的必须手动进行吗?

手动代码验证是一项艰巨的任务,甚至可能是不可能完成的任务。 不仅每位审阅者都必须仔细查看每一行代码,而且几乎必须完全了解标准。 疯了!

因此,MISRA开发人员自己建议使用静态分析来测试您的代码。 毕竟,实际上,静态分析是代码审查的自动化过程。 您只需在程序上运行分析器,几分钟后,您便会收到有关可能违反标准的报告。 这就是您所需要的,不是吗? 您所要做的就是查看日志并修复警告。

下一个问题是-我们应该从什么时候开始使用MISRA? 答案很简单:越早越好。 理想情况下-在您完全开始编写代码之前,因为MISRA假定您在整个代码生命周期中都遵循该标准。

嗯,并非一开始就总是可能按照MISRA编写。 例如,通常情况是项目已经部分或完全实施,但是后来客户希望项目符合标准。 在这种情况下,您将不得不对现有代码进行彻底的重构。

那就是陷阱出现的地方。 我什至会说水下巨石出现了。 如果您使用静态分析仪并检查“普通”项目以满足MISRA标准,会发生什么情况? 剧透:您可能会害怕。

图5


是的,图片中的例子被夸大了。 它显示了检查一个实际上不是用于微控制器的大型项目的结果。 但是,当检查已经存在的代码时,您很可能会收到一,二,三甚至一万次分析器警告。 针对新代码或修改后的代码发出的新警告将在大量警告中完全丢失。

那你该怎么办呢? 您真的必须推迟所有任务并全力以赴解决旧警告吗?

作为静态分析器的开发人员,我们知道检查之后会出现很多警告。 因此,我们开发了该解决方案,可以在不停止工作的情况下立即帮助分析仪使用。 此解决方案称为“抑制基础”。

抑制基代表PVS-Studio机制,使您可以大量抑制分析器消息。 如果您是第一次检查项目并收到数千条警告-您只需将它们添加到抑制基数中,下一次运行将为您提供零警告。

这样,您可以继续按常规方式编写和更改代码,这样做时,您将仅收到有关项目中刚刚发生的错误的消息。 因此,您将在此时此刻从分析器中获得最大的收益,而不会因为耙旧错误而分心。 只需单击几下即可将分析仪应用到您的开发中! 您可以在此处阅读有关此操作的详细说明。

您可能会想:“等等,隐藏的警告呢?”答案很简单:不要忘记它们,并通过简单的步骤进行修复。 例如,您可以在版本控制系统中加载抑制基,并仅允许那些不会增加警告数量的提交。 因此,逐渐地,您的“水下巨石”将早晚磨掉而不会留下任何痕迹。

好的,分析仪现已成功采用,我们已准备好继续。 接下来要做什么? 答案不言而喻-使用代码! 但是,要宣布符合该标准需要做什么? 您如何证明您的项目符合MISRA?

实际上,您的代码没有对应于MISRA的特殊“证书”。 按照标准的规定,合规性跟踪应由两方进行:软件客户和软件供应商。 供应商开发符合标准的软件并填写必要的文档。 反过来,客户必须确保这些文档中的数据是真实的。

如果您自己开发软件,那么达到标准的责任就落在您的肩上:)

通常,要证明项目的合规性,您将需要证明文件。 项目开发人员应准备的文档清单可能会有所不同,但是MISRA提供了一些文档集作为参考。 让我们仔细看看这个集合。

您将需要这些东西来申请标准合规性:

  • 项目本身,其代码符合强制性和必需规则
  • 指导执行计划
  • 有关所有编译器和静态分析器警告的文档
  • 与要求规则的所有偏离的文档
  • 准则合规摘要

首先是指导执行计划。 这是您最重要的表,其中包含对所有其他文档的引用。 在其第一列中是MISRA规则的列表,其余部分则指出与这些规则是否有任何差异。 该表如下所示:

图片1

该标准建议使用多个编译器来构建项目,并使用两个或多个静态分析器来测试代码的符合性。 如果编译器或分析器发出与规则相关的警告,则应在表中记录该警告并记录以下几点:为什么无法修复该警告,该警告是否为假等等。

如果静态分析器无法检查其中一个规则,则必须执行手动代码检查。 还必须记录此过程,然后将指向该文档的链接添加到合规计划中。

如果事实证明编译器或静态分析器是正确的,或者在代码检查过程中存在有效的规则冲突,则必须更正它们或对其进行记录。 同样,通过将链接附加到表中的文档。

因此,合规计划是一个文档,它将为您的代码中标识的任何偏差提供文档。

让我们简要介绍一下直接记录与规则的偏差。 正如我提到的那样,此类文档仅对于必需规则是必需的,因为不能违反强制性规则,并且在没有任何文档的情况下也可能违反咨询规则。

如果您选择偏离规则,则文档应包括:

  • 违反规则数
  • 偏差的确切位置
  • 偏差的有效性
  • 证明不偏离安全性的证明
  • 对用户的潜在后果

如您所见,这种记录文档的方法使您严重怀疑违规是否值得。 这样做是为了不希望违反要求的规则而进行的:)

现在介绍遵守规则的摘要。 也许本文将是最容易填写的:

图片3

在开始使用代码之前,中间一栏已填满,在项目准备好之后,中间一栏已填满。

这是一个合理的问题:如果标准本身已经指定了规则类别,为什么还要指定规则类别? 事实是,该标准允许将规则“提升”为更严格的类别。 例如,客户可能会要求您对咨询规则进行分类。 应该在使用代码之前进行这种“促销”,并且遵守规则的摘要使您可以明确地注意到它。

至于最后一列,这很简单:您只需要注意是否正在使用该规则,如果正在使用,则是否有偏离。

需要整个表,以便您可以快速查看规则具有哪些优先级以及代码是否符合它们。 如果您突然想知道偏差的确切原因,则可以随时求助于合规计划并查找所需的文档。

图6

因此,您按照MISRA规则仔细地编写了代码。 您已经制定了合规计划,并记录了可以记录的所有内容,并且填写了合规简历。 如果确实如此,那么您现在已经讨厌了一个非常干净,非常易读且非常可靠的代码:)

您的程序现在将放在哪里? 在MRI设备中? 在普通的速度传感器中还是在某些太空卫星的控制系统中? 是的,您已经走过严肃的官僚主义道路,但这没什么大不了的。 在现实生活中,您必须始终谨慎行事。

如果您已成功应对并取得了胜利,那么我衷心祝贺您:您编写了高质量的安全代码。 谢谢你

标准的未来


最后,我想谈谈标准的未来。

现在,米斯拉生活并在发展。 例如,“ MISRA C:2012年第三版(第一次修订)”是经过修订和扩大的,并于2019年初宣布了新的规则版本。与此同时,即将发布的“ MISRA C:2012年修正案2-C11”宣布了“ Core”,它是2012年的修订标准。 本文档将包含首次涵盖2011年和2018年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,请下载演示版本并检查项目。

那就是我的文章结束的地方。 祝所有读者圣诞快乐,新年快乐!

Source: https://habr.com/ru/post/zh-CN482486/


All Articles