第三章 TC3xx 硬件安全机制(二):SMU(安全管理单元)详解、故障反应与恢复策略
好,咱们接着聊。上一章我们讲了时钟、电源、看门狗这些基础安全机制。这一章,我要重点聊聊 SMU——安全管理单元。说实话,这是 TC3xx 安全架构里最核心的模块之一。我个人觉得,不理解 SMU,就等于没理解 TC3xx 的安全设计。
3.1 SMU 是什么?为什么需要它?
你想想看,一个芯片里可能有几十个安全监控点:时钟故障、电压跌落、内存 ECC 错误、看门狗超时……每个监控点检测到故障后,该怎么处理?是直接复位?还是触发中断?还是什么都不做只记录一下?
SMU 就是干这个的。它像一个「安全总指挥」,统一收集所有故障信号,然后根据你配置的规则,决定下一步动作。
核心思想: SMU 把故障检测和故障响应解耦了。检测由各个模块自己负责,响应由 SMU 统一管理。这样设计更灵活,也更容易满足功能安全的要求。
我在一个项目中遇到过这样的情况:客户要求某个 ECC 错误不能直接复位,而是要记录日志后再软复位。如果没有 SMU,你得改一堆模块的逻辑。有了 SMU,改几行配置就行。嗯,这就是它的价值。
3.2 SMU 的架构与关键寄存器
SMU 内部结构不算复杂,但有几个关键点你必须掌握。
3.2.1 故障输入(Alarm Inputs)
SMU 有最多 256 个故障输入通道。每个通道对应一个特定的故障源。比如:
- Alarm[0]:CPU 锁步比较错误
- Alarm[1]:SRAM ECC 不可纠正错误
- Alarm[2]:时钟 PLL 失锁
- ……
每个通道可以独立配置。你可以决定这个故障是「致命」的还是「可恢复」的。
3.2.2 故障响应配置(SMU_AGiCFn 寄存器)
这是 SMU 的核心寄存器组。每个故障通道对应一个 AGiCF(Alarm Group Configuration)寄存器。你可以在里面配置:
- 响应类型(RTS):是触发中断?还是触发复位?还是触发 SMU 的 FSP(故障信号协议)输出?
- 使能控制(EN):这个故障是否被使能。
- 恢复模式(RM):故障清除后,是自动恢复还是手动恢复。
我的习惯: 在项目初期,我会把所有故障通道都配置成「仅记录,不动作」。等系统跑起来后,再逐个使能并验证响应是否正确。这样可以避免误触发导致系统反复复位,调试起来很痛苦。
3.2.3 故障状态寄存器(SMU_AGiSP)
这个寄存器告诉你当前哪些故障处于活跃状态。调试时我经常盯着它看。如果某个故障一直置位,说明问题还没解决,别急着清标志。
3.3 故障反应策略:三种典型模式
根据功能安全等级的不同,故障反应策略可以分为三类。我分别说说。
3.3.1 立即复位(Immediate Reset)
说白了就是「一发现故障,立刻让系统重启」。适用于那些不可恢复的致命故障,比如 CPU 锁步错误、内存双比特错误。
配置示例:
// 假设 Alarm[0] 是 CPU 锁步错误
SMU_AGiCF[0].RTS = 0b10; // 触发系统复位
SMU_AGiCF[0].EN = 1; // 使能该故障
我曾经在一个项目中,因为锁步错误没有配置复位,导致系统在错误状态下继续运行了十几毫秒,最终输出了一组错误数据。嗯,从那以后,我对这类故障一律采用立即复位。
3.3.2 中断通知(Interrupt Notification)
适用于那些「可以容忍短暂延迟」的故障。比如某个温度传感器读数异常,你可以先触发一个中断,让软件决定怎么处理。
配置示例:
// 假设 Alarm[10] 是温度传感器故障
SMU_AGiCF[10].RTS = 0b01; // 触发 SMU 中断
SMU_AGiCF[10].EN = 1; // 使能
在中断服务函数里,你可以读取温度值,判断是否真的超标,再决定是否要降频或者关机。这种策略给了软件更多的处理空间。
3.3.3 故障信号输出(FSP)
FSP 是 SMU 的一个硬件输出引脚。你可以把它接到外部安全控制器(比如另一个 MCU 或 CPLD)。当 SMU 检测到故障时,FSP 引脚会输出一个脉冲或电平变化,通知外部系统。
这种策略常用于 ASIL-D 级别的系统。即使主芯片挂了,外部安全控制器也能接管。
注意: FSP 输出需要配置 SMU_FSP 寄存器,包括脉冲宽度、极性等。我见过有人忘了配置极性,结果故障时输出低电平,外部电路以为是正常状态……调试了两天才发现。
3.4 故障恢复策略:自动恢复 vs 手动恢复
故障恢复,说白了就是「故障消失后,系统怎么回到正常状态」。SMU 支持两种模式。
3.4.1 自动恢复(Auto Recovery)
故障条件消失后,SMU 自动清除故障状态,系统恢复正常。适用于那些瞬态故障,比如电源短暂波动。
优点: 不需要软件干预,响应快。
缺点: 如果故障频繁出现,系统会反复进入恢复-故障-恢复的循环,可能掩盖了根本问题。
3.4.2 手动恢复(Manual Recovery)
故障条件消失后,故障状态仍然保持。需要软件主动写寄存器来清除。
优点: 软件可以记录故障次数、时间戳,做更精细的管理。
缺点: 如果软件没写好,可能永远不清除故障,导致系统一直处于受限状态。
我个人习惯:对于关键故障(比如 ECC 错误),我会用手动恢复。这样我可以记录故障发生时的上下文,方便事后分析。
3.5 实战:SMU 初始化与故障处理流程
下面我给一个简单的初始化代码框架。注意,这只是示意,实际项目中要根据你的安全需求调整。
void SMU_Init(void)
{
// 1. 关闭所有故障,防止初始化过程中误触发
for (int i = 0; i < 256; i++) {
SMU_AGiCF[i].EN = 0;
}
// 2. 配置关键故障
// CPU 锁步错误 -> 立即复位
SMU_AGiCF[0].RTS = 0b10; // 复位
SMU_AGiCF[0].RM = 0; // 自动恢复
SMU_AGiCF[0].EN = 1;
// SRAM ECC 不可纠正错误 -> 中断通知
SMU_AGiCF[1].RTS = 0b01; // 中断
SMU_AGiCF[1].RM = 1; // 手动恢复
SMU_AGiCF[1].EN = 1;
// 3. 配置 FSP 输出(如果需要)
SMU_FSP.POL = 1; // 高电平有效
SMU_FSP.PW = 3; // 脉冲宽度 3 个时钟周期
// 4. 使能 SMU 全局控制
SMU_KEYS.KEY = 0xBC; // 解锁 SMU 配置
SMU_CTRL.EN = 1; // 使能 SMU
}
避坑指南: 我曾经在初始化时忘了解锁 SMU_KEYS 寄存器,结果配置写不进去,所有故障都默认不使能。系统跑起来后,ECC 错误发生了,但 SMU 没有任何反应……嗯,从那以后,我每次初始化都会先检查 KEYS 寄存器是否解锁成功。
3.6 故障处理流程:从检测到恢复
一个完整的故障处理流程,大致是这样的:
- 故障发生:某个模块检测到异常,向 SMU 发送 Alarm 信号。
- SMU 仲裁:SMU 根据 AGiCF 配置,决定响应方式(复位/中断/FSP)。
- 响应执行:如果是中断,CPU 进入中断服务函数;如果是复位,系统重启。
- 故障清除:故障条件消失后,根据恢复模式,自动或手动清除故障状态。
- 系统恢复:系统回到正常状态,继续运行。
这里有个细节要注意:如果配置了手动恢复,但软件忘了清除故障标志,那么 SMU 会认为故障仍然存在,可能会持续触发中断或复位。所以,手动恢复模式下,一定要在合适的时机调用清除函数。
void SMU_ClearAlarm(uint32_t alarmIdx)
{
// 先确认故障是否真的消失了
if (SMU_AGiSP[alarmIdx] == 0) {
// 清除故障标志
SMU_AGiSC[alarmIdx] = 1;
} else {
// 故障仍然存在,不要清除
// 记录日志,等待处理
}
}
3.7 小结
SMU 是 TC3xx 安全架构的「大脑」。它统一管理所有故障的检测、响应和恢复。掌握了 SMU,你就掌握了 TC3xx 功能安全设计的核心。
下一章,我们会聊聊内存保护单元(MPU)和锁步核的配合使用。到时候我会分享一个我在实际项目中遇到的「锁步核误报」的案例,挺有意思的。
好,今天就到这里。有问题欢迎交流。