3. 硬件自检概述
在MCU系统中,硬件自检(Built-In Self-Test, BIST)是指由固件主动发起、通过片上资源或外部辅助电路对关键硬件模块进行检测与判定的过程。它的目标不是替代功能测试,而是在系统启动、运行或维护阶段快速回答三个问题:硬件是否存在、是否可用、是否可信。与依赖外部仪器的产线测试不同,硬件自检强调“自包含”和“可重复”,通常由MCU自身执行,必要时配合少量外部激励。
核心定义:硬件自检是MCU固件在受控条件下,对CPU、RAM、Flash、时钟、电源、通信外设、ADC、GPIO等硬件资源执行检测,并输出通过/失败/降级结论的机制。它既是一种测试技术,也是一种系统安全策略。
一、自检的分类维度
硬件自检可以从多个维度分类。按执行时机可分为启动自检(Power-On Self-Test, POST)和运行时自检(Runtime Self-Test, RST);按覆盖对象可分为CPU自检、存储器自检、时钟自检、电源自检、外设自检和IO自检;按检测方式可分为逻辑内建自检(LBIST)、存储器内建自检(MBIST)、软件自检(SBST)和签名/校验自检。不同分类并非互斥,一个完整的自检策略往往是多类组合。
| 分类维度 | 典型类型 | 检测对象 | 常用方法 |
|---|---|---|---|
| 执行时机 | 启动自检 | CPU、RAM、Flash、时钟 | 上电复位后全量扫描 |
| 执行时机 | 运行时自检 | RAM、Flash、外设、电源 | 周期抽检、后台校验 |
| 检测方式 | LBIST | CPU内核、总线逻辑 | 伪随机序列+签名压缩 |
| 检测方式 | MBIST | SRAM、Flash阵列 | March算法、棋盘格 |
| 检测方式 | SBST | 寄存器、指令集、外设 | 软件激励+结果比对 |
| 覆盖对象 | 电源/时钟自检 | LDO、BOR、PLL、晶振 | 阈值比较、频率计数 |
二、启动自检与运行时自检
启动自检发生在复位释放后、应用程序正式运行前。它的特点是全量、阻塞、可预期:CPU先执行ROM中的自检代码,依次检查时钟是否稳定、RAM是否可读写、Flash校验是否正确、关键外设是否响应。若自检失败,系统可进入安全状态、报警或禁止启动。启动自检的代价是启动时间增加,因此需要权衡检测深度与启动时限。
运行时自检发生在应用运行过程中,通常由定时器或任务调度触发。它的特点是抽检、非阻塞、可恢复:例如每隔100ms对RAM的某个区块做March测试,或利用Flash ECC错误计数判断存储单元健康度。运行时自检不能长时间占用CPU,也不能破坏正在使用的数据,因此常采用后台DMA、双区切换或空闲窗口执行。
三、自检覆盖率与失效模式
自检覆盖率(Test Coverage)是衡量自检有效性的核心指标,通常定义为“被自检能够检测到的故障类型数 / 该模块全部可能故障类型数”。覆盖率越高,系统对潜在故障的暴露能力越强,但检测时间和资源开销也越大。工程上需要根据安全等级(如IEC 61508 SIL、ISO 26262 ASIL)确定目标覆盖率,而不是盲目追求100%。
失效模式(Failure Mode)是自检设计的输入。常见的MCU硬件失效模式包括:存储单元固定故障(stuck-at)、相邻单元耦合故障、地址译码故障、时钟频率偏移、电源电压跌落、复位电路失效、外设寄存器位翻转、总线开路或短路等。自检算法必须针对这些失效模式设计激励和观测点,否则覆盖率只是纸面数字。
工程提示:自检覆盖率不是越高越好。对于非安全关键模块,过高的覆盖率会挤占启动时间和CPU带宽。建议按“安全相关模块优先、故障影响大优先、检测成本低优先”的原则分配自检资源。
四、案例:电机控制器的启动与运行时自检
某工业电机控制器采用Cortex-M7 MCU,安全目标为SIL 2。其自检策略如下:启动阶段执行时钟检测、RAM March C-全量测试、Flash CRC32校验和电源BOR检查,总耗时约85ms;运行阶段每50ms对RAM做分块抽检,每500ms对Flash做后台CRC巡检,每10ms读取一次ADC参考电压和内部温度传感器。若运行时自检发现RAM错误,系统记录故障码并切换到安全转矩关断状态;若Flash CRC错误,则禁止执行该区块代码并触发报警。
/* 启动自检伪代码示例 */
void POST_Run(void) {
if (CLOCK_Check() != OK) { Safety_Shutdown(ERR_CLOCK); }
if (RAM_MarchC_Test() != OK) { Safety_Shutdown(ERR_RAM); }
if (Flash_CRC32_Check() != OK) { Safety_Shutdown(ERR_FLASH); }
if (Power_BOR_Check() != OK) { Safety_Shutdown(ERR_POWER); }
POST_Result = POST_PASS;
}
/* 运行时自检伪代码示例 */
void RST_Task_50ms(void) {
uint8_t block = RST_NextBlock();
if (RAM_March_Block(block) != OK) {
Fault_Log(ERR_RAM_RUNTIME, block);
Safety_Degrade();
}
}
五、常见误区与复盘
- 误区一:自检等于功能测试。自检只验证硬件“是否可信”,不验证应用逻辑是否正确。两者目标不同,不能互相替代。
- 误区二:启动自检越全越好。启动时间受限于系统上电时序和看门狗超时,过度自检会导致启动失败或用户体验下降。
- 误区三:运行时自检可以随意打断业务。运行时自检必须考虑数据一致性和实时性,避免在DMA传输或中断关键区执行破坏性测试。
- 误区四:覆盖率报告等于实际防护能力。覆盖率需要结合失效模式分析(FMEA)和故障注入测试验证,否则只是理论值。
复盘结论:硬件自检的设计应围绕“失效模式—检测方法—覆盖率—响应策略”闭环展开。启动自检解决“上电是否可信”,运行时自检解决“运行中是否退化”,两者配合才能在MCU全生命周期内提供可量化的硬件健康保障。