8.2.4 软件可靠性与安全性设计

8.2.4 软件可靠性与安全性设计

不同于普通的消费类计算机电子产品软件,考虑卫星在轨长期稳定运行的需求和不便维修等原因,在软件开发过程中各环节都需要进行安全性分析和可靠性设计,避免潜在的可靠性风险,对识别的安全性关键和可靠性薄弱的环节采取特定的可靠性措施。

8.2.4.1 软件安全性分析方法

星载计算机软件通常采用基于故障树分析(FTA)和失效模式及影响分析(FMEA)的方式开展安全性分析。软件安全性活动贯穿星载计算机软件研制的全流程。

1)系统需求分析阶段

进行初步危险分析,提出软件安全性需求。

2)软件需求分析阶段

基于软件功能的故障树分析和失效模式及影响分析,得出软件安全关键功能,提出软件设计约束。主要从电源失效防护、系统加电检测、电磁干扰防护、空间单粒子防护、系统不稳定防护、接口故障防护、干扰信号防护和防止错误操作等方面进行考虑。

3)软件设计阶段

进一步开展基于软件模块的故障树分析和失效模式及影响分析,得出软件安全关键部件和单元,制定或选择软件设计参考准则,对安全关键功能的设计采取相应的软件可靠性设计措施,并提出软件安全性测试要求。主要从模块化设计(高内聚、低耦合)、资源余量设计、时序余量设计、参数检查和数据隔离等方面进行考虑。

4)软件编码实现阶段

根据设计阶段明确的安全关键部件和单元及其设计约束,开展安全关键部件和单元的安全性、可靠性设计,使软件安全性问题得到缓解或解决。

5)软件测试验证与确认

对软件安全关键单元和部件开展安全性单元和部件测试,验证软件设计安全性措施正确有效。对软件安全关键的功能开展安全关键性各项测试,确认软件安全关键功能得到保证。

8.2.4.2 软件可靠性设计要求

为保证软件长期在轨运行的稳定性,星载计算机软件需要采取必要的可靠性设计措施进行约束。软件可靠性设计要求包括通用类要求、中断设计要求、数据处理要求、与结构有关的程序设计要求、说明类要求、输入输出类要求、与高级编程语言有关的程序设计要求。

1)通用类要求

通用类要求适用于各类型处理器平台的软件,主要目的是避免在软件开发过程中的不良习惯导致软件设计中存在风险,主要包括:

(1)软件编码应当清晰易懂,不要为了“效率”而牺牲清晰。

(2)尽可能使用库函数,应注意硬件差异可能带来的影响。

(3)在编码前先设计,先用易于理解的伪码语言编写算法并分析评估。

(4)在设计前做好模块划分,并尽量做到各功能模块高内聚、低耦合。

(5)进行防错性程序设计,尽可能多地检测操作过程中的错误。

(6)要特别注意参数边界检查。

(7)软件源代码编译过程中出现的警告信息也要当成错误予以消除,除非在技术上确实有必要;无法回避的,在源代码中给出注释。

2)中断设计要求

中断处理要求约定了软件在中断设计时的注意事项,避免软件中断响应或处理异常,主要包括:

(1)未屏蔽的中断与绑定操作一一对应。对于软件未使用的中断,设置中断服务子程序陷阱,一旦误操作时,执行相应的可靠性措施,如主动咬狗复位。

(2)分析中断嵌套时对共享数据访问的影响,避免自身的中断嵌套。

(3)检查中断优先级的设置是否合理,注意实时性要求高的中断不能被处理时间长的中断打断。

(4)主流程关闭中断保护后,避免其他中断处理时,又把该中断打开。

(5)处理器端和外部中断产生端设置相同的脉冲触发或电平触发方式,以免丢失中断。

3)数据处理要求

数据处理要求规范了软件编码时对具体的业务数据处理时应注意的事项,避免软件设计出现潜在的逻辑缺陷,主要包括:

(1)无符号数做减法运算时,应当确保被减数大于等于减数,避免减出一个超大数。

(2)防除零设计,进行连续乘除运算时,尽量保证除法在前、乘法在后,确保不会溢出。

(3)对于影响软件控制流程的缓变的状态参数如电压参数等,进行多个软件周期连续条件判断成立,才切换相应的状态或执行相应的应急操作,避免状态来回抖动或误操作。

(4)判断数据计数到位尽量避免==判断,而采用>=或<=判断;判断浮点数相等时,不能采用a==b,而应当采用(a>=b)&&(a<=b)。

(5)安全关键信息必须使用强数据类型表示。不得使用一位的逻辑“0”或“1”来表示,建议使用4位或4位以上,既非全“0”又非全“1”的独特模式来表示,以确保不会因无意差错而造成的危险。

(6)对于接收的遥控指令、注入数据等,需要进行累加和、数据一致性、数据范围校验通过后才执行,否则丢弃不执行,并下行相应的遥测状态参数。

(7)对于周期性处理的数据,当出现异常情况导致节拍错位错误时,要及时进行数据节拍同步、及时修正错误,避免后续节拍出现连续错误。

(8)长期驻留的、参与重要流程控制的参数应当识别为关键参数,并定期进行三取二维护;可以按字节或按位的方式进行三取二处理,通常首先按字节三取二,按字节三取二失败再按位三取二;对于安全关键参数,按位三取二之后还应当做参数范围判断,避免三取二失败出现错误结果引起系统安全性问题;除EEPROM操作外,比对两份数据一致后,应当回写第三份数据。

(9)配对处理:禁止同一组配对出现在不同的模块中;若同种配对所在模块分布在多任务或多线程中,则必须进行时序同步设计和同步分析;禁止无嵌套机制的配对性操作嵌套。配对性操作包括禁中断、开中断,禁EDAC、开EDAC,堆栈入栈、堆栈出栈等。

(10)对于安全关键的系统控制流程,可以通过设置关键路径参数来避免错误传递,判断前一个流程已执行才执行当前流程,否则认为是发生了飞程序,自主咬狗复位,避免故障扩大;对重要错误处理流程分别进行计数并设置关键遥测,一旦发生错误,通过遥测可以对错误处理路径和原因进行准确定位。

4)与结构有关的程序设计要求

与结构有关的程序设计要求主要对程序分支语句的设计加以约束,避免出现潜在的软件逻辑错误,主要包括:

(1)尽量简化逻辑设计,避免重复冗余的不必要的分支。

(2)使用括号以避免运算表达式因结合顺序而产生的二义性。

(3)判定条件中的逻辑组合个数不宜超过7个。

(4)各模块间的耦合逻辑应尽量简单。

(5)避免因节省空间而把多个语句写在一行。

(6)过程和函数的输入输出参数个数不宜超过7个。

(7)在对同一个标志型变量进行判断时,软件前后应当采用统一的判断标准,避免出现非真非假时导致前后逻辑不统一。

5)说明类要求

说明类要求主要对程序编码时变量命名和注释加以约束,避免对软件功能设计产生误解,主要包括:

(1)使用有意义的、不易混淆的变量名,如index、temp、count等,避免使用i、j之类的变量名。

(2)保持注释和程序一致,在修改代码时同时更新注释。

(3)注释应当简单明了且精炼,起到辅助理解程序代码的目的。

(4)程序的格式安排应有助于理解,括号应对齐。

6)输入输出类要求

输入输出类的要求主要是对程序的输入输出参数的处理加以约束,避免外部数据错误导致程序出现不可预知的错误,主要包括:

(1)在设计时应检查输入参数的合法性和无二义性。

(2)对外部接口输入的参数应当按照接口协议约定从严判定其有效性,采取如比较特定值、限幅等措施。

(3)识别错误的输入,并尽可能地纠正错误;若不可纠正,则应当立即终止后续处理流程。

7)与高级编程语言有关的程序设计要求

以目前最常用的高级编程语言C语言为例,对编码规范加以约束,主要包括:

(1)注意区分==和=,与常数比较时使用“数值==变量”的形式。

(2)尽可能减少使用指针数据类型,使用前必须检查其有效并在合理范围内。

(3)访问数组前必须检查下标范围。

(4)尽可能减少使用全局变量作为模块间通信手段;如果使用,就必须分析是否需要互斥访问。

(5)调用函数后应检查函数的返回值,获取函数实际的返回结果。

(6)if语句后的语句块、循环语句的循环体,必须用花括号包围。

(7)++或--运算符不得与其他运算符混合使用。

(8)逻辑运算符&&或||的右操作数不得带有副作用,如++、--等操作。

(9)所有非空的Switch子句都应该以break语句结束。

(10)Switch的最后一个子句必须是default子句,如果default中没有包含任何语句,那么应该有注释来说明为什么没有进行任何操作。

(11)禁止使用goto语句,慎用continue语句;如果使用,就必须注明期望退出到哪里。

(12)除非特别需要,函数禁止递归调用;如果由于技术上的需要必须使用递归算法完成迭代时,那么必须有措施保证迭代深度不超过必要限制。

8.2.4.3 自测试设计

在软件上电启动时,为避免硬件接口错误导致软件功能异常,通常会在初始化流程中加入硬件资源和外部接口等自测试功能,并将测试结果通过遥测参数反馈地面。若涉及设备安全的功能测试失败,则应禁止相关功能操作,由地面决策,确认无误后可通过指令的方式重新启动相关功能。

软件在轨运行时,也可以通过地面发送遥控指令的方式启动自测试流程,软件依次遍历相关硬件状态,通过遥测参数反馈自检结果,便于地面维护人员进行故障诊断。