做功能安全的同行,这几年应该都有同一个感受:ISO 26262已经被客户、供应商、审核机构反复挂在嘴边,ASIL这个缩写几乎成了汽车电子圈里最常见的“安全等级标签”。但我发现,很多团队讨论ASIL的时候,注意力基本都停在“这个功能是ASIL D,那个功能是ASIL B”这种静态结论上,进了方案评审,又把ASIL当成一个需要应付的及格线,而不是作为设计决策的输入。这篇文章想把这些东西重新拆开:ASIL究竟是怎么评出来的,评完之后怎样落到架构、软硬件和测试里,以及项目实战中在哪些判断上最容易翻车。如果你正在做功能安全开发,或者常需要跟功能安全团队配合,这篇文章应该能帮你少走几条弯路。
1. 从QM到ASIL D:安全完整性等级的本质是“风险降低幅度”
1.1 安全不是“造出不坏的系统”,而是“残余风险可接受”
ISO 26262最核心的一个观念,是它不追求“永不失效”。任何电子系统都会失效,机械件会磨损,芯片会瞬断,软件会有逻辑缺陷,绝对安全在工程上不存在。标准要解决的是另一件事:把风险降到“可以被相关人群接受”的水平。
这里的“风险”等于危害发生的概率乘以伤害的严重度。ASIL(Automotive Safety Integrity Level,汽车安全完整性等级)就是用来量化“还需要额外做多少安全工作”的尺度。它分QM、A、B、C、D五档,其中QM表示按照成熟的质量管理体系来做就足够,A到D则需要逐步增加安全专用活动。ASIL D要求最高,通常对应那些一旦失效就可能导致严重甚至致命伤害的场景。
我在项目里常给团队打一个比方:假如你家在高楼,你会选择家里装烟感,但未必会装一套工业级消防喷淋系统。风险不同,防护等级不同。ASIL就是在替每一个功能决定它是装烟感、装喷淋、还是在大楼之外再安排一支消防队。
1.2 四个等级背后的“定量感觉”
ASIL不像普通的质量等级那样是一个模糊档位,它背后实际上对应着一个失效概率数量级。ISO 26262-10中有参考性的量化指标:ASIL A对应的随机硬件失效目标大约是10^-6/h,ASIL B和C约10^-7/h,ASIL D约10^-8/h。
可能有人觉得这些数字太抽象,那我做个粗略换算:10^-8/h意味着平均1亿小时才允许出现一次对应等级的失效,换算成年限超过一万年;10^-6/h则粗略相当于一百一十年一次。听到这里,你应该能理解为什么汽车电子不能像消费电子那样只追求“均匀随机失效少”,也不能简单等同于“争取多活几年”。它关心的是在一个庞大保有量的车群里,不良事件发生的总次数会不会超过社会可接受的范围。
不过要提醒一句,这个数量级只能帮你建立直觉,不代表可以用它去“证明”某个单点部件一定不会坏。实际上PMHF的计算要综合多个安全目标、多类失效模式,而且在做残余风险论证时还要考虑故障检测覆盖率、容错时间间隔、安全机制自身失效等一堆边界条件。这些后面会展开。
2. 三个参数决定一个ASIL:S/E/C评分是风险判断的起点
2.1 严重度S:伤害程度的等级划分
ISO 26262概念阶段的风险评估,主要通过三个维度完成:严重度S(Severity)、暴露率E(Exposure)、可控性C(Controllability)。
严重度S描述潜在危害对人员造成伤害的严重程度。S0是无伤害,S1是轻度或中度伤害,S2是严重但可能不危及生命的伤害,S3是危及生命或致命伤害。评分一般从“人会被怎样伤到”入手,而不是从“系统哪里会坏”入手。
举一个我熟知的BMS例子:动力电池高压回路绝缘失效,导致车身金属部件带电,此时司机或乘客无意间触碰到就可能触电,伤害很容易达到S3;而雨刮电机卡死导致雨刮不动作,顶多影响视野,危害通常停留在S1甚至S0。评分的时候,很多人习惯按“最坏情况”给分,这是不合适的。ISO 26262的评估要考虑“在当前使用场景下合理可预见的后果”,而不是用极端片面的故障树吓唬所有人。真实项目里S往往不像表面那么好评,关键是要把使用场景描述清楚,并且留记录。
2.2 暴露率E:人员处在危险情境中的时间占比
暴露率E衡量“潜在危险发生的场景,人员暴露在其中的概率或时间占比”。E0是几乎不暴露,E4是几乎每一次行车都可能遇到。
还是拿高压绝缘失效来说:车辆一启动,动力电池就持续与车身高压系统连接,绝缘失效带来的触电风险在整个行驶工况里都存在,E通常给到E3甚至E4。反过来,如果某个失效只在打开前舱盖维修时才出现,维修人员以外的人几乎不会暴露,E就是E0或E1,等级会明显下降。
E值的评估经常在团队里吵架,因为涉及“使用场景假设”:有人认为保守起见全部给E4,结果把本来ASIL B的功能评成了ASIL D,报价和开发成本涨一大截。这里我的建议是,把评估前置条件和场景假设全部写进安全档案,例如评估时刻写明“当前按普通乘用车的城市通勤、年均行驶里程和维修频次来评估”,既不拍脑袋过度保守,也不为了降成本故意调低。
2.3 可控性C:普通人能不能避开伤害
可控性C描述的是,当危害场景出现时,驾驶员或周围人员能否通过合理反应避免伤害。C0表示完全可控,通常可直接归入QM;C1是大部分驾驶员都能应付;C2是有相当一部分人能避免伤害;C3则是多数人不能避免,伤害基本无可躲避。
这里最容易犯的错,是用“赛车手”或“厂内测试工程师”的表现去评估普通用户。我遇到过有团队把方向盘转向失效的可控性评成C1,理由是“我认为司机能握紧方向盘打一把方向”。但冷静想想,高速上转向控制突然丢失,普通司机几乎没有反应时间,也没有足够的控制权限,这明显更接近C2甚至C3。可控性评估的对象必须是统计意义上的普通驾驶员,同时要考虑乘客、行人、维修人员等不同角色。
S、E、C三项通过标准的风险矩阵组合,最后会落在QM/A/B/C/D某个等级上。例如一个场景是“行驶中高压系统绝缘失效导致可接触金属部件带电,驾驶员无法感知、无法避免,且几乎全程暴露”,综合S3、E4、C3的组合,通常会落在最高的ASIL D,这也是为什么动力电池高压放电相关功能普遍被定为高等级的原因。
2.4 从评分到安全目标:写清楚“发生什么、多快反应、到什么状态”
评分结束之后,概念阶段的下一个动作是形成安全目标(Safety Goal)。安全目标不是“系统要安全”这种空话,它必须能指导设计。好的写法是:检测到某种故障事件后,系统应在多长容错时间间隔(FTTI)内,进入某个可验证的安全状态。
还是以BMS为例:安全目标可以写成“当检测到高压回路绝缘电阻低于安全阈值时,应在500ms内断开高压输出,并点亮绝缘故障警示”。这里面的“500ms”“断开高压输出”“点亮警示”都是可验证的指标。没有这些约束,ASIL评出来也只是纸面上的D,后面做软硬件开发时根本没法落地。
3. ASIL分解:高等级不是只能硬扛
3.1 为什么要做ASIL分解
当某个安全目标被评为ASIL D时,直接按D要求开发所有相关部件,成本高、周期长。ISO 26262-9允许做ASIL分解:把一个高等级的安全目标,拆到两条相互独立的机制或通道上,让每条通道承担较低的要求,只要组合起来仍然满足原始风险降低幅度。
最常见的分解逻辑是把ASIL D拆成两条ASIL C的通道,或者拆成一条ASIL D加一条ASIL A的备份通道;ASIL B也可以拆成两条ASIL A。核心原则是“总风险不能因为拆了就增加”。你可以把这个过程想象成两个人互相复核,复核后出错的可能性,要小于一个人独立处理。但前提是两个人之间不能共享同一个知识盲区——如果两人用同一套错题本、同一个思维习惯,复核就是形式主义。
3.2 独立性:ASIL分解的命门
因为分解依赖“互相独立弥补”,独立性就成了整个论证中最关键也最容易出漏洞的部分。两条通道不能共用同一个电源、同一个时钟源、同一颗MCU、同一路CAN收发器,更不能共用同一版完全相同的软件。任何共享的单一节点,都会把“两条通道”重新变回“一个公共点”,共因失效分析(Dependent Failure Analysis,DFA)就是专门用来排查这些共享点的。
我在审核现场见过最多的不符合项,基本都集中在这几个地方:两路电机驱动芯片虽然物理独立,但它们的供电来自同一个LDO;两套软件的版本完全一致,评审时认为“总有一条路能起作用”,可两套软件跑在同一个核上,一个死循环就让整套系统都停摆。做分解不是画架构图时把两个方框分开就完了,背后要有一份清单,把电力、时钟、软件、通信、工具链、开发团队都过一遍,确认哪些共享是可接受的,哪些必须切断。
3.3 分解不是免费的,有时不如直接做到高等级
不少人一看到ASIL D就觉得必须马上“分解”,这是另一个误区。分解需要增加一路完整的硬件通道,占用PCB面积,增加物料成本,还要额外做两条通道之间的比较逻辑,顺便把诊断和故障注入测试的量翻倍,这些开销有时候比直接按ASIL D开发一个简单系统还高。
我的建议是在系统架构评审阶段,就做一张“安全目标—安全机制—ASIL分配与分解”的矩阵表,把每个安全目标用哪些机制覆盖、每条机制分配到什么等级、是否需要独立性边界都写清楚。这张矩阵不只是给审核老师看,它最大的作用是让系统架构师、硬件工程师和软件工程师在同一张图上讨论问题。后续需求变更时,这张表也要同步回归,否则很容易出现某个安全机制悄悄被改弱的事。
4. ASIL从系统落到硬件和软件:等级要变成可计算的指标
4.1 硬件层:SPFM、LFM、PMHF和FMEDA
到了硬件设计阶段,ASIL会转化成一组客观的随机硬件失效指标。针对随机硬件失效,ISO 26262定义了单点故障度量(SPFM)、潜伏故障度量(LFM)和平均小时失效率(PMHF)。
先给一个目标参考表:
| ASIL等级 | SPFM目标 | LFM目标 | PMHF参考目标 |
|---|---|---|---|
| ASIL B | ≥90% | ≥60% | 10^-7/h |
| ASIL C | ≥97% | ≥80% | 10^-7/h |
| ASIL D | ≥99% | ≥90% | 10^-8/h |
SPFM衡量的是“危险的单点故障被安全机制检测或控制的比例”。举个例子,一个继电器驱动芯片统计出的全部危险失效为20 FIT,如果某个安全机制能诊断覆盖90%,那么残余的未被覆盖失效就是2 FIT,SPFM就是90%,勉强到ASIL B。想达到ASIL D,至少要求全覆盖到99%以上,那就得增加第二重诊断、加快检测速度,或者改变失效物理路径。
LFM衡量的是潜伏故障(比如RAM里的数据粘滞、时钟漂移这类平时不发作、一旦被触发才致命的失效)有没有被周期性诊断覆盖。它不像SPFM那样只关心单点失效,而是要关心那些“现在看起来没事、过段时间变成炸弹”的失效,被周期自检、内存读写测试等措施覆盖得怎么样。因此,SPFM高不代表LFM也高,很多团队只盯着覆盖失败的单个点,忘了给整个生命周期里的周期自检留预算。
PMHF则是把多个安全相关安全目标的硬件失效率按时间加权汇总,用来回答“整个系统在平均每个运行小时内,会不会超过那个数量级”的问题。这三项指标不是只靠估算就能交差,通常要基于FMEDA(故障模式、影响和诊断分析)来做。FMEDA是一张很长的表格,每种器件的每个失效模式都要列出失效率λ、失效分类(安全/危险/单点/潜伏)、有无安全机制覆盖、覆盖率为多少,最后加权算出指标。
做FMEDA时最烦的其实不是表格,而是失效模式和失效率数据从哪来。元器件厂商的数据手册里常常只有基础失效率,没有区分“开路卡死”“漂移超限”这种具体失效模式;标准里的部分参考数据又只覆盖典型类别。我的经验是,第一版FMEDA用相对保守的通用故障模式库把框架搭起来,然后把供应商能提供的失效率数据逐项替换进去,最后把不确定性在报告里明确标注。别为了数字好看而强行上调覆盖率,审核老师最爱沿着覆盖率反查设计,看安全机制是否真的能在FTTI内动作。
4.2 软件层:ASIL直接决定编码和测试强度
软件没有“随机失效率”一说,所以ASIL对软件的要求主要体现在开发流程上:很多措施从“推荐”变成“强烈推荐”,从“可做可不做”变成“没做就需要给出论证”。
实际开发中最明显的变化有三个。第一是编码规范,比如基于MISRA的规则集在ASIL等级高的模块里会限制更多用法,禁用递归、限制指针、强制显式类型转换检查。第二是程序流监测,ASIL C/D的软件往往要有独立于主逻辑的监控机制,例如窗口看门狗或程序流监测模块,用来发现执行流跑飞、死循环、关键函数没有按时执行等问题。第三是测试覆盖率,单元级的结构覆盖要求随等级提高:ASIL B通常要求语句覆盖,ASIL C往往要分支覆盖,ASIL D通常进一步到修改条件/判定覆盖(MC/DC)。
很多团队一整年忙下来,最后发现覆盖率报告不符合要求,原因不是测少了,而是测试用例压根没按需求建立追溯关系。覆盖率是一个结果证明,背后是需求、测试用例、代码行三者的对应。从一开始每个软件需求就挂测试用例,每个用例明确要覆盖哪些分支、哪些条件组合,到最后才能顺理成章拿到覆盖率闭环。如果只把测试堆在项目收尾阶段,MC/DC这种覆盖要求几乎不可能临时补上。
软件阶段的ASIL还会影响“隔离”需求。同一个MCU里可能同时存在ASIL D和QM的软件组件,ISO 26262要求做软件层面的共存性分析,必要时通过存储保护、内存分区、特权模式等手段避免低等级任务干扰高等级任务。这方面的判断同样要写进软件安全计划,不是功能跑通就能糊弄过去的。
5. 工程实践中的常见误区与经验复盘
5.1 误区一:拿到ASIL等级就堆安全机制,忘了反推需求
我发现很多新团队拿到一个被定位成ASIL D的功能后,第一反应是“我们得多加诊断”,于是这里加个监测,那里加个保护,整个系统越来越复杂。但安全机制的堆叠并不等于安全,每加一个新的安全机制,它自己也会失效,也需要被保护;复杂度上来之后,反而拉低硬件指标、拖慢软件验证。
正确做法是从安全目标反推:系统在什么故障下进入什么安全状态,FTTI是多长,要检测哪些故障,每个故障的安全机制应该检测出多少比例。先把这个链条拉通,再决定具体加什么。我手上做过的几个项目中,真正决定“做不做得了ASIL D”的往往不是某个诊断够不够强,而是整个系统找没找到明确、可实现的安全状态。
5.2 误区二:共因失效只在写文档时出现,没有落到设计里
独立性不足是审核重灾区。下面这张表是我整理的典型问题速查:
| 常见问题 | 原因 | 改进方向 |
|---|---|---|
| 冗余MCU共用同一个电源 | 供电设计只算功率,没做供电独立性 | 划分独立电源域,做掉电优先级测试 |
| 两路传感输入共用一颗ADC | 以为物理上多条路就是独立 | 用独立ADC或至少独立采样保持通道,并做输入隔离 |
| 分解后两路软件版本完全相同 | 统一代码仓库省事 | 让冗余路径用独立团队或不同实现,避免共同缺陷 |
| 周期性自检没有覆盖“保持状态”的潜伏失效 | 只做了完整读改写,没做定期状态刷新 | 对静态RAM做固定模式的周期扫描,对关键寄存器做回读比较 |
这些问题的本质,都是把“独立性”当成画图语言,而不是工程约束。要真正防止共因失效,必须在设计阶段做DFA,逐项列出公共资源清单,把“哪些共享合理、哪些必须打破”当成正式评审条目。
5.3 误区三:文档和实际开发两张皮
功能安全行业被很多人抱怨“全是文档”,但这个印象的来源,往往是有些团队把安全需求、FMEDA、安全档案当成代码写完之后的补作业,而不是项目过程的产物。安全档案要回答的其实就一个问题:你能不能证明,这条安全目标在软件需求里有对应、在代码里有实现、在测试报告里有验证?
我见过最好用的做法,是每个安全需求从创建那天就带一个唯一编号,这个编号像一条线一样贯穿系统需求、软件需求、测试用例、验证记录。评审的时候不用到处翻文档,打开编号就能看到完整证据链。这也意味着不容易出现某一个证据缺失。
顺便说一个轻踩过的坑:网上很多人搜“ISO 26262中文版PDF”,但标准条款在ASIL分解、共因失效这些关键概念上,翻译很容易丢失语境。如果是自己学习,可以参考中文解读;如果是为了评审和项目决策,建议始终以英文原版为唯一依据,哪怕英文吃力一些,也不要默认翻译版本表述准确。
5.4 给不熟悉功能安全的管理层讲清楚ASIL
如果你需要向项目经理或公司管理层解释ASIL,不要第一句话就说PMHF或者MC/DC。先用风险故事说明白:ASIL是一个业务决策输入,它衡量的是“万一这个功能出问题,会造成多严重的事故,发生的频率高不高,人能不能躲开”。再补一句:定成D不意味着产品更高级,只说明风险大,需要投入更多精力去控制。
这样管理层会更容易接受“为什么这个模块要增加成本、加长测试周期”。反过来,如果只把ASIL D当成一个技术标签,管理层看到的只有预算超支和延期,项目很容易被推着走向“先砍测试、后补文档”的死胡同。让决策者理解ASIL背后的风险逻辑,其实是最重要的一道管理屏障。
我个人做了这些年BMS和底盘控制器,最深的体会是,ASIL等级出来那一刻从来不是项目的结束,真正的麻烦在安全目标如何变成一条一条可验证的测试用例。如果一条安全需求最终在测试台上找不到对应的通过判据,那它基本就是一页纸上画出来的安全。最后分享一个比较有用的热身办法:新团队启动功能安全项目时,先挑一个功能粒度较小的模块,完整走一遍S/E/C评分、安全目标、ASIL分配、FMEDA、测试计划的闭环,哪怕这个模块本身最后只评到ASIL B也没关系,流程走通一次之后,你会突然发现后面那些ASIL D的大块头也没有想象中那么可怕。