ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

机载软件适航符合性:需求追溯、MC/DC覆盖与工具鉴定

机载软件适航符合性:需求追溯、MC/DC覆盖与工具鉴定 民用飞机机载软件的适航符合性这话题在饭桌上讲基本没人爱听但在工程现场它是能决定一个项目生死的东西。很多人第一次听到“符合性”两个字脑子里浮现的是给软件跑一轮测试、出一份报告、盖个章然后就可以装机飞了。真到现场你会发现完全不是这么回事测试报告只是证据链里的一个环节真正被审的是你从项目第一天到交付那天整套工程活动的逻辑自洽和可追溯。我写这篇东西的出发点很简单——把我这几年在机载软件验证与审定对接上踩过的坑、理清的思路整理出来给刚入行的验证工程师、系统工程师、以及从互联网或消费电子转过来做航空软件的朋友一个可参照的框架。下面不谈空泛概念从“证明什么”开始一路讲到需求追溯、覆盖分析、工具鉴定、常见问题排查尽量把每个动作背后的理由说清楚。1. 先把问题摆正机载软件向谁证明什么1.1 “符合性”这个词的真实含义航空领域的“符合性”不是指软件质量好、bug 少、跑得稳而是指你声称做到的每一件事都有对应的证据且这些证据能够被独立的第三方复核。这里的第三方就是审定方派出的审查代表他们不关心你代码写得漂不漂亮关心的是你声明了哪些过程、这些过程的输出在哪、这些输出之间能不能对上、对不上的地方有没有解释。所以机载软件的适航符合性本质上是一份工程逻辑的自证材料。它的形式是一大堆文档、数据、记录、报告构成的生命周期数据集合它的内核是一条闭环的证据链。你可以在某个环节用很土的手工表格也可以用高度自动化的工具链只要证据链完整、可追溯、可复核都能成立反过来工具再先进、自动化程度再高追溯断了、评审记录缺了、问题报告没闭环一样过不了。搞清这一点后面所有的动作就都顺了。你在项目里做的每一件事都要问自己一句这件事将来谁来看他要从哪份材料里看到他能顺着材料找到上游和下游吗问不清这三个问题做的事情大概率是白做。1.2 从飞机级安全目标倒推到软件等级机载软件开发不是“先写代码再定要求”而是反过来的从飞机级的安全目标往下倒推。飞机级的功能危害评估先识别出各种失效状态判断每种失效状态的严重程度——是灾难性的、危险性的、较大的、较小的还是无安全影响。这个严重程度直接决定了系统的设计约束也决定了系统分配给软件的开发保证等级。行业里通常用 A 到 E 五个等级来对应这五种严重程度A 级对应灾难性失效状态要求最严E 级基本没有安全影响过程要求最宽。举个常见的例子电传飞控的主计算通道软件一旦失效可能导致飞机失去控制那它就是 A 级而客舱娱乐系统里的节目单管理软件失效最多让乘客看不了电影那大概率是 D 级甚至 E 级。这个等级不是给自己贴标签用的它直接决定后面每一个过程的严格程度A 级要做的目标数量最多B 级次之往下逐级递减。行业里常说 A 级对应七十余个目标实际数量以标准里的目标表原文为准不同版本和统计口径会有差异但那个量级的概念是对的。我见过新手最容易犯的错是拿 B 级甚至 C 级的做法去套 A 级项目前期省了力气到了审定介入阶段全部返工代价比一开始就按最高要求做还要大。1.3 为什么软件不能“测够了就算安全”硬件可以靠冗余、靠失效模式分析、靠疲劳寿命模型来说事软件不行。软件的状态空间是组合爆炸的几个整型变量、几个分支、几层嵌套就能凭空造出天文数字量级的执行路径。更要命的是软件失效往往不体现在“坏了”而是体现在“它按照一段谁也没想到的逻辑做了一件合理但错误的事”。我做过一个很典型的例子一个状态机在某两个事件同时到达时会走一条设计文档里根本没有画出来的路径——不是死循环也不是崩溃而是安安静静地用了一个过期的参数。这种问题靠随机测试几乎测不到靠代码走查也容易漏只能靠需求追溯和结构覆盖分析去把“未被执行过的逻辑”逼出来。正因为测不完航空软件工程才把重心从“测出多少 bug”转移到“过程是否可控、证据是否完整”。这不是对测试的否定而是承认测试的边界。你把过程的每个环节都做扎实才能让审定方相信即使有残留缺陷它的概率和影响已经被约束到了可接受的水平。2. 证据链的骨架四类生命周期数据怎么分工2.1 计划类数据先把“我要怎么做”说明白计划类数据是整条证据链的头部。它回答的是“这个项目打算怎么做、做到什么程度、谁来负责”。核心的一份是机载软件审定方面的计划文件业内通常叫 PSAC它向审定方声明软件的等级、生命周期过程、采用的标准、工具使用情况、以及打算提交哪些数据。PSAC 一旦基线化后面所有工作都要跟它对得上改 PSAC 是一件很重的事情。PSAC 之下还有一组计划软件开发计划说明开发流程、组织分工、进度基线软件验证计划说明验证策略、独立性安排、覆盖目标软件配置管理计划说明基线怎么建、变更怎么控、状态怎么记软件质量保证计划说明谁来做过程符合性检查、检查什么、记录在哪。除此之外还有三类标准文件——需求标准、设计标准、编码标准它们约束“写出来的东西长什么样”。提示这三类标准最容易被当成摆设。实际上它们是审查代表最爱翻的材料之一因为从标准就能看出你的团队是不是真的按统一规则在做还是每个人一套风格。标准写得越具体、越可执行后面追溯和评审越省事。2.2 开发类数据需求、设计、代码和它们之间的对应关系开发类数据包括软件高层需求、低层需求、软件架构与详细设计、源代码、可执行目标码以及参数数据项。这一层的核心不是文件本身而是它们之间的对应关系。高层需求必须能追溯到低层需求低层需求必须能追溯到设计设计必须能追溯到代码代码必须能追溯到目标码。很多团队在这一层栽跟头不是因为文件写得差而是因为颗粒度和编号规则没定好。常见的情况是需求编号到设计编号之间用了人工映射表前期改得动后期需求一变表就烂了。我的做法是在项目启动时就固定一套需求标识规则和追溯颗粒度比如每条低层需求必须对应至少一条高层需求每条设计单元必须至少承载一条低层需求任何一条落单都要在评审里给出理由。2.3 验证类数据评审、分析、测试三条腿验证类数据包括验证用例与规程、验证结果、各类评审与分析记录、追溯数据。这里要强调一点验证不等于测试。验证包含评审、分析、测试三类手段测试只是其中最贵、最耗时、也最容易被当成全部的那一类。评审用来发现需求和设计层面的问题分析用来处理那些无法通过执行来验证的内容——比如某些算法精度、某些时序约束、某些无法在目标环境中复现的边界条件测试用来验证可执行目标码的行为。三条腿缺一条验证的完整性就有缺口。我做过的项目里分析类证据经常是最薄弱的环节很多团队写不出像样的分析报告最后只能硬凑测试用例效率极低。2.4 支持类与审定联络类数据让整条链能被复核支持类数据包括配置索引、生命周期环境配置索引、问题报告、以及最终的那份软件完成情况总结业内叫 SAS。审定联络类数据则是整个过程中与审定方之间的往来记录、符合性矩阵、审查问题答复等。SAS 是最后交付的关键文件它把前面所有数据串起来向审定方说明目标是否达成、未达成的部分如何处理、各数据之间的关系是什么。符合性矩阵则把标准里的每一条目标与你的证据一一对应起来。这两份文件写得好不好直接决定审查代表能不能在有限时间里看懂你的项目。我见过技术做得很扎实、但 SAS 写得像流水账的项目审查时被反复追问白白多花好几周沟通成本。数据类别典型文件谁最关心常见坑计划类审定计划、开发计划、验证计划、配置管理计划、质量保证计划审查代表、项目经理与实际执行两套皮计划改了执行没改开发类高层需求、低层需求、设计说明、源码、目标码开发、验证、审查代表追溯颗粒度不统一编号规则中途变更验证类验证用例与规程、验证结果、评审记录、分析报告验证工程师、审查代表分析类证据缺失评审记录只有签名没有结论支持与联络类配置索引、问题报告、完成情况总结、符合性矩阵审查代表、审定联络人SAS 与前期数据不一致问题报告未闭环3. 把目标拆成可检查的动作追溯、覆盖与独立性3.1 需求追溯双向追溯的颗粒度怎么定双向追溯的意思是从任意一条高层需求能一路走到对应的测试用例从任意一条测试用例也能回溯到它验证的那条需求。听起来简单做起来最难的是颗粒度。颗粒度太粗一条高层需求对应十几条低层需求、几十个测试用例一旦出问题定位不到颗粒度太细每条需求拆成一句话追溯表变成几千行维护成本高得离谱。我的经验是按可独立验证的功能点来拆一条需求如果可以被单独设计、单独编码、单独测那它就是一个追溯单元。举个具体的例子“当空速大于阈值时系统在 50 毫秒内输出告警”可以拆成三条判定条件、时序约束、输出行为。这三条各自能测各自能追溯颗粒度就合适。3.2 结构覆盖分析语句、判定与 MC/DC 的差别结构覆盖分析是把“代码里哪些逻辑被执行过”这件事量化。等级不同要求不同最低等级通常要求语句覆盖中间等级要求判定覆盖最高等级要求修正条件判定覆盖也就是常说的 MC/DC。用一句生活化的话解释这三者的差别语句覆盖关心“每行代码有没有跑过”判定覆盖关心“每个 if 的真假两边有没有都走过”MC/DC 关心“每个判定里的每一个独立条件有没有单独决定过结果”。前两个容易达标第三个经常把人卡住。拿一段最常见的代码举例if ((a 0 || b 10) c OK) { /* 正常分支 */ }把三个条件记作 A、B、C判定结果是 X。判定覆盖只需要 X 为真一次、为假一次。MC/DC 则要证明 A、B、C 每个都能独立影响 X。下面这组用例可以做到用例Aa0Bb10CcOK判定结果证明的独立影响1真假真真基准用例2假假真假A 翻转导致判定翻转3假真真真B 翻转导致判定翻转4真假假假C 翻转导致判定翻转在工程里我不会把这类向量手工列完而是写脚本让工具去解算——尤其是判定复杂、条件多的时候人工挑向量几乎必然出错。我建议的做法是先用工具自动生成候选向量并给出覆盖报告再人工复核每个向量在业务上是否可达、参数是否合法。工具能告诉你“逻辑上覆盖了”但告诉不了你“这个输入在真实飞行中不可能出现”。3.3 验证独立性谁测、谁判、谁签字验证的独立性是适航里一个硬约束。简单说做验证的人不能是写这段代码的人做判定的人不能是被判定的那个人。等级越高独立性要求越强最低等级允许开发人员自己验证自己的代码中间等级要求验证人员与开发人员不同最高等级还要求验证人员在组织上、汇报关系上与开发相对独立。很多团队在这里吃亏。项目赶进度时让开发顺手把测试写了看起来效率高实际上这既违反了独立性要求也容易让测试用例继承开发人员的思维盲区——他写代码时没想到的边界条件写测试时同样想不到。我的做法是开发人员可以写单元级的自检脚本但正式的验证用例必须由独立验证人员重写或至少重新设计不能直接复用。3.4 问题报告闭环别让报告躺在系统里问题报告是整条证据链的胶水。每一个在评审、测试、代码走查里发现的问题都要有记录、有分析、有处理、有验证、有关闭。听起来是常识但实际项目里最常见的情况是问题报告开了几百条关了一半剩下的因为“影响不大”“下个版本处理”一直挂着到最后做 SAS 时才发现关不掉。我处理的方式是给每个问题报告定关闭判据要么代码改了并回归通过要么评估后确认不影响安全且给出了书面理由。任何一条问题报告不允许以“已知悉”状态结束。这样做前期累后期省心尤其是审定介入阶段审查代表翻问题报告列表时会一条条看闭环率是他判断项目成熟度的直接指标。4. 实操流程一次完整的符合性表明怎么推进4.1 阶段一计划基线与首次审查介入项目启动后第一件事是把软件等级确定下来然后基于等级裁剪标准里的目标集形成项目自己的符合性活动清单。这份清单会直接支撑 PSAC 的编写。PSAC 写完、内部评审通过后提交审定方通常会安排一次正式的介入审查业内常叫第一次阶段介入审查。这次审查的目标只有一个确认你的计划合理、等级判定正确、目标裁剪没有漏洞。审查代表会问得很细比如“这条目标为什么不适用”“这个工具你打算怎么处理”“验证独立性怎么保证”。我的经验是这一阶段多花两周把计划写扎实后面能省两个月。计划阶段的问题最好是问题一旦进入开发阶段再改计划牵动的数据量是成倍的。4.2 阶段二需求、设计与早期验证计划基线定下来后进入开发和早期验证。这个阶段的关键动作是需求编写与评审、架构与详细设计、编码、以及针对需求和设计的评审与分析。同时要建立配置管理基线把每一份输出的版本管起来。这个阶段我特别想强调需求评审的深度。很多团队的评审停留在“文档格式对不对、章节全不全”真正的技术评审很少。我推的做法是带着测试视角去评审需求读一条需求时当场问出至少三个边界场景。如果这条需求答不上来说明它本身就有歧义必须改。这个习惯能让后期验证用例的设计效率提高一大截。4.3 阶段三验证执行与覆盖分析进入验证执行阶段主要工作是把验证用例在目标环境上跑完收集结果做覆盖分析对未覆盖的部分逐条给出说明。这个阶段往往会有第二次阶段介入审查审查代表会看你的验证环境、看你的用例设计、看你对未覆盖代码的处理方式。未覆盖代码的处理是这个阶段最费脑子的部分。有些代码确实不可达比如防御性编程里的兜底分支、编译器插入的代码有些代码可达但需要特殊条件比如故障注入才能触发的路径。前者需要给出分析证据说明为什么不可达后者需要设计专门的测试方法去覆盖。具体怎么区分、怎么处理放到第 6 节展开。4.4 阶段四完成情况总结与最终审查所有验证做完、问题报告闭环之后进入收尾阶段整理配置索引编写软件完成情况总结编制符合性矩阵提交最终审查。这一步的工作量被严重低估——它不是简单地把前面文件拼起来而是一次全局一致性检查。我在这一步通常做三件事第一把符合性矩阵里每一条目标对应的证据实际打开看一遍确认文件版本是最新的、内容真的对得上第二把 SAS 里声明的每一句话跟前面的计划、验证结果做交叉核对任何对不上的地方要么改 SAS要么改数据第三把所有问题报告再过一遍确认没有漏关的、没有关闭理由含糊的。这三件事做完最终审查基本不会有大的意外。阶段主要输出关键动作审查形式计划审定计划、各类计划与标准等级确定、目标裁剪、计划评审首次阶段介入审查开发与早期验证需求、设计、源码、评审与分析记录需求深度评审、基线建立第二次阶段介入审查验证执行验证结果、覆盖分析报告用例执行、未覆盖项说明第三次阶段介入审查收尾配置索引、完成情况总结、符合性矩阵全局一致性核对、问题闭环最终审查5. 工具链与工具鉴定别让自动化工具偷走你的信心5.1 工具鉴定的判定逻辑自动化工具能极大提升效率但也带来一个新问题如果工具本身出错了它生成的证据还可信吗这就是工具鉴定要回答的事。判定逻辑其实很朴素就问两个问题这个工具的输出会不会被后续的验证活动检查如果工具出错会不会把错误引入最终产品或者掩盖掉本来能发现的错误如果两个答案都是“不会”那这个工具不需要鉴定把它当普通开发辅助工具用就行。如果工具输出直接进入产品、且没有任何后续活动能发现它的错误那它就需要做完整鉴定等级最高的那类工具要做的事情几乎等同于开发一个同等安全等级的软件——这代价非常大所以工具选型时要尽量避开这种组合。我见过团队稀里糊涂地把一个代码生成器用在了最高等级项目上直到审查阶段才意识到要鉴定临时补材料最后不得不改设计、把生成代码转入人工评审流程工期直接崩了。工具选型必须在计划阶段做而且要和等级一起考虑。5.2 工具链配置的几个实操考虑工具链选型我一般看四点一是功能覆盖度需求管理、追溯、测试管理、覆盖分析能不能在一个环境里闭环跨工具的数据交换最容易出错二是输出格式的可导出性证据最终要落到文档里工具的私有格式会让归档很痛苦三是脚本化能力批量操作、批量生成报告、批量校验追溯链这些都得靠脚本四是长期可维护性工具版本升级后历史数据能不能打开这个在长周期项目里特别重要。追的自动化我的建议是核心追溯链一定要有独立的校验脚本不能完全依赖工具自带的追溯矩阵。工具展示的是“它认为的追溯关系”而你要确认的是“实际文件里的标识符是否真的对得上”。我写过一个几十行的脚本定期扫描需求、设计、代码、测试用例里的标识符把孤立节点、断链、重复编号全列出来跑一次两分钟能省掉后期几周的排查时间。6. 常见问题与排查技巧实录6.1 覆盖率死活不达标怎么办这是最常被问到的问题。覆盖率卡住的原因通常有三类一是代码里有不可达分支比如防御性判断、编译优化留下的死代码二是测试用例本身设计不足没覆盖到某些条件组合三是代码结构过于复杂单个函数里嵌套太深条件之间耦合严重。排查顺序我建议从第三类开始先看结构。如果一个函数的判定条件超过四五个MC/DC 的向量需求会迅速爆炸而且很难保证所有组合在业务上可达。这时候应该回到设计层面把函数拆分降低单个判定的复杂度覆盖率自然就上去了。这是唯一一个“改代码比写测试更省事”的场景。处理不可达代码要谨慎不能自己下结论说“这段代码永远不会执行”就完事。要给出分析证据从需求层说明该分支对应的保护逻辑在正常和故障场景下都不需要触发从设计层说明该分支是编译器或框架引入的配合代码结构分析报告提交。我见过最省事的做法是把不可达分支用一个统一的记录表管理起来每条注明位置、原因、分析依据审查时直接给表比一次一次解释高效得多。6.2 追溯断链的排查顺序追溯断链的表象是“某条需求找不到对应的测试用例”或“某个测试用例找不到对应的需求”。排查时按这个顺序走先确认标识符本身有没有写错、有没有重号这是最容易出也最容易改的问题再确认是不是新加的需求没进基线、或者旧需求被删了但引用没清最后才怀疑是追溯关系本身设计有问题。我踩过一次坑需求编号里用了下划线和空格两种分隔符脚本按一种规则解析结果另外一半的追溯关系全部解析失败报了几百条断链实际代码一条问题都没有。后来我定了死规矩——标识符只允许大写字母、数字和连字符长度固定任何人不许例外。这个规矩让后面所有自动化校验的准确率几乎到了百分之百。6.3 需求变更引发的连锁返工需求变更是长周期项目的常态问题不在于变更本身而在于变更的传播没被控制住。一条高层需求改了一句话可能牵动低层需求、设计、代码、测试用例、覆盖分析结果、追溯矩阵、甚至计划文件里的描述。我的做法是给每次变更做一个影响清单逐项列出受影响的对象和处理动作处理完逐项签字。这个清单会成为配置管理记录的一部分也是向审查代表说明变更受控的直接证据。别小看这张清单它能防住大部分“改了这里忘了那里”的问题。问题现象常见根因处理动作覆盖率长期不达标判定嵌套过深、条件耦合严重拆分函数、降低单判定复杂度某段代码始终不可达防御性分支、编译器插入代码出具结构分析证据登记不可达清单追溯批量报错标识符规则不统一、脚本解析差异统一标识符规则固定长度与字符集变更后测试失效影响范围未识别完整建立变更影响清单逐项确认处理问题报告关不掉关闭判据不明确明确关闭条件禁止以“已知悉”结案7. 我在项目里总结的几条经验先说一条最反直觉的证据的可读性比证据的数量更重要。我见过一个项目提交了几千页验证数据每份都合规但审查代表看了两天还没搞清楚这些数据之间的关系最后要求项目组补一份数据关系说明。同样的内容如果每份文件开头有三五行的定位说明——这份文件解决什么问题、上游是什么、下游是什么——审查效率能提高数倍。这个习惯我从第二年开始养成后来所有文档模板里都强制加了这一段。第二条是关于“提前”的所有跟审定相关的事情都要提前一到两个阶段做。计划阶段把工具鉴定想清楚开发阶段把独立性安排清楚验证阶段把不可达清单理清楚收尾阶段就不会手忙脚乱。我在项目里给自己定了个规矩每到一个阶段结束就拿最终审查的视角把当前数据过一遍问自己“如果明天审定方来看我能解释清楚吗”。这个问题问下来总能提前发现几个大坑。第三条是关于人的适航符合性这件事从来不是一个人的工作它是开发、验证、配置管理、质量保证、审定联络几个角色的协同产物。任何一个角色缺位证据链都会有个缺口。我的建议是项目早期就把这几个角色的职责边界和交接物定义清楚交接物具体到“什么文件、什么粒度、什么时间、交给谁”。边界清楚返工就少边界模糊后面全是扯皮。最后分享一个具体的小技巧。我在做覆盖分析时会给每一个未覆盖项建一个编号编号规则和问题报告的编号统一然后在 SAS 里用一个表格把编号、位置、原因、证据、处理结论一次性列完。这套做法让审查代表不用一份份翻报告看一张表就能掌握全部未覆盖情况。用了这个方法之后我负责的项目在覆盖分析这一块的审查问询量下降了一大半效果非常直接。
返回列表