3、故障响应策略设计:故障响应等级划分与响应策略选择

各位工程师朋友,咱们今天聊聊故障响应策略。说实话,这是ECU设计里最考验功力的部分。我见过太多项目,功能逻辑写得漂亮,但一遇到故障就乱了阵脚。为什么?因为没想清楚「故障来了怎么办」。

我个人习惯,在设计阶段就把故障响应想透。别等到实车测试才发现问题,那代价就大了。

3.1 故障响应等级划分

故障来了,系统该怎么反应?不是所有故障都要「大动干戈」。我一般把故障响应分成三个等级:

等级 名称 说明 典型场景
Level 0 无影响 故障存在,但不影响当前功能 某个冗余传感器读数异常,但主传感器正常
Level 1 降级 功能受限,但系统仍可运行 摄像头被遮挡,ADAS降级为仅雷达工作
Level 2 安全状态 系统进入安全模式,停止部分或全部功能 刹车压力传感器失效,系统进入跛行回家模式

关键原则:能降级就别停机,能忽略就别降级。说白了,别让一个小故障把整台车搞趴下。

我在项目中遇到过一件事:某个客户要求所有传感器故障都进入安全状态。结果呢?一个雨量传感器偶尔误报,车就停在路中间了。用户体验极差。后来我们改成了「故障确认+降级」策略,问题才解决。

3.2 响应策略选择

等级定好了,接下来就是选策略。我常用的策略有四种,你想想看,每种都有它的适用场景:

3.2.1 忽略策略

适用于Level 0故障。故障存在,但系统可以继续正常工作。比如某个冗余通道的校验和偶尔出错,但主通道数据完好。这时候忽略它,记录日志就行。

我的经验:忽略不等于不管。一定要记录故障码,方便后续诊断。我曾经因为没记录,排查问题花了三天。

3.2.2 重试策略

适用于瞬态故障。比如CAN总线偶尔丢一帧,或者传感器通讯超时。我建议重试2-3次,如果还失败,再考虑其他策略。

/* 重试策略示例 - 伪代码 */
uint8_t retry_count = 0;
while(retry_count < MAX_RETRY) {
    if(read_sensor_data(&data) == SUCCESS) {
        break;
    }
    retry_count++;
    delay(10);  // 等待10ms后重试
}
if(retry_count == MAX_RETRY) {
    // 重试失败,进入降级或安全状态
    enter_degraded_mode();
}

3.2.3 切换策略

适用于有冗余设计的系统。主通道故障,切换到备用通道。我做过一个项目,双路刹车压力传感器,一路失效自动切到另一路。切换时间必须控制在10ms以内,否则驾驶员能感觉到。

注意:切换策略要处理好「切换抖动」问题。我见过一个案例,切换时信号跳变,导致控制器误判。解决方案是加一个平滑过渡滤波器。

3.2.4 停机策略

这是最后的手段。当故障严重到无法保证安全时,必须停机。比如电机控制器过流、电池热失控。但停机不是「啪」一下断电,而是有序地进入安全状态。

3.3 响应时间要求与实时性分析

响应时间,这是硬指标。我常说一句话:「故障响应晚1ms,可能就出人命。」

不同等级有不同的时间要求:

故障等级 典型响应时间 说明
Level 0 无严格要求 记录日志即可,后台处理
Level 1 50-200ms 降级动作要快,但不能影响主功能
Level 2 10-50ms 安全状态必须快速进入

嗯,这里要注意:响应时间不是拍脑袋定的。我一般会做实时性分析,用RTA(Response Time Analysis)工具跑一遍。核心是看任务的最坏情况执行时间(WCET)能不能满足要求。

避坑指南:我曾经犯过一个错误——只测了平均响应时间,没测最坏情况。结果量产之后,某个极端工况下响应慢了3倍。从那以后,我要求团队必须做WCET分析,而且留出30%的余量。

实时性分析有几个关键点:

  • 中断优先级:故障响应任务要放在高优先级中断里。我习惯把安全相关的故障检测放在最高优先级。
  • 任务抢占:低优先级任务不能阻塞高优先级任务。用优先级继承协议可以解决。
  • 资源竞争:多个任务同时访问共享资源时,要用互斥锁或临界区保护。

举个例子,我之前做的一个线控制动项目:

/* 故障响应任务 - 最高优先级 */
TASK(Fault_Response_Task) {
    while(1) {
        if(detect_brake_fault() == TRUE) {
            // 必须在20ms内完成
            enter_safe_state();
            set_system_status(SAFE_MODE);
        }
        WaitEvent(FAULT_EVENT);
    }
}

这个任务跑在10ms周期里,WCET实测是3.2ms,余量充足。但要注意,如果同时有其他高优先级任务,就要重新算。

最后说一句:响应时间设计不是一锤子买卖。随着软件迭代,任务执行时间会变。我建议每个版本都重新做一次实时性分析,别偷懒。

个人习惯:我会在代码里埋一个「故障响应时间监控」的hook。每次故障触发,自动记录响应时间。如果发现超限,立刻报警。这样量产之后也能持续监控。

好了,故障响应策略就聊到这儿。下一节咱们聊聊具体的故障诊断机制,包括故障确认、故障存储和故障恢复。这些东西串起来,就是一个完整的故障管理体系。