2. 常见故障模型:硬件故障、软件故障、人为故障
做可靠性验证,第一件事就是搞清楚——你到底在防什么?
我见过不少团队,一上来就堆测试用例,结果漏掉最基础的故障模式。说白了,你连敌人长什么样都不知道,怎么打?
这一章,咱们就把常见的故障模型掰开揉碎。我按自己的习惯分成三大类:硬件故障、软件故障、人为故障。你想想看,系统出问题,跑不出这三类。
核心观点:故障模型是可靠性验证的“靶子”。靶子画不准,后面的测试、分析、定位全是白费功夫。
2.1 硬件故障:开路、短路、漂移
硬件故障是可靠性工程的“老本行”。我入行那会儿,师父就跟我说:硬件不会无缘无故坏,一定有物理原因。
常见的硬件故障,归纳起来就三种:开路、短路、漂移。咱们一个一个说。
2.1.1 开路故障
开路,就是电路断了。电流过不去,信号传不到。原因很多:焊点脱落、线缆断裂、过流烧断、振动导致接触不良……
典型表现:功能完全丧失。比如电源开路,设备直接掉电;信号线开路,通信中断。
我的经验:曾经有一款车载控制器,出厂测试全过,但跑到客户手里就间歇性死机。查了两个月,最后发现是连接器端子压接工艺有问题,振动后偶尔开路。从那以后,我要求所有连接器必须做压接剖面分析。
2.1.2 短路故障
短路,就是不该连的连上了。电流走捷径,轻则功能异常,重则烧毁器件。
短路的原因五花八门:锡渣残留、绝缘层破损、潮湿导致漏电、金属异物掉入……
| 短路类型 | 典型场景 | 后果 |
|---|---|---|
| 电源短路 | PCB 焊接桥连 | 烧保险、烧电源芯片 |
| 信号短路 | 排线相邻引脚粘连 | 数据错误、总线冲突 |
| 对地短路 | 电容击穿、绝缘破损 | 电平异常、功耗飙升 |
注意:短路故障的定位往往比开路更难。开路至少还能测通断,短路有时候是“软短路”——万用表量不出来,上电才现形。我建议备一台热成像仪,短路点通常会局部发热。
2.1.3 漂移故障
漂移,说白了就是参数变了。电阻值变大、电容容量衰减、晶振频率偏移、MOSFET 导通电阻增加……
漂移不像开路短路那么“暴力”,它是慢慢来的。今天还能用,明天性能下降,后天彻底失效。
为什么会这样?温度、湿度、老化、应力释放,都是元凶。
关键认知:漂移故障是可靠性验证中最容易被忽略的。很多产品出厂测试全合格,但用了半年后参数漂出规格,客户就投诉了。所以,高温老化测试和参数边界测试必须做。
2.2 软件故障:内存泄漏、竞态条件
软件故障,嗯,这话题我能聊一天。做了十几年系统,我最大的感受是:硬件故障往往有物理痕迹,软件故障纯粹是逻辑问题。
软件故障种类很多,但可靠性验证中最常碰到的,我挑两个重点讲:内存泄漏和竞态条件。
2.2.1 内存泄漏
内存泄漏,就是申请了内存不释放。一次两次没事,但跑久了,可用内存越来越少,最终系统崩溃。
我见过最典型的案例:一个嵌入式设备,运行 72 小时后必死机。查到最后,是某个中断服务程序里每次调用 malloc 但不 free。中断频繁触发,内存一点点被吃光。
// 典型的内存泄漏示例
void interrupt_handler(void) {
char *buffer = (char *)malloc(256);
// 处理数据...
// 忘记 free(buffer); // 泄漏就在这里
}
避坑指南:我曾经在一个项目中强制团队遵守“谁申请谁释放”原则,并且每次提交代码都要过静态内存分析。效果立竿见影,内存泄漏 bug 减少了 80% 以上。
2.2.2 竞态条件
竞态条件,就是多个任务同时访问共享资源,结果取决于谁先谁后。这种 bug 最难复现,也最难定位。
举个例子:两个线程同时写一个全局变量。线程 A 先读后写,线程 B 也先读后写。如果 A 读完之后、写之前,B 插进来写了,那 A 写回去的时候就把 B 的更新覆盖了。
// 竞态条件示例(伪代码)
int counter = 0;
// 线程1
void task1(void) {
if (counter < 10) {
counter++; // 这里可能被线程2打断
}
}
// 线程2
void task2(void) {
if (counter < 10) {
counter++; // 这里可能被线程1打断
}
}
注意:竞态条件的验证,靠常规功能测试基本没用。必须用压力测试和随机时序注入。我习惯在测试阶段故意把任务调度周期打乱,或者用多个 CPU 核同时跑,增加碰撞概率。
2.3 人为故障:操作失误
最后说人为故障。你可能会想:人又不是机器,出错很正常。但可靠性验证必须把“人”这个因素考虑进去。
人为故障,最常见的就是操作失误。比如:
- 维护时接错线
- 升级固件时断电
- 配置参数填错
- 维修后忘记装回屏蔽盖
我印象最深的一次:某通信基站批量掉线,查了三天,最后发现是现场工程师把光纤收发器的 TX 和 RX 接反了。你说这是硬件故障还是人为故障?
我的建议:可靠性验证中,一定要设计防呆测试。比如:接口做防反插设计、软件做参数合法性校验、操作流程做强制确认步骤。别指望人永远不出错,要假设“人一定会出错”,然后让系统扛得住。
2.4 三类故障的关联与验证策略
实际项目中,三类故障经常混在一起。硬件漂移导致软件时序异常,人为误操作触发短路……你很难孤立地看待它们。
| 故障类型 | 验证方法 | 定位手段 |
|---|---|---|
| 硬件开路/短路 | 边界扫描、ICT 测试、X-ray 检查 | 万用表、示波器、热成像 |
| 硬件漂移 | 高温老化、参数极限测试 | 数据趋势分析、统计过程控制 |
| 内存泄漏 | 长时间压力测试、内存监控 | 静态分析工具、堆栈跟踪 |
| 竞态条件 | 随机时序注入、多核并发测试 | 日志分析、断点调试 |
| 人为操作失误 | 防呆设计验证、操作流程评审 | 操作日志回放、故障复现 |
好了,这一章咱们把故障模型理清楚了。记住一句话:验证不是碰运气,是有的放矢。你知道敌人长什么样,才能设计出有效的防御手段。