24小时联系电话:18217114652、13661815404

中文

您当前的位置:
首页>
电子资讯>
技术专题>
基于标准的开发实践

技术专题

基于标准的开发实践


整个行业都围绕着以功能安全性,安全性和编码标准(例如IEC 61508ISO 26262IEC 62304MISRA CCWE)为支持的验证和确认实践而发展。当然,并非所有人都有义务遵循这些标准所倡导的正式流程和方法,尤其是在其软件不需要满足这些标准的严格要求的情况下。但是标准支持最佳实践,因为经验表明,它们代表了获得高质量,可靠和强大的软件的最有效方法。

遵循这些标准的最佳实践开发技术可帮助确保一开始就不会在代码中引入错误,从而减少了对大量调试活动的需求,这些活动可能会缩短上市时间并增加成本。当然,并非所有开发人员都拥有在航空航天,汽车或医疗设备行业中看到的应用程序所能承受的时间和预算。但是,无论关键性是否强制使用它们,他们部署的技术对于任何开发团队而言都具有巨大的潜在利益。

错误类型和解决方法

在软件中可以找到两种关键类型的错误,并使用防止错误引入的工具进行了处理:

编码错误。一个示例是尝试访问数组范围之外的代码。可以通过执行静态分析来检测这些类型的问题。

应用程序错误。只有通过确切了解应用程序应该做什么才能检测到这些,这意味着需要进行测试。

编码错误和代码检查

静态分析是检测编码错误的有效技术,尤其是从项目开始部署时。一旦分析了代码,就可以查看不同类型的结果。在代码审查中,将根据诸如MISRA C2012之类的编码标准来检查代码,这是我们在本文中重点介绍的内容。

理想情况下,所有嵌入式项目都应使用安全语言(例如Ada)。Ada具有许多特性,可以强制执行思考过程,从而自然地减少错误(例如,严格键入)。不幸的是,很难找到具有Ada知识和经验的程序员,因此大多数公司都使用C/C ++。但是,即使是经验丰富的开发人员,这些语言也会带来陷阱。幸运的是,通过执行代码审查,可以避免大多数这些潜在的陷阱。

避免代码缺陷的最佳方法是避免将其放置在此处。这听起来很明显,但这正是编码标准所做的。在CC ++世界中,大约80%的软件缺陷是由错误使用大约20%的语言引起的。如果限制使用该语言以避免该语言的已知部分出现问题,则可以避免出现缺陷,从而大大提高软件质量。

C / C ++编程语言与语言相关的故障的根本原因是未定义的行为,实现定义的行为和未指定的行为。这些行为导致软件错误和安全问题。

作为实现定义的行为的示例,请考虑当有符号整数右移时的高阶位的传播。结果是0x40000000还是0xC0000000

 

某些C和C ++构造的行为取决于所使用的编译器

答案取决于您使用的是哪个编译器(图1)。可能是。函数参数的求值顺序未在C语言中指定。在图2所示的代码中其中rollDice()函数仅从持有值“ 1234”的循环缓冲区中读取下一个值),期望的返回值为1234。但是,没有为此,至少一个编译器将生成返回值3412的代码。

 

图2:某些C和C ++构造的行为未由语言指定

C / C ++语言存在许多类似的陷阱,但是通过使用编码标准,可以避免这些未定义,未指定和实现定义的行为。同样,使用诸如gotomalloc之类的构造会导致缺陷,因此可以使用编码标准来防止使用这些构造。混合有符号和无符号值时会发生许多问题,这在大多数情况下不会产生问题,但是有时可能会出现极端情况,即有符号的值溢出并变为负数。

编码标准还可以检查代码是否以特定样式编写。例如,验证未使用制表符,缩进是特定大小还是括号位于特定位置。这很重要,因为将需要进行一些手动代码审查,并且在其他选项卡字符大小不同的编辑器中查看代码时,奇怪的布局分散了审查者的注意力,使他们无法集中精力审查代码。

一些开发人员对编写聪明的代码感到内gui,这些代码可能是高效且紧凑的,但也可能是晦涩复杂的,这使得其他人难以理解。最好保持简单,让编译器负责制作高效的二进制文件。再次,使用编码标准可以帮助防止开发人员创建未记录且过于复杂的代码。

最著名的编程标准可能是MISRA标准,该标准于1998年首次发布给汽车行业。这些标准的普及反映在提供某种级别的MISRA检查的嵌入式编译器中。MISRA的最新版本是MISRA C2012,其页数几乎是其前身的两倍。这些附加文档中的大多数包含有关每个规则为何存在的有用解释,以及该规则的各种例外的详细信息。MISRA有几个准则,并且在适用时,它们包含对标准或未定义,未指定和实现定义的行为的引用。这样的一个例子可以在图3中看到。

 

图3:MISRA C引用了未定义,未指定和实现定义的行为

MISRA的大多数指南都是可判定的,这意味着工具应该能够识别是否存在违规行为。但是,一些准则是不确定的,这意味着工具并非总是可能推断出是否存在违规行为。例如,将未初始化的变量作为输出参数传递给应该对其进行初始化的系统函数时。但是,除非静态分析可以访问系统功能的源代码,否则它将无法在该功能初始化之前就知道该功能是否使用了该变量。如果使用简单的MISRA检查器,则它可能不会报告此违规,可能导致假阴性。或者,如果不确定MISRA检查器,则它可以报告违规情况,可能导致假阳性。什么是最好的?不知道可能有问题吗?还是确切地知道在哪里花费时间来确保绝对没有问题?当然,假阳性比假阴性更可取。

20164月,MISRA委员会发布了对MISRA C2012的修订,其中增加了14条准则,以帮助确保MISRA不仅适用于安全性至关重要的软件,还适用于安全性至关重要的软件。这些准则之一就是指令4.14,如图4所示,该准则有助于防止由于未定义行为引起的陷阱。


图4:MISRA和安全注意事项

应用程序错误和需求测试

应用程序错误只能通过测试产品是否达到了预期功能才能找到,这意味着有要求。避免应用程序错误既需要设计正确的产品,又需要设计正确的产品。

设计正确的产品意味着预先建立需求,并确保需求和源代码之间的双向可追溯性,以便已实现每个需求,并且每个软件功能都可以追溯到需求。任何缺少的或不必要的功能(不符合要求)也是应用程序错误。设计产品权利是确认开发的系统代码满足项目要求的过程,可以通过执行基于需求的测试来实现。

5显示了双向可追溯性的示例。在这个简单的示例中,选择了一个功能,并突出了从功能到低层需求,然后是高层需求,最后是系统层需求的上游可追溯性。

 

图5:双向可追溯性,已选择功能

在图6中,选择了一个高级需求,并且高亮显示了对系统级别需求的上游可追溯性和对低级别需求以及源代码功能的下游可追溯性。

 

图6:双向可追溯性,已选择要求

这种可视化可追溯性的能力可以导致在生命周期的早期发现可追溯性问题(应用程序错误)。

测试代码功能需要了解它应该做什么,这意味着具有低级要求来陈述每个功能的作用。图7显示了一个低级别需求的示例,在这种情况下,它完整地描述了一个功能。


图7:低级别需求示例

测试用例源自表1中所示的低级需求。


表1:来自低级需求的测试用例

然后使用单元测试工具在主机或目标上执行这些测试用例,以确保代码的行为符合要求。8显示所有测试用例均已回归并通过。

 

图8:执行单元测试

测试用例运行后,应测量结构覆盖范围,以确保所有代码都已执行。如果覆盖率不是100%,则可能需要更多的测试用例,或者有多余的代码应删除。

请输入搜索关键字

确定