1. 先把"适航符合性"这层窗户纸捅破
机载软件适航符合性这个话题,圈外人听着像天书,圈里人一提起多半也是一脸苦笑——这几个字背后,是几十项需要逐一交代清楚的目标、成堆的生命周期数据,以及以年计的审定沟通。前阵子在一次行业技术交流上,有位做飞控软件的兄弟半开玩笑地说:"我们写的不是代码,是证据。"这句话其实把它说透了。
这里说的机载软件,指的是装上飞机之后会参与飞行控制、航电显示、通信导航、发动机管理等功能的软件,它和地面上的普通应用软件完全是两套玩法。适航符合性,说白了就是要向适航审定方证明:这套软件在预期的运行环境和失效场景下,不会带来超出可接受范围的风险。它不是一次性的验收测试,而是一整套从需求说起、贯穿开发全过程、最终形成可追溯证据链的活动。
适合读这篇的人大致有三类:刚进入航空软件领域、被"符合性"三个字搞得一头雾水的工程师;做系统或软硬件接口、需要理解软件侧审查逻辑的人;还有准备参与审定沟通、想提前摸清门道的项目管理者。下面我尽量用大白话把底层逻辑讲清楚,也会给出一些实操层面的细节和踩坑经验。
1.1 机载软件为什么不能像硬件那样直接做实物试验
硬件有个天然优势——看得见摸得着,能做疲劳试验、能测寿命、能拆解失效件做分析。软件不一样,它没有物理磨损,你没法通过"跑到一定小时数"就宣布它可靠。软件的失效几乎全部来自逻辑缺陷:需求写漏了、代码写错了、时序设计有漏洞。这些缺陷不会因为多跑几遍就消失,反而可能在某个特定输入组合下突然冒头。
所以机载软件的符合性从来不是"测够了就行",而是要在设计阶段就控制缺陷的进入,在验证阶段把缺陷尽量找出来,还要能证明"找的过程"本身是可信的。这就是为什么软件符合性强调过程——你没法只靠最终产品判断软件够不够好,只能靠过程的可信度来背书。
还有一个现实因素:软件几乎可以零成本地被修改,今天改一行代码,明天就可能是另一个产品。正因为变化太容易,才需要一套严格的构型管理和更改控制,让每一次改动都能追溯到需求、追溯到验证证据。这一点和硬件的"改了要重新做试验"逻辑是相通的,只是软件把它做成了流程约束。
1.2 软件符合性的本质:拿过程和证据说话
很多新手会问:飞机上的机载软件到底怎么"表明"自己符合适航要求?答案不是交一份测试报告完事,而是构建一条完整的证据链,让审定方能够独立判断你的软件是"可控的"。这条链的每一环都要能回答三个问题:这个需求从哪来、它是怎么被实现的、它又是怎么被验证的。
换个生活化的类比:这就像装修一套房,你不是找物业说一句"我装好了",而是要交出施工图、材料清单、水电改造记录、隐蔽工程照片、验收单,让人相信房子住着不会塌。机载软件也一样,需求文档是施工图,设计是结构图,代码是材料,测试是验收记录,构型管理则保证这些文件从头到尾是同一套、没有被偷偷改过。
这里的关键在于"可追溯性"。从系统级需求拆到软件高层需求,再拆到低层需求,然后对应到设计、代码、测试用例,最后到测试结果,这条线必须是通的、闭合的。任何一处断裂,在审定眼里都是风险点。我见过不少项目栽在追溯矩阵上:需求改了,测试用例没同步,或者节奏一乱,追溯表就成了"事后补"的东西,补出来的表基本经不起追问。
2. 定级:软件符合性工作量的总开关
在聊具体怎么表明符合性之前,必须先讲清楚软件等级,因为它是决定后面一切工作量的总开关。同一套流程,A级软件和D级软件的工作要求可能差出一倍不止。很多项目在起步阶段对定级认识不足,后期才发现验证深度要求远超预期,返工代价极大。
2.1 五个等级从哪来
软件等级不是软件团队自己拍脑袋决定的,它由系统层面的安全性评估过程分配下来。系统工程师先做功能危害评估,分析每个功能的失效会对飞机和人员造成什么后果,再依据后果的严重程度给功能定级,软件作为功能的实现载体,继承相应的等级。这件事属于系统工程范畴,软件团队更多是"接单方",但绝不能当甩手掌柜。
等级大致分五档。A级是最严的,失效会导致最严重的后果;B级次之;C级对应较严重的后果;D级对应较轻的后果;E级则是基本没有安全影响的软件。举例来说,直接参与飞行控制的软件通常落在A级或B级,而一些仅用于客舱信息显示、出问题也不影响飞行安全的软件可能在C级甚至D级。
这里有个常见的误区:有人觉得"等级越高越安全,干脆都按A级做"。这种想法在工程上不现实,A级的工作量、验证深度、文件要求都是最高的,把D级软件按A级做纯属浪费资源,还会打乱整个交付节奏。正确做法是尊重系统安全性评估的结论,该是哪级就是哪级,同时留意等级可能会随系统设计变更而调整。
2.2 等级如何影响后面每一步
等级的影响是全链条的,不是只影响测试。它决定了你要满足哪些目标、验证要做多深、覆盖分析要做到哪一档、工具要不要鉴定、构型管理的严格程度。以结构覆盖为例,最高等级会要求做到修正条件判定覆盖,也就是常说的 MC/DC;往下一级可能只要求判定覆盖;再往下可能只要求语句覆盖。这几档的测试用例数量和投入完全不是一个量级。
我个人的经验是,在项目早期就把等级相关的目标清单拉出来做成一张表,逐条标注适用与否,这样后面做计划和预算时心里有数。最怕的是做到一半才发现某个目标没覆盖,那时候补的成本非常高,因为很多证据是"过程性"的,过了那个阶段就再也补不回来。
另外,等级还影响审定方参与的深度。等级越高,越可能需要在早期就提交规划类文件、越需要频繁的沟通和阶段评审。这不是麻烦,反而是一种保护——早期把方向对齐,总比后期大面积返工要好。
3. 表明符合性的骨架:过程、目标、证据
讲完定级,就可以进入正题了。机载软件表明适航符合性,国际上有一套成熟的方法论,核心逻辑可以概括成三块:一套必须执行的软件生命周期过程、一批必须满足的目标、以及用来证明目标已满足的生命周期数据。这三者构成了整个符合性工作的骨架。
3.1 三类过程撑起整个框架
这套方法论把软件活动划分为三大类过程。第一类是规划过程,负责在动手前把"怎么做"定下来,包括软件审定计划、开发计划、验证计划、构型管理计划、质量保证计划等。规划类文件是整个体系的顶层设计,它们告诉审定方你打算如何满足要求。
第二类是开发过程,也就是把需求变成可运行软件的过程,涵盖需求定义、架构设计、详细设计、编码和集成。开发过程的核心是各级需求和它们之间的追溯关系。第三类是综合过程,包括验证、构型管理、质量保证和审定联络。综合过程不直接生产软件,但它保证了软件是被"正确地验证、受控地变更、可信地交付"的。
这三类过程不是并列关系,而是交织在一起的。规划过程定规则,开发过程产生产品,综合过程负责检查和背书。理解这个分工,就不会把验证简单等同于"最后测一下",也不会以为构型管理只是"存个档"。
3.2 目标与符合性矩阵:把"做到了没"变成可查的表
这套方法论的精髓在于"目标"这个概念。它不规定你必须用什么工具、什么方法,而是列出一批"目标",比如"高层需求要可追溯""低层需求要精确且可验证""代码要符合标准""结构覆盖要达到规定程度"等。你的任务是针对每一个目标,说明自己是怎么满足的,并附上证据。
这就引出了符合性矩阵。它是一张表,横轴是各等级对应的目标,纵轴是你采用的方法和证据来源。这张表的价值在于把"我们做得很规范"这种模糊说法,变成"目标几号,用何种活动满足,证据在某份文件的某节"这种可核查的表述。审定时,双方基本就是围绕这张表逐条过。
我特别想强调的是,目标数量随等级递减。最高等级需要满足的目标最多,往下逐级裁剪,到最低的安全相关等级只剩二十几项,而几乎没有安全影响的等级基本不涉及。具体数目各方资料略有出入,做项目时要以标准原文和审定方的确认为准,不要凭记忆。
3.3 生命周期数据:证据的载体
被满足的目标要靠"生命周期数据"来承载。生命周期数据可以理解成软件从生到死产生的所有受控文档和记录,大致分为计划类、开发类、验证类、构型管理类、质量保证类和审定联络类。每一份数据都是证据链上的一环。
这里有个容易忽视的点:生命周期数据本身就是需要被评审和受控的。不是说你写了一份测试报告就完事,这份报告要经过评审、纳入构型管理、有版本记录、有批准记录。如果报告是"事后补"的,评审记录和变更记录对不上,审定方一眼就能看出来。
还有一个关键文件叫软件成就摘要,它在项目收尾时把"我们满足了哪些目标、还有哪些没满足、为什么可以接受"整体交代一遍。这份文件相当于给整个符合性工作做一个自我介绍,写得好能省下大量沟通成本,写得含糊则可能引发一连串追问。
4. 从需求到验证:生命周期实操里的关键动作
骨架讲完,落地到日常干活,真正决定成败的是生命周期各阶段的细节执行。这一章我按开发顺序讲几个关键动作,重点放在容易踩雷的地方。
4.1 需求阶段最容易埋雷的地方
软件需求分高层需求和低层需求。高层需求描述软件要做什么,通常由系统需求分解而来;低层需求描述软件怎么实现,往下就对应到代码。需求阶段最大的雷是"需求写得不够精确、无法验证"。比如需求里出现"及时响应""尽量稳定"这类词,验证时根本没法判定通过与否,审定方也会直接质疑。
我的经验是,每一句需求都要能回答"我拿什么证明它被满足了"。如果一句话说不清楚验证方法,那多半是需求本身有问题。另外,需求的可追溯性是重中之重:每条软件需求都要能追溯到上层的系统需求,同时要被至少一个测试用例覆盖。这种"向上可追溯、向下被覆盖"的双向关系,是需求评审最常被盯的地方。
还要注意需求的完备性。漏掉一条边界条件的需求,可能就漏掉一整组测试用例,进而导致覆盖分析不达标。实际项目里,需求评审最好拉上验证人员一起做,让写测试用例的人提前介入,很多"不可验证"的问题能在早期暴露出来。
4.2 设计、编码与可追溯性
设计阶段把需求转化成架构和详细设计。这里讲究的是设计与需求的对应关系——每个设计元素都应该服务于某条需求,反过来每条需求都应该有设计来落实。编码阶段则要遵守编码标准,编码标准的作用不是"好看",而是规避那些已知容易出错的写法,比如隐式类型转换、不可达代码、危险的指针操作等。
在规模稍大的项目里,代码评审和静态分析是标配。静态分析能在不运行代码的前提下发现一批潜在问题,属于"低成本的缺陷拦截"。但要注意,静态分析报告也是证据的一部分,报告里的告警要么被修掉,要么要给出不修的理由,不能直接忽略。
可追溯性在这一阶段体现得最具体:需求、设计、代码、测试用例四者之间要能对得上。我见过最省心的做法,是从项目一开始就用工具管理追溯关系,每次变更自动更新关联项。也见过最痛苦的做法,是用表格手工维护,改一条需求要手动改好几处,时间一长必然对不上。工具选型这件事,值不值得投入,取决于项目规模和变更频率。
4.3 验证方法与结构覆盖:语句、判定、MC/DC
验证是重头戏。常用的验证方法有三类:评审、分析和测试。评审靠人来判断文档的正确性,分析靠工具或推理证明某些性质,测试靠运行软件观察结果。三者各有适用场景,不是所有目标都能用测试来满足。
结构覆盖则是验证深度的量化指标,也是审定时最容易被追问的部分。它衡量的是测试用例对代码结构的覆盖程度,从浅到深大致分几档。最浅的是语句覆盖,要求每一条可执行语句都被执行过;往上一档是判定覆盖,要求每个判定的真、假两个分支都被走到;最深的是修正条件判定覆盖,要求每个判定里的每个条件都能独立影响判定结果。
为什么最高等级要求做到这么深?因为浅层覆盖会漏掉一类隐蔽缺陷:某个条件被短路求值掩盖了,导致它的取值变化根本没有影响最终结果,表面看测试全过了,实际这个条件形同虚设。MC/DC 就是要逼出这种情况,让每个条件都被单独"验证过"。
4.4 覆盖分析的实操细节
做覆盖分析有几个实操要点。第一,覆盖分析要基于测试用例执行的真实结果,不能手工"标注满足"。有些团队为了赶进度,人工判定"这条分支跑到了",这种做法在工具化审定时很容易被识破,风险极高。
第二,达不到的覆盖要能给出合理解释。比如某段防御性代码在正常场景下永远不可达,这类"死代码"要么删掉,要么说明其存在理由,必要时通过专门的分析手段证明它不会带来风险。不能简单地"覆盖不到就算了"。
第三,覆盖工具本身也需要被关注。如果工具的输出被直接用作符合性证据,那工具的可信度就成了问题,这就引出了下一章要讲的工具鉴定。很多团队第一次做高等级项目时,都是在这一环上栽跟头。
5. 工具鉴定与参数数据:最容易被低估的两块
如果说前面的内容是主线,那工具鉴定和参数数据就是两条容易被忽视、却又绕不开的支线。它们在最高等级项目里几乎是必答题,在其他等级里也常常是加分或减分的分水岭。
5.1 工具鉴定等级怎么判
先说工具鉴定。软件开发过程中会用到大量工具:编译器、需求管理工具、测试工具、覆盖分析工具、静态分析工具等。这些工具如果只是"帮人干活",人还能复核它的输出,那它的可信度就不那么关键;但如果工具的输出直接被当作符合性证据,而人无法或不去复核,那工具本身的缺陷就可能让证据失效。
这就是工具鉴定的逻辑:依据"工具输出是否被直接依赖"以及"依赖程度",判定工具需要做到什么样的可信级别。级别越高,对工具的开发过程、验证、配置管理等要求越严,做工具鉴定的成本和周期也越可观。反过来,如果能让工具的使用方式变得"始终有人复核",就可以把工具的鉴定要求降下来。
我的实操建议是:在规划阶段就把所有工具列出来,逐一评估它的输出会不会被直接引用为证据。能通过流程设计降低依赖的,就降低依赖;确实必须鉴定的,提前排期,别等验证都做完了才想起来工具还没鉴定。
5.2 参数数据项与结构覆盖分析工具的取舍
再说参数数据。有一类软件的行为不是靠改代码,而是靠改配置参数来调整的。这类"参数数据"同样会影响软件行为、同样可能有安全问题,所以也需要纳入符合性活动,比如参数数据的正确性要验证、变更要受控。它容易被漏掉,是因为大家习惯性地把它当成"配置"而非"软件"。
结构覆盖分析工具的取舍也值得单独讲。这类工具能自动算出覆盖结果,省下大量人工,但它的输出往往直接被引用为证据,因此如果用它,基本就要面对鉴定问题。有的团队会选择"工具算出结果,人工抽样复核关键分支",以此降低对工具的绝对依赖。这个平衡点怎么找,取决于项目等级、规模和团队能力,没有标准答案,但一定要在早期想清楚。
6. 符合性证据的组织与审定配合
前面讲了怎么做,这一章讲怎么"交"。证据组织得好不好,直接影响审定沟通的效率。很多技术做得很扎实的团队,最后卡在证据组织上,非常可惜。
6.1 生命周期数据清单怎么盘
第一步是把生命周期数据清单盘清楚。按计划、开发、验证、构型管理、质量保证、审定联络六大类列出所有受控文件,标明版本、状态、评审和批准记录。这张清单要和符合性矩阵对应起来,让每个目标都能指向具体的证据文件。
盘清单时有个实用技巧:按"审定方会怎么问"来组织,而不是按"团队内部怎么存"来组织。内部文件夹结构往往很乱,审定方不会去你的目录里翻,所以要专门整理一份面向审定的证据索引。索引要清晰到"第几章第几节",最好带上页码,减少对方来回找的时间。
6.2 与审定方打交道的经验
沟通这件事,我的体会是"早、准、实"。早,指早期就提交规划类文件、早期确认关键假设,别憋到最后一次性交出大堆材料。准,指问题要问得具体,不要泛泛地问"这样行不行",而是带着方案问"我打算这样做,是否满足某目标"。实,指证据要落到实处,避免用漂亮话掩盖具体缺失。
还有一点:审定提出的问题,回答要直接,别绕。如果某个目标确实没满足,就给出不满足的理由、替代措施和风险评估,坦诚比含糊更容易获得理解。我见过因为一句含糊表述被追问半年的案例,后来发现其实问题并不大,只是当时没讲清楚。
7. 常见问题与排查技巧实录
这一章把实际项目里反复出现的坑整理成快查表,方便对照排查。
| 常见问题 | 典型表现 | 排查思路 | 处理建议 |
|---|---|---|---|
| 需求不可验证 | 出现模糊词汇,测试用例写不出通过判据 | 逐条需求追问"拿什么证明" | 重写需求,补充量化边界 |
| 追溯链断裂 | 需求改了,测试用例和设计未同步 | 用追溯矩阵逐项核对双向关系 | 尽量用工具自动维护追溯 |
| 覆盖不达标 | 某些判定分支长期未覆盖 | 分析是由测试不足还是死代码导致 | 补测试或说明并证明无风险 |
| 工具未鉴定 | 工具输出直接引用为证据 | 列出所有工具,评估输出依赖度 | 降低依赖或提前安排鉴定 |
| 参数数据遗漏 | 配置改动未纳入受控和验证 | 盘点所有影响软件行为的配置项 | 纳入生命周期数据统一管理 |
| 证据事后补 | 评审和变更记录对不上 | 检查记录时间线是否合理 | 过程性证据要边做边留 |
| 等级判断偏差 | 验证深度与等级要求不符 | 与系统安全性评估结论核对 | 早期对齐等级并锁定目标清单 |
除了表里的内容,再补几个独家经验。第一,"边做边留痕"是铁律,过程性证据一旦错过时间点就补不回来,我踩过最大的坑就是验证做完了才想起来评审记录没签。第二,把最挑剔的人拉进评审,让他提前问刁钻问题,比审定当天被问住强得多。第三,别迷信"工具能解决一切",工具能提高效率,但不能替你承担符合性责任。
最后分享一个我在实际项目中的体会:机载软件适航符合性的核心,说到底是"把不确定变成确定、把隐性的东西变成显性的东西"。每一次需求澄清、每一份评审记录、每一行可追溯的测试用例,都是在把风险从暗处搬到明处。这个过程确实繁琐,但当你真正把证据链理顺了,那种"心里有底"的踏实感,是任何捷径都换不来的。这个方向后续还可以往模型化开发和形式化方法延伸,等有精力我再单独整理一篇实操笔记。