第 15 讲 | 量产测试与老化:出厂前必须跑通的那 8 项
【本讲要点】出厂坏一台,售后成本可能是售价的 10 倍。这一讲给出产测固件设计与出厂前的 8 项必测。
一、先算一笔账
一台设备出厂卖 100 元。如果它出厂时是坏的:
| 客户投诉、退换物流 | 30 元 |
| 售后人力(诊断 + 处理) | 50 元 |
| 换新机成本 | 100 元 |
| 品牌信誉损失 | 无法估量 |
一台坏机的处理成本轻松超过 200 元,是售价的 2 倍以上。 如果坏机率是 3%,那就是 100 台里亏 6 台的利润。
而这 3% 里的绝大多数问题,在出厂时用 5 分钟就能测出来。
二、量产测试和研发测试不一样
最容易犯的错:把研发阶段的测试脚本直接拿来量产。 两者目标完全不同:
| 目标 | 找 bug、验证功能 | 快速筛出不良品 |
| 时间 | 可以跑几小时 | 每台 1~5 分钟 |
| 输出 | 详细日志 | 一个 PASS / FAIL |
| 操作者 | 工程师 | 产线工人 |
| 自动化 | 手工 | 必须自动化 |
核心原则:产测要"快、自动、结果明确"。
三、出厂前必测的 8 项
1. 上电自检(Power-On Self-Test)
设备一上电,自动跑一遍硬件自检:
typedef struct {
uint8_t flash_ok : 1;
uint8_t ram_ok : 1;
uint8_t uart_ok : 1;
uint8_t sensor_ok : 1;
uint8_t rf_ok : 1;
uint8_t key_ok : 1;
uint8_t led_ok : 1;
uint8_t rtc_ok : 1;
} selftest_t;
selftest_t g_selftest;
void selftest_run(void)
{
/* Flash:读回校验 */
g_selftest.flash_ok = (flash_self_check() == 0);
/* RAM:写读模式测试(注意只能用未使用的 RAM 区!) */
g_selftest.ram_ok = (ram_march_test() == 0);
/* UART:回环测试(TX 短接 RX 或内部回环) */
g_selftest.uart_ok = (uart_loopback_test() == 0);
/* 各传感器:读一次,判断是否在合理范围 */
g_selftest.sensor_ok = sensor_read_plausible();
/* 按键:检测是否有按键被卡住(长按) */
g_selftest.key_ok = !key_stuck();
/* LED:全亮全灭 */
g_selftest.led_ok = led_test();
log_info("selftest: 0x%02x", *(uint8_t *)&g_selftest);
}
注意 ram_march_test 的坑:千万不能测正在使用的 RAM 区,否则会把栈/堆写坏。只能测 linker 预留的"未使用 RAM"区域。
2. 通信压力测试
这是最能提前暴露问题的测试。
/* 产测模式:连续收发 N 次,统计成功率 */
void prod_comm_stress_test(void)
{
uint32_t err = 0;
for (int i = 0; i < 200; i++) {
/* Modbus 回环 / WiFi 上报一帧,等 ACK */
if (comm_roundtrip() != 0) {
err++;
}
vTaskDelay(pdMS_TO_TICKS(20));
}
/* 判定标准:200 次里错误不能超过 2 次 */
prod_result(err <= 2);
}
判定标准要基于实测数据定(比如真机上跑 1000 台,统计后拿到基线),不能拍脑袋。
3. 内存长跑测试
泄漏是"跑几天才炸"的问题,出厂测试必须能提前发现。
void prod_mem_test(void)
{
uint32_t h0 = xPortGetFreeHeapSize();
/* 让所有任务都转 100 圈 */
for (int i = 0; i < 100; i++) {
comm_roundtrip();
sensor_read();
app_tick();
vTaskDelay(pdMS_TO_TICKS(10));
}
uint32_t h1 = xPortGetFreeHeapSize();
/* 堆不应减少(允许少量波动) */
prod_result(h0 – h1 <= 8);
}
这个测试能在 10 秒内抓出"每次操作泄漏几个字节"的问题——而这类问题在现场是灾难。
4. 上下电测试
专门验证参数保存与掉电保护。
① 写入一组参数 → 断电 → 上电 → 读回,确认一致
② 升级到一半断电 → 上电 → 确认仍跑旧固件(第 13 讲)
③ 连续快速上下电 20 次 → 确认每次都正常启动
配套工具:产测治具要能自动控制继电器给设备上下电。
5. 高低温测试
- 低温:参数漂移、晶振起振困难、LCD 无显示;
- 高温:Flash 写入可靠性下降、电池充电异常、通信误码率上升。
至少做 3 个温度点(比如 -10℃ / 25℃ / 60℃),每点稳定 30 分钟后测通信。
6. 老化测试(Burn-in)
这是筛"早期失效"的唯一手段。
| 时长 | 48~72 小时 |
| 条件 | 通电 + 持续通信 + 反复读写 |
| 判定 | 全程零复位、零通信中断、内存无泄漏 |
| 抽检 | 通常抽检(如 5%),高风险产品全检 |
老化测试必须记录"复位次数"(第 10 讲的复位原因统计在这里发挥作用):
/* 老化结束时读取 */
if (boot_count > 0 || watchdog_reset_count > 0) {
log_error("burn-in FAIL: reset %u times", boot_count);
prod_result(0);
}
老化能筛出:焊接虚焊、元件早期失效、Flash 坏块、晶振不稳。这些在常温下测不出来,但会是现场投诉的主力。
7. OTA 升级测试
每一台出厂前都要跑一遍完整 OTA 流程(第 13 讲):
下载 → 校验 → 重启 → 试运行 → 确认 → 再升回原版本
为什么要在出厂测? 因为 OTA 涉及的 Flash 操作、Bootloader 跳转、参数区读写,是最依赖"这颗芯片的 Flash 是否健康"的功能。Flash 有坏块的芯片,平时的功能全正常,只有升级时才暴露。
8. 接口与按键功能测试
- 每个按键功能正常(不能有卡键、失灵);
- 每个接口(USB、扩展口)通断正确;
- LED、蜂鸣器、显示屏工作正常。
这一项通常由治具自动完成(治具驱动按键、读反馈)。
四、产测固件设计
产测模式的实现方式有两种:
方案 A:同一份固件,靠"进入条件"切换
void app_main(void)
{
/* 上电时检测某个 GPIO / 按键组合,进入产测模式 */
if (prod_mode_detect()) {
prod_test_main(); /* 产测流程,永不返回 */
}
normal_app_main(); /* 正常业务流程 */
}
优点:不用维护两份固件,OTA 也不会漏;
缺点:产测代码会占 Flash,量产发布时体积偏大。
方案 B:单独的产测固件
优点:正式固件干净、体积小;
缺点:要烧两次固件(产测固件 + 正式固件),产线多一道工序。
我推荐方案 A,因为 Flash 现在通常够用,而且"少一道烧写工序"在产线上价值很大。
产测模式的人机交互
产线工人操作,界面必须极简:
【产测模式】
1. 自检 ……… PASS
2. 通信测试 ….. PASS
3. 内存测试 ….. PASS
4. 按键测试 ….. PASS
———————
结果: PASS (LED 绿灯常亮)
- PASS:绿灯常亮,工人直接流下去;
- FAIL:红灯闪烁 + 蜂鸣器报警,同时打印出失败项,方便维修定位。
void prod_test_main(void)
{
if (selftest_run_all() && prod_comm_test() &&
prod_mem_test() && prod_key_test()) {
led_set(LED_GREEN, ON);
prod_report_all_pass(); /* 上报产测数据(用于追溯) */
} else {
led_blink(LED_RED, 5);
buzzer_alarm();
prod_report_fail_detail(); /* 上报失败项 */
}
for (;;) vTaskDelay(pdMS_TO_TICKS(1000));
}
五、数据追溯:把每台设备"记在账上"
每台设备的产测结果、SN、时间都要上传存档。
typedef struct {
char sn[16]; /* 序列号 */
uint8_t result; /* 0=FAIL 1=PASS */
uint8_t fail_item; /* 失败项编号 */
uint32_t fw_version;
uint16_t err_code; /* 错误码 */
uint32_t timestamp;
int16_t rssi; /* 通信信号强度,反映产线环境 */
} prod_record_t;
追溯的价值:
- 某批次集中失败 → 立刻定位到元件批次 / 焊接工艺问题;
- 某工位失败率高 → 定位到设备或人员操作;
- 售后返修时 → 查到它出厂时的测试数据,判断是"出厂就有问题"还是"用坏的"。
没有追溯数据的产线,出了问题只能整批召回。
六、产测清单(可直接打印贴在产线)
| 1 | 上电自检 | 自动 | 全部 OK |
| 2 | 通信压力 | 200 次收发 | 错误 ≤ 2 |
| 3 | 内存长跑 | 100 圈循环 | 堆减少 ≤ 8 字节 |
| 4 | 上下电 | 20 次快速通断 | 每次正常启动 |
| 5 | 高低温 | 3 个温度点 | 通信正常 |
| 6 | 老化 | 72h 通电 | 零复位 |
| 7 | OTA | 完整升级 + 回滚 | 成功且能回滚 |
| 8 | 接口按键 | 治具自动 | 全部正常 |
七、小结
四句话:
1. 产测和研发测试目标不同:产测要"快、自动、结果明确"。
2. 通信压力测试和内存长跑,是性价比最高的两项——能在几分钟内筛出最贵的故障。
3. 老化测试是筛"早期失效"的唯一手段,必须记录复位次数。
4. 产测数据必须存档追溯,否则出了问题只能整批召回。
下一讲(第 16 讲),是最后一讲。我们不做技术细节,而是回头看一眼:这 16 讲串起来的,到底是一条什么样的能力路径——从"会写驱动"到"能交付产品",中间差的是什么。
网硕互联帮助中心





评论前必须登录!
注册