继上一篇《从功能安全视角看软件架构设计》,架构阶段的下一个阶段是软件组件设计,这个阶段在功能安全软件设计开发中是一个容易被忽视的过程,实际过程经常是确定架构后就开始编代码了,后面再来补软件组件设计的文件。这里除了符合功能安全标准的符合性要求,从组件的可重用性、可测试性考虑,至少应在编码前确定各个软件组件的设计要求,想清楚了再实施,即每个组件所实现的预期功能、接口、安全完整性等级、算法和数据结构。
先回顾一下软件组件的定义,在ISO26262-6中第8节为software unit design and implemention(软件单元设计与实现),对于unit(单元)的概念,参见ISO26262-1 software unit和software component的定义如下:
units: atomic level software component of the software architecture that can be subjected to stand-alone testing
component: one or more software units
因此,单元是最基本的组件,一个或多个单元(基本组件)构成组件。
如上图,架构中的一个组件所实现的需求向下分解,确定为实现该需求的函数F11,F12,F13,实现的算法和数据结构,组件服务所依赖的库。
组件设计原则
在进行组件设计前,应明确以下设计原则:
以上原则仅是安全关键软件设计的一些基本要求,嵌入式安全软件常采用C语言编码,标准中认可的编程规范为MISRA C,最新版本为2012版。
软件设计时的错误来源于定义不当的结构、程序员意外的行为、实现人员的误解,该指南定义了C语言的子集,以避免或减少编程人员犯错的机会,用于开发与安全相关的软件的标准要求或建议使用,可以通过工具自动检查MISRA-C的符合情况。
MISRA C 规则摘要
标准中建议将编码规则转化为公司内部的编程指南,包括规则关联的SwSIL等级,规则来自标准条款,对规则的解释,规则使用的示例(列举一条正确使用的例子和不正确使用的反例),规则是建议满足还是必须满足,对规则的验证方法,如代码走查,工具静态分析,不遵循规则造成的影响,特别是对安全性的影响等。
组件测试
软件组件必须具备可测试性,虽然在ISO26262-6中在下一阶段进行组件验证,但在实际的软件项目中,组件级的测试伴随开发过程,因此在组件设计阶段有必要考虑组件测试的策略,以确认:
-
组件是否实现了其预期的功能(黑盒测试);
-
组件的内部function如何相互作用以执行预期功能(黑/白盒测试);
-
组件的所有组成部分都经过了测试(白盒测试)。
组件测试规范的确定,依赖于组件的需求规范,因此在组件设计时应考虑可测试性的要求,所以直接把代码交给做外包的测试公司,没有组件规格,即使做了也很难起到良好的效果。因此,比较好的实践方式是对组件熟悉的人来做测试,如开发人员互相测试对方的组件,组件之间存在接口的开发者互相进行测试,测试用例包括:
-
输入数据集,描述初始输入的一组数据,即软件算法不同路径的输入;
-
预期输出,描述组件在规定输入值下的预期结果。
如果软件组件的某些部分不可能定义测试,需要说明理由,并列出替代的验证方法。
测试覆盖率的度量方法在ISO26262-6 的table 9进行了规定,可参考EN50128 A.21对代码测试覆盖率的要求,规定更为详细。
结语
组件设计和测试作为安全软件开发中忽视的环节,经常导致一些低层次的bug没有被测出,在系统测试中花了很大力气解决。实际项目实施中,大家又会觉得组件设计和测试起不到作用,白费时间,这个不在于具体进行组件设计的软件工程师,在于软件架构师能否将标准中的要求理解到位,并转化为组件设计指南和规则,并在项目中对软件开发人员进行持之以恒的训练,提高其编码素质和安全意识。
本篇没有提到自动代码生成的组件设计,关于形式化语言规范及验证,与手工代码的开发有较大区别,留个话题,专开一篇聊。
原文始发于微信公众号(薄说安全):从功能安全视角看软件组件设计