2、故障模式与影响分析(FMEA)

各位工程师,咱们今天聊聊FMEA。这玩意儿,说白了就是「事前诸葛亮」。

我做了十几年嵌入式医疗设备,见过太多产品在客户手里出问题。有些问题,其实在设计阶段就能发现。FMEA就是干这个的——提前把可能出故障的地方找出来,评估风险,然后想办法堵住漏洞。

2.1 FMEA基础概念

FMEA,全称是Failure Mode and Effects Analysis。翻译过来就是「故障模式与影响分析」。它不是一个高深的理论,而是一套实用的方法论。

我个人习惯把FMEA理解成三件事:

  • 这东西会怎么坏?(故障模式)
  • 坏了会怎样?(影响分析)
  • 我们能做什么?(改进措施)

举个例子。你设计一个输液泵的电机驱动电路。你得问自己:

  • 电机如果堵转了,会怎样?
  • 驱动芯片如果过热,会怎样?
  • 电源如果突然掉电,会怎样?

每个问题都要回答,而且要写在纸上。嗯,这里要注意,别光在脑子里想。我见过太多工程师说「我想过了」,结果真出问题时,发现根本没想全。

FMEA的核心指标有三个:

指标 含义 评分范围
严重度(S) 故障发生后,对患者或设备的影响程度 1~10
发生度(O) 故障发生的可能性 1~10
检测度(D) 现有手段能发现故障的概率 1~10

三个分数相乘,得到风险优先数(RPN)。RPN越高,越需要优先处理。

关键点:医疗设备中,严重度(S)是红线。只要S≥9,不管RPN多低,都必须采取措施。这是法规要求,没得商量。

2.2 硬件故障模式

硬件故障,说白了就是物理层面的损坏。我在项目中遇到过各种奇葩情况,但归纳起来,无非三种基本模式。

2.2.1 开路

开路,就是电路断了。电流过不去,信号传不了。

常见原因:

  • 焊点虚焊、脱落
  • 导线断裂
  • 保险丝熔断
  • PCB走线腐蚀

影响分析:

  • 信号通路中断,功能丧失
  • 如果是电源开路,整个系统掉电
  • 如果是传感器开路,可能读到错误值

避坑指南:我曾经遇到一个血氧仪,偶尔报错「传感器故障」。查了三天,最后发现是排线插座的一个引脚虚焊。温度一高,接触不良。从那以后,我所有设计都要求加「开路检测」电路。比如上拉电阻,让MCU能检测到信号线是否断了。

2.2.2 短路

短路,就是不该连的地方连上了。电流乱窜,后果往往很严重。

常见原因:

  • 焊锡桥接
  • 元器件引脚碰在一起
  • 潮湿环境导致漏电
  • 金属碎屑掉在PCB上

影响分析:

  • 电源短路,可能烧毁保险丝或电源芯片
  • 信号线短路,数据出错
  • IO口短路,可能损坏MCU

特别注意:医疗设备中,电源短路是最危险的。如果短路发生在患者连接部分,可能造成电击。我建议所有电源输出都要加限流保护,而且限流值要低于安全标准。

2.2.3 漂移

漂移,就是参数慢慢变了。元器件老化、温度变化、湿度影响,都会导致漂移。

常见场景:

  • 电阻值随温度变化
  • 电容容量衰减
  • 运放偏置电压漂移
  • 晶振频率偏移

影响分析:

  • 测量精度下降
  • 定时不准
  • 控制环路不稳定

你想想看,一个血压计的传感器如果漂移了,测出来的数值可能差20mmHg。这在临床上会误导医生判断。

2.3 软件故障模式

软件故障,比硬件更隐蔽。硬件坏了你能看到冒烟,软件坏了,你只能看到屏幕卡住。我吃过不少软件的亏。

2.3.1 死锁

死锁,就是两个任务互相等对方释放资源。结果谁也动不了。

典型场景:

  • 任务A持有锁1,等待锁2
  • 任务B持有锁2,等待锁1
  • 两个任务永远等下去
// 死锁示例(伪代码)
Task_A() {
    take_lock(lock1);
    take_lock(lock2);  // 等lock2
    // 干活
    release_lock(lock2);
    release_lock(lock1);
}

Task_B() {
    take_lock(lock2);
    take_lock(lock1);  // 等lock1
    // 干活
    release_lock(lock1);
    release_lock(lock2);
}

解决方法:我个人的习惯是,所有任务按固定顺序获取锁。比如总是先拿lock1再拿lock2。这样就不会死锁。另外,用超时机制也很重要——拿不到锁就报错,别死等。

2.3.2 内存泄漏

内存泄漏,就是申请了内存不释放。系统跑着跑着,可用内存越来越少,最后崩溃。

为什么嵌入式设备特别怕这个?因为内存本来就小。一个监护仪跑24小时,如果每小时泄漏1KB,24小时就是24KB。对于只有128KB RAM的系统来说,这已经不少了。

常见原因:

  • malloc后忘了free
  • 链表操作中节点没释放
  • 中断服务程序里申请了内存

避坑指南:我曾经维护过一个老项目,设备运行72小时后必死机。查了整整一周,发现是一个定时器回调函数里,每次调用都new一个对象,但从来没delete。72小时正好把内存耗光。从那以后,我要求所有代码必须做内存泄漏检测,而且跑压力测试至少跑满7天。

2.3.3 看门狗超时

看门狗,是嵌入式系统的最后一道防线。程序跑飞了,看门狗会复位系统。

但看门狗超时本身,也是一种故障模式。它说明系统已经不正常了。

常见原因:

  • 主循环卡死在某个任务里
  • 中断频率过高,主循环没机会跑
  • 死循环或无限等待
  • 喂狗代码放在了错误的位置
// 错误的喂狗方式
void main_loop() {
    while(1) {
        feed_watchdog();  // 一进来就喂狗
        // 这里如果卡死,看门狗不会复位
        do_some_work();   // 可能卡在这里
    }
}

// 正确的喂狗方式
void main_loop() {
    while(1) {
        do_some_work();   // 先干活
        feed_watchdog();  // 干完活再喂狗
    }
}

特别注意:看门狗不是万能的。它只能复位系统,但解决不了根本问题。我见过一个产品,看门狗频繁复位,工程师觉得「反正能复位,没事」。结果呢?设备在手术中复位了。你说这后果谁担得起?

所以,看门狗超时应该被当作一个严重故障来处理。每次复位都要记录原因,分析根因,彻底解决。

好了,FMEA的基础概念和常见故障模式就讲到这里。下一节我们会聊怎么具体做FMEA分析,以及怎么根据分析结果设计容错机制。记住一句话:故障是不可避免的,但灾难是可以避免的。