SMPL 模块分析
一、模块概述
1.1 功能定位
SMPL (Sudden Momentary Power Loss,瞬时掉电) 是华为 MATE X5 电源管理系统中的瞬时掉电异常监控模块,专门用于检测和记录设备因瞬时电压跌落导致的意外重启事件,通过分析重启原因并上报 DMD(Device Monitor Diagnosis)告警,帮助定位电源系统故障。
1.2 核心功能
重启原因识别:通过 Kernel Cmdline 参数识别 SMPL 重启事件
多模式检测:支持 4 种不同的 SMPL 标识字符串
自动 DMD 上报:检测到 SMPL 后自动上报告警信息
电池状态采集:记录重启时的电池品牌、温度、电压、电量等关键信息
延迟检测:系统启动 10 秒后执行检测,确保电池信息可用
1.3 设计背景
SMPL 是一种常见的电源系统故障现象,表现为系统运行中突然断电重启。常见原因包括:
通过监控 SMPL 事件并记录关键信息,可以帮助:
分析电源系统故障模式
识别批次性硬件问题
指导售后维修策略
优化电源系统设计
二、系统架构
2.1 模块组成
smpl 模块
├── smpl.c # 主逻辑(重启原因检测、DMD 上报)
├── smpl.h # 数据结构定义
├── Kconfig # 内核配置
└── Makefile # 编译配置
2.2 架构分层
+---------------------------------------------------------------+
| Bootloader (U-Boot/ABL) |
| 检测重启原因 → 设置 Kernel Cmdline 参数 |
| - normal_reset_type=SMPL |
| - reboot_reason=power_loss |
| - reboot_reason=2sec_reboot |
| - normal_reset_type=BR_POWERON_BY_SMPL |
+---------------------------------------------------------------+
↓
+---------------------------------------------------------------+
| Kernel (smpl.c) |
| 1. 启动 10 秒后执行检测 |
| 2. 解析 Cmdline 参数识别 SMPL |
| 3. 采集电池状态信息 |
| 4. 上报 DMD 告警 |
+---------------------------------------------------------------+
↓
+---------------------------------------------------------------+
| DMD System (Device Monitor) |
| - 错误码: POWER_DSM_ERROR_NO_SMPL |
| - 错误类型: POWER_DSM_SMPL |
| - 告警内容: 电池品牌、温度、电压、电量 |
+---------------------------------------------------------------+
↓
+---------------------------------------------------------------+
| Cloud Analysis Platform |
| - 统计 SMPL 发生频率 |
| - 分析故障模式 |
| - 生成维修建议 |
+---------------------------------------------------------------+
2.3 工作流程
设备启动
↓
Kernel 初始化
↓
smpl_init() 执行
↓
创建延迟工作队列(10 秒)
↓
等待 10 秒(确保电池驱动就绪)
↓
smpl_error_monitor_work() 执行
↓
┌─────────────────────────────────────────────────┐
│ 检查 Kernel Cmdline 参数 │
│ 1. strstr("normal_reset_type=SMPL") │
│ 2. strstr("reboot_reason=power_loss") │
│ 3. strstr("reboot_reason=2sec_reboot") │
│ 4. strstr("normal_reset_type=BR_POWERON_BY_SMPL") │
└─────────────────────────────────────────────────┘
↓
发现 SMPL 标识?
├─ 否 → 退出(正常启动)
└─ 是 → 继续
↓
采集电池状态信息
├─ 电池品牌: power_supply_app_get_bat_brand()
├─ 电池温度: power_supply_app_get_bat_temp()
├─ 电池电压: power_supply_app_get_bat_voltage_now()
└─ 电池电量: power_supply_app_get_bat_capacity()
↓
构造 DMD 告警字符串
↓
上报 DMD
↓
记录日志
↓
完成
三、核心数据结构
3.1 设备管理结构
struct smpl_dev {
struct device *dev;
struct delayed_work monitor_work;
};
说明:
3.2 常量定义
#define DELAY_TIME_FOR_MONITOR_WORK 10000
设计意图:
四、核心算法与工作流程
4.1 重启原因检测算法(smpl_check_reboot_reason)
static bool smpl_check_reboot_reason(void)
{
if (strstr(saved_command_line, "normal_reset_type=SMPL")) {
hwlog_info("smpl happened: normal_reset_type=smpl\n");
return true;
}
if (strstr(saved_command_line, "reboot_reason=power_loss")) {
hwlog_info("smpl happened: reboot_reason=power_loss\n");
return true;
}
if (strstr(saved_command_line, "reboot_reason=2sec_reboot")) {
hwlog_info("smpl happened: reboot_reason=2sec_reboot\n");
return true;
}
if (strstr(saved_command_line, "normal_reset_type=BR_POWERON_BY_SMPL")) {
hwlog_info("smpl happened: normal_reset_type=BR_POWERON_BY_SMPL\n");
return true;
}
return false;
}
Cmdline 参数来源:
Bootloader(U-Boot/ABL)在启动时检测 PMIC 寄存器
PMIC 记录上次关机/重启原因(PONSTS/PON_REASON 寄存器)
Bootloader 将原因编码为 Cmdline 参数传递给 Kernel
四种检测模式对应平台:
normal_reset_type=SMPL:高通平台(Qualcomm)
reboot_reason=power_loss:MTK 平台(MediaTek)
reboot_reason=2sec_reboot:特殊场景(连续快速重启)
normal_reset_type=BR_POWERON_BY_SMPL:华为自研平台(Kirin/HiSilicon)
4.2 SMPL 监控工作流程(smpl_error_monitor_work)
static void smpl_error_monitor_work(struct work_struct *work)
{
char buf[POWER_DSM_BUF_SIZE_0128] = { 0 };
hwlog_info("monitor_work begin\n");
if (!smpl_check_reboot_reason())
return;
snprintf(buf, POWER_DSM_BUF_SIZE_0128 - 1,
"smpl happened : brand=%s t_bat=%d, volt=%d, soc=%d\n",
power_supply_app_get_bat_brand(),
power_supply_app_get_bat_temp(),
power_supply_app_get_bat_voltage_now(),
power_supply_app_get_bat_capacity());
power_dsm_report_dmd(POWER_DSM_SMPL,
POWER_DSM_ERROR_NO_SMPL, buf);
hwlog_info("smpl happened: %s\n", buf);
}
DMD 告警格式示例:
smpl happened : brand=ATL t_bat=250, volt=3850, soc=65
信息解读:
4.3 模块初始化流程(smpl_init)
static int __init smpl_init(void)
{
struct smpl_dev *l_dev = NULL;
l_dev = kzalloc(sizeof(*l_dev), GFP_KERNEL);
if (!l_dev)
return -ENOMEM;
g_smpl_dev = l_dev;
INIT_DELAYED_WORK(&l_dev->monitor_work, smpl_error_monitor_work);
schedule_delayed_work(&l_dev->monitor_work,
msecs_to_jiffies(DELAY_TIME_FOR_MONITOR_WORK));
return 0;
}
初始化时机:module_init()
4.4 模块退出流程(smpl_exit)
static void __exit smpl_exit(void)
{
if (!g_smpl_dev)
return;
cancel_delayed_work(&g_smpl_dev->monitor_work);
kfree(g_smpl_dev);
g_smpl_dev = NULL;
}
五、典型应用场景
5.1 场景1:电池老化导致的 SMPL
用户场景:
设备使用 2 年,电池老化,内阻升高
触发过程:
1. 用户运行大型游戏(高功耗负载)
↓
2. CPU/GPU 突发功耗峰值 6W
↓
3. 电池瞬时放电电流 2A
↓
4. 电池内阻 300mΩ(新电池约 100mΩ)
↓
5. 压降 = 2A × 0.3Ω = 0.6V
↓
6. VBAT 从 3.8V 跌落至 3.2V
↓
7. PMIC 欠压保护触发(阈值 3.3V)
↓
8. 系统复位重启(SMPL 事件)
↓
9. Bootloader 检测到 PMIC PONSTS 寄存器 = SMPL
↓
10. 设置 Cmdline: normal_reset_type=SMPL
↓
11. Kernel 启动,smpl 模块检测到 SMPL
↓
12. 上报 DMD:
brand=ATL t_bat=350 volt=3200 soc=45
↓
13. 分析结论:
- 电压 3200mV 过低
- 电量 45% 不应该出现 SMPL
- 怀疑电池老化
5.2 场景2:BTB 接触不良导致的 SMPL
用户场景:
设备跌落后,电池连接器松动
触发过程:
1. 用户手机意外跌落
↓
2. BTB 连接器受冲击松动
↓
3. 接触电阻从 5mΩ 升至 100mΩ
↓
4. 正常使用中,瞬间断开 → 重新接触
↓
5. 电池断开瞬间 → VBAT = 0V
↓
6. PMIC 检测到掉电 → 系统复位
↓
7. BTB 重新接触 → 电池恢复供电
↓
8. 设备自动重启(SMPL 事件)
↓
9. Bootloader 设置 Cmdline: reboot_reason=power_loss
↓
10. smpl 模块检测并上报:
brand=SUNWODA t_bat=280 volt=3900 soc=78
↓
11. 分析结论:
- 电压 3900mV 正常
- 电量 78% 充足
- 温度 28°C 正常
- 怀疑机械故障(BTB/电池接触不良)
5.3 场景3:充电 IC 故障导致的 SMPL
用户场景:
充电过程中系统突然重启
触发过程:
1. 用户边充电边玩游戏
↓
2. 充电 IC 输出电流 = 充电电流 + 系统负载
↓
3. 充电 IC 内部 MOSFET 异常(批次缺陷)
↓
4. 输出电流能力下降至 1A(正常应 3A)
↓
5. 系统负载突增至 2A
↓
6. 充电 IC 过流保护触发 → 输出关断
↓
7. VSYS 跌落 → 系统掉电
↓
8. SMPL 重启
↓
9. Bootloader 设置 Cmdline: normal_reset_type=BR_POWERON_BY_SMPL
↓
10. smpl 模块上报:
brand=ATL t_bat=420 volt=4100 soc=85
↓
11. 分析结论:
- 电池状态良好
- 充电中发生(电压 4.1V 为充电电压)
- 温度 42°C 偏高(充电 + 游戏发热)
- 怀疑充电 IC 或电源路径故障
5.4 场景4:连续快速 SMPL(2sec_reboot)
用户场景:
设备启动过程中反复重启
触发过程:
1. 设备首次 SMPL 重启
↓
2. Bootloader 启动 → Kernel 加载
↓
3. 系统初始化过程中再次触发 SMPL
↓
4. 连续重启时间 < 2 秒
↓
5. Bootloader 检测到连续重启
↓
6. 设置 Cmdline: reboot_reason=2sec_reboot
↓
7. smpl 模块检测到异常重启模式
↓
8. 上报 DMD:
brand=ATL t_bat=150 volt=3100 soc=2
↓
9. 分析结论:
- 电量仅 2%(临界低电量)
- 电压 3100mV(关机阈值附近)
- 温度 15°C(低温环境)
- 启动电流峰值导致电压跌落
- 建议进入低电量保护模式
六、调试方法
6.1 日志关键点
[smpl] monitor_work begin
[smpl] smpl happened: normal_reset_type=smpl
[smpl] smpl happened: reboot_reason=power_loss
[smpl] smpl happened: reboot_reason=2sec_reboot
[smpl] smpl happened: normal_reset_type=BR_POWERON_BY_SMPL
[smpl] smpl happened: brand=ATL t_bat=250, volt=3850, soc=65
6.2 Cmdline 参数查看
cat /proc/cmdline
cat /proc/cmdline | grep -E "SMPL|power_loss|2sec_reboot"
6.3 PMIC 寄存器查看
cat /sys/kernel/debug/pmic-debug/pon_reason
cat /sys/kernel/debug/mtk-pmic/pon_reason
cat /sys/kernel/debug/hi6xxx-pmic/pon_reason
6.4 DMD 查询
cat /sys/kernel/debug/power_dsm/power_dsm_dump | grep SMPL
logcat -b events | grep SMPL
6.5 手动触发测试
setenv bootargs "${bootargs} normal_reset_type=SMPL"
boot
chosen {
bootargs = "... normal_reset_type=SMPL";
};
6.6 常见问题排查
问题1:SMPL 未检测到
现象:设备明显重启但无 SMPL 日志
排查步骤:
检查 Cmdline 参数:
检查 PMIC 驱动是否正确设置参数
检查 smpl 模块是否加载:
lsmod | grep smpl
dmesg | grep smpl
问题2:电池信息为空
现象:DMD 上报中电池信息为 0 或空
排查步骤:
检查延迟时间是否足够:
#define DELAY_TIME_FOR_MONITOR_WORK 20000
检查电池驱动是否已初始化:
cat /sys/class/power_supply/battery/voltage_now
cat /sys/class/power_supply/battery/capacity
问题3:频繁 SMPL 告警
现象:DMD 系统频繁收到 SMPL 告警
排查步骤:
分析 DMD 数据趋势:
电压分布(是否集中在低电压区)
电量分布(是否集中在低电量区)
温度分布(是否在极端温度)
电池品牌分布(是否特定批次)
硬件排查:
cat /sys/class/power_supply/battery/health
cat /sys/class/power_supply/battery/cycle_count
cat /sys/class/power_supply/battery/resistance
软件优化:
优化功耗峰值控制
调整 PMIC 欠压保护阈值
改善电源管理策略
七、SMPL 故障分析方法
7.1 数据分析维度
电压维度
| VBAT 范围 | 可能原因 | 处理建议 |
|---|
| < 3000mV | 极低电量,电池耗尽 | 低电量保护优化 |
| 3000-3200mV | 电池老化,内阻高 | 更换电池 |
| 3200-3500mV | 负载过大,电压跌落 | 功耗优化 |
| 3500-3800mV | BTB 接触不良 | 硬件检修 |
| > 3800mV | 充电中 SMPL | 充电 IC 故障 |
电量维度
| SOC 范围 | 可能原因 | 处理建议 |
|---|
| 0-5% | 正常低电量关机 | 提前低电量保护 |
| 5-15% | 电池老化严重 | 电池健康度检测 |
| 15-50% | 电池或硬件故障 | 硬件检修 |
| > 50% | 充电 IC/BTB 故障 | 硬件更换 |
温度维度
| 温度范围 | 可能原因 | 处理建议 |
|---|
| < 0°C | 低温电池性能下降 | 低温保护优化 |
| 0-15°C | 温和环境,其他故障 | 硬件检查 |
| 15-40°C | 正常温度范围 | 其他原因分析 |
| > 40°C | 高负载发热 | 温控优化 |
7.2 故障模式分类
模式1:电池老化型
特征:
电压 3000-3300mV
电量 30-60%
温度正常
频繁发生
处理:建议用户更换电池
模式2:接触不良型
特征:
电压正常(3500-4000mV)
电量充足(> 50%)
随机发生
可能伴随跌落
处理:检查 BTB 连接器
模式3:低温型
特征:
温度 < 5°C
电量中等(20-50%)
电压偏低(3200-3500mV)
处理:优化低温保护策略
模式4:充电故障型
特征:
电压 > 3900mV(充电电压)
电量递增趋势
充电中发生
处理:检查充电 IC 和电源路径
八、总结
8.1 技术特点
轻量级设计:模块极简,无复杂依赖
延迟检测:10 秒延迟确保依赖服务就绪
多平台兼容:支持高通、MTK、华为等平台
信息丰富:记录电池关键状态便于分析
8.2 设计亮点
8.3 应用价值
故障定位:快速识别电源系统问题根因
质量改进:通过大数据分析发现批次缺陷
售后支持:为用户维修提供诊断依据
产品优化:指导下一代产品的电源设计
8.4 局限性
信息有限:仅记录静态信息,无法获取 SMPL 瞬间的动态数据
无实时监控:仅启动时检测,无法监控运行时状态
依赖 Bootloader:必须依赖 Bootloader 正确设置 Cmdline
无主动防护:仅监控上报,不具备 SMPL 预防能力
8.5 改进方向
增强信息采集:
记录 PMIC 寄存器快照
采集 SMPL 前的系统负载信息
记录充电状态和电流
实时监控:
监控电池电压/电流波动
检测电压跌落趋势
预警潜在 SMPL 风险
主动防护:
低电量时限制功耗峰值
低温时降低性能避免电压跌落
老化电池检测并告警