3. 安全目标定义:从危害事件到安全目标

好,我们进入正题。上一章我们聊了危害分析与风险评估(HARA),拿到了危害事件清单。那下一步干什么?说白了,就是把每个危害事件,翻译成工程团队能执行的“技术指令”——这就是安全目标。

我见过不少团队,HARA 做得漂漂亮亮,一到定义安全目标就开始含糊。为什么?因为从“危害”到“目标”,中间缺了一层翻译。今天我们就来把这层窗户纸捅破。

3.1 什么是安全目标?

安全目标,就是针对每个危害事件,定义的最高层级安全要求。它回答一个问题:系统必须做什么(或不做什么),才能避免这个危害?

举个例子:

  • 危害事件:车辆在高速行驶时,制动系统意外失效,导致无法减速。
  • 安全目标:制动系统在车辆行驶过程中,必须按驾驶员意图提供制动力,不得出现非预期的制动力丧失。

你看,危害事件描述的是“坏事发生了”,安全目标描述的是“系统必须保证不出现这个坏事”。

核心原则:每个危害事件至少对应一个安全目标。一个安全目标可以覆盖多个危害事件,但反过来不行——别偷懒。

3.2 安全目标的属性

光写一句话不够。安全目标必须带属性,否则没法落地。我个人习惯,每个安全目标至少带四个属性:

属性 含义 典型值举例
ASIL 安全完整性等级,继承自危害事件的 ASIL ASIL D, ASIL C, ASIL B, ASIL A, QM
FTTI 故障容错时间间隔,从故障发生到危害发生的最短时间 10 ms, 100 ms, 500 ms
容错时间 系统从检测到故障到进入安全状态的最大允许时间 ≤ FTTI
安全状态 系统在故障后应进入的降级或停止模式 切断动力、维持转向、报警提示

嗯,这里要注意:FTTI 和容错时间不是一回事。FTTI 是“从故障发生到危害发生”的窗口,容错时间是“从检测到故障到进入安全状态”的窗口。后者必须小于等于前者,否则危害已经发生了,你进安全状态也没用。

我曾经踩过的坑:在一个 EPS(电动助力转向)项目中,我们把 FTTI 设成了 100 ms,但容错时间也设成了 100 ms。结果发现,故障检测本身就要 30 ms,留给响应的时间只有 70 ms,根本来不及。后来我们把容错时间压到 60 ms,才勉强通过验证。记住:容错时间要留余量。

3.3 从危害事件导出安全目标:三步法

我总结了一个三步法,每次做项目都这么走,基本不会漏:

  1. 提取危害条件:从危害事件中,找出导致危害的关键条件。比如“制动失效”、“转向卡滞”、“加速非预期”。
  2. 反向表述:把危害条件反过来,变成“系统必须避免……”。比如“制动失效” → “系统必须保证制动功能可用”。
  3. 补充量化约束:加上 ASIL、FTTI、容错时间、安全状态等属性。

举个例子,我们拿一个实际项目来走一遍:

危害事件:车辆在高速(>80 km/h)行驶时,EPS 系统输出非预期的大角度转向,导致车辆偏离车道,与相邻车道车辆碰撞。

第一步:提取危害条件

  • 条件 1:EPS 输出非预期转向
  • 条件 2:车速 > 80 km/h
  • 条件 3:导致车辆偏离车道

第二步:反向表述

  • 安全目标:EPS 系统不得输出非预期的转向角度,尤其是在车速 > 80 km/h 时。

第三步:补充量化约束

  • ASIL:D(因为涉及高速、碰撞、严重伤害)
  • FTTI:50 ms(从故障发生到车辆偏离车道的时间窗口)
  • 容错时间:≤ 40 ms(留 10 ms 余量)
  • 安全状态:切断 EPS 助力,维持机械转向,同时点亮报警灯

小技巧:FTTI 怎么定?我一般会拉上系统工程师和硬件工程师一起做“故障注入仿真”。在仿真里注入典型故障,看多久会触发危害。实测数据比拍脑袋靠谱得多。

3.4 安全目标与 ASIL 等级分解

安全目标定义好了,ASIL 也定了。但问题来了:一个安全目标往往要分配给多个子系统或组件去实现。比如“制动系统不得失效”这个目标,涉及 ECU、传感器、执行器、通信总线……每个组件承担一部分责任。

这时候就需要 ASIL 分解。分解的原则很简单:

  • 一个 ASIL D 的安全目标,可以分解为两个 ASIL C 的子系统要求,再加上冗余和独立性验证。
  • 分解后的每个子要求,ASIL 等级可以降低,但必须满足“足够独立”的条件。

ISO 26262 允许的分解方式:

原始 ASIL 分解方案 1 分解方案 2 分解方案 3
ASIL D ASIL C(D) + ASIL C(D) ASIL B(D) + ASIL B(D) ASIL D + QM(D)
ASIL C ASIL B(C) + ASIL B(C) ASIL C + QM(C) —
ASIL B ASIL A(B) + ASIL A(B) ASIL B + QM(B) —

注意括号里的字母,表示“这个子要求是从哪个等级分解下来的”。审核的时候,审核员会看这个。

避坑指南:分解不是万能的。如果你分解后两个子要求之间没有足够的独立性(比如共用同一个电源、同一个 MCU),那分解无效。我曾经在一个项目中,把 ASIL D 分解成两个 ASIL C,结果两个子系统共用同一个看门狗芯片——审核员直接打了回来。独立性,独立性,独立性,重要的事情说三遍。

3.5 安全目标定义流程总图

下面这张图,是我每次做安全目标定义时都会贴在墙上的。它把整个流程串起来了:

安全目标定义与ASIL分解流程 安全目标定义与 ASIL 分解流程 危害事件清单 安全目标定义(含属性) ASIL 等级分配 是否需要 ASIL 分解? 是 分解为子安全目标 否 直接进入功能安全要求 说明:分解后的子安全目标必须满足独立性要求,否则分解无效

3.6 实战中的常见问题

最后,分享几个我在项目中反复遇到的问题:

  • 安全目标写得太抽象:比如“系统必须安全”。这等于没写。安全目标必须可验证、可测试、可分配。
  • FTTI 拍脑袋:没有仿真或实测数据,全靠“我觉得”。结果后期验证发现根本达不到,只能返工。
  • 忽略安全状态定义:只写了“系统进入安全状态”,但没写具体是什么状态。结果开发团队各自理解,最后集成时发现对不上。
  • 分解后忘了验证独立性:分解方案写得漂亮,但实际实现中两个子系统共用同一个中断、同一个内存区域——独立性没了,分解白做。

我的习惯:每个安全目标定义完成后,我会拉上系统、硬件、软件、测试四个角色一起过一遍。每个人从自己的角度问三个问题:

  1. 这个目标我能实现吗?
  2. 这个目标我能验证吗?
  3. 这个目标有没有遗漏的约束?

通常一轮下来,能发现 30% 以上的问题。别省这一步。

好,安全目标定义这部分就聊到这里。记住:安全目标是整个功能安全开发的“宪法”,后面所有的设计、实现、验证,都要围绕它展开。定义得越清晰,后面的路越顺。