3. 功能安全基础:ISO 26262标准、ASIL等级、故障处理机制

各位同学,咱们今天聊聊功能安全。说实话,我刚入行那会儿,觉得功能安全就是个「流程活儿」,不就是填表、写文档嘛。直到有一次,我在一个ADAS项目中,亲眼看到因为一个时序错误,导致系统在关键时刻没响应——嗯,从那以后,我再也不敢小看功能安全了。

3.1 ISO 26262:汽车功能安全的「宪法」

ISO 26262,全称是《道路车辆功能安全》。它不是什么高深的理论,说白了就是一套「如何避免电子系统出人命」的工程方法。它覆盖了从概念设计、系统开发、硬件软件,一直到生产、运行、报废的全生命周期。

我个人习惯把ISO 26262分成三块来看:

  • 管理层面:谁负责、怎么管、文档怎么走
  • 技术层面:怎么设计、怎么验证、怎么测试
  • 支持流程:工具链、配置管理、变更管理

你想想看,一个刹车系统,如果软件出了bug,车停不下来,后果是什么?ISO 26262就是确保这种「万一」不会发生。

核心原则:ISO 26262不是让你「不出错」,而是让你「出错后系统依然安全」。这个思路很重要。

3.2 ASIL等级:风险有多高,要求就有多严

ASIL,全称是Automotive Safety Integrity Level,汽车安全完整性等级。它分四个等级:ASIL A、B、C、D。D是最严格的,A是最宽松的。还有一个QM(Quality Management),意思是「按质量管理做就行,不用特殊安全措施」。

ASIL等级怎么定的?看三个因素:

  • 严重度(Severity):出事后人受伤有多重?轻伤、重伤、致命?
  • 暴露率(Exposure):这种情况发生的概率高不高?天天遇到还是十年一次?
  • 可控性(Controllability):驾驶员能不能在出事前补救?能轻松控制还是完全失控?

举个例子。安全气囊的控制器,一旦失效,后果是致命的(严重度高),而且你没法提前预判(可控性低),所以它通常是ASIL D。而一个车窗升降系统,就算坏了,也就是窗户关不上,不会出人命,所以它可能只是ASIL A,甚至QM就够了。

ASIL等级 典型应用 硬件故障率要求 开发严格度
QM 信息娱乐、导航 无特殊要求
ASIL A 尾灯控制、门锁 < 10⁻⁶ /小时 中低
ASIL B 制动灯、雨刮器 < 10⁻⁷ /小时
ASIL C 自适应巡航、自动紧急制动 < 10⁻⁸ /小时
ASIL D 线控制动、转向、安全气囊 < 10⁻⁹ /小时 极高

我的经验:在FPGA设计中,ASIL D的项目,我建议从一开始就做「双轨冗余」架构。别想着后期再补,那成本翻倍都不止。

3.3 故障处理机制:出了事怎么办?

功能安全不是「不出故障」,而是「出了故障也能安全处理」。ISO 26262把故障分成几类:

  • 单点故障(SPF):一个元件坏了,直接导致安全目标被违反。
  • 潜伏故障(LF):一个故障存在,但没被发现,直到另一个故障出现才暴露。
  • 多点故障(MPF):多个故障同时发生,才导致安全问题。

那怎么处理呢?常用的机制有:

  1. 故障检测:比如CRC校验、ECC内存、看门狗定时器。我做过一个项目,用FPGA内部的CRC模块做数据通路校验,延迟只多了两个时钟周期,但安全性提升了一个等级。
  2. 故障响应:检测到故障后,系统要进入安全状态。比如切断动力输出、点亮故障灯、切换到冗余通道。
  3. 故障容错:即使有故障,系统还能继续工作。比如三模冗余(TMR),三个模块同时计算,取多数结果。

注意:故障处理机制本身也可能出问题。比如看门狗如果自己坏了怎么办?所以「诊断覆盖率」这个概念很重要——你的检测机制能覆盖多少比例的故障?

3.4 在FPGA中落地功能安全

FPGA做功能安全,跟MCU不太一样。MCU是固定的硬件,你只能靠软件做诊断。FPGA呢?你可以自己设计硬件安全机制。

我常用的几个方法:

  • 冗余设计:关键路径用双模或三模冗余。比如状态机,我习惯用三模冗余加投票器,虽然面积大了三倍,但ASIL D的覆盖率能到99%以上。
  • 在线监控:用FPGA内部的逻辑分析仪IP,实时监控关键信号。一旦发现异常,立即触发中断。
  • 定期自检:在系统空闲时,运行内置的自检程序。比如用LFSR生成测试向量,检查逻辑门的输出是否正确。
// 一个简单的三模冗余投票器示例(Verilog)
module voter #(
    parameter WIDTH = 8
)(
    input  [WIDTH-1:0] data_a,
    input  [WIDTH-1:0] data_b,
    input  [WIDTH-1:0] data_c,
    output [WIDTH-1:0] data_out,
    output reg         error_flag
);

    // 两两比较
    wire ab_eq = (data_a == data_b);
    wire bc_eq = (data_b == data_c);
    wire ac_eq = (data_a == data_c);

    // 多数表决
    assign data_out = (ab_eq) ? data_a : 
                      (bc_eq) ? data_b : 
                      (ac_eq) ? data_a : 
                      {WIDTH{1'bx}};  // 全不一致,输出未知

    // 错误检测
    always @(*) begin
        if (ab_eq & bc_eq & ac_eq)
            error_flag = 1'b0;  // 全部一致,无故障
        else if (ab_eq | bc_eq | ac_eq)
            error_flag = 1'b1;  // 有一个不一致,检测到故障
        else
            error_flag = 1'b1;  // 全不一致,严重故障
    end

endmodule

避坑指南:我曾经在一个项目中,把投票器放在组合逻辑里,结果时序分析没过。后来改成寄存器输出,才搞定。记住:投票器最好用寄存器打一拍,避免毛刺。

3.5 小结

功能安全不是「加个看门狗就完事」那么简单。它是一整套从需求到验证的闭环。ISO 26262给了你框架,ASIL给了你目标,故障处理机制给了你手段。在FPGA里做功能安全,优势在于你可以灵活定制硬件安全机制,但代价是设计复杂度上升。

下一章,我会聊聊AMD自适应计算平台里,具体怎么用硬件加速功能安全机制。到时候我会拿一个实际案例来拆解,保证干货满满。