一、低功耗调试概述
1.1 为什么要做低功耗调试?
说实话,我刚入行那会儿,对低功耗这事也不太在意。
觉得功能跑通了就行,功耗嘛,大不了多充几次电。
直到有一次,我负责的一个项目,整机待机电流超标了 3 倍。
客户反馈说手机放一晚上,早上起来掉了 20% 的电。
嗯,那场面,至今难忘。
低功耗调试,说白了就是跟「漏电」和「不该干活却在干活」的模块作斗争。
你想想看,一个 SoC 里几十个电源域,上百个时钟,几千个外设。
任何一个地方没关干净,电流就上去了。
为什么要做低功耗调试?我总结了三个核心原因:
- 续航是用户体验的底线——功能再强,半天就没电,用户直接骂娘。
- 发热会触发温控降频——功耗高了,温度上来,性能反而下降,得不偿失。
- 过温可能损坏硬件——我在项目中见过 PMIC 因为持续过流烧掉的案例,板子直接冒烟。
核心观点:低功耗调试不是「锦上添花」,而是「生死存亡」。一个产品如果功耗不过关,连上市的机会都没有。
1.2 PMU 在 Android 系统中的角色
PMU,全称 Power Management Unit,电源管理单元。
很多人把它跟 PMIC(电源管理芯片)搞混,其实不一样。
PMIC 是硬件芯片,负责输出各路电压。
PMU 是 SoC 内部的一个逻辑模块,负责「管」这些电压和时钟。
PMU 在 Android 系统里到底扮演什么角色?我习惯用三个词概括:
- 调度员——谁该供电,谁该断电,PMU 说了算。
- 守门员——系统要进休眠,PMU 检查所有外设是否就绪。
- 记录员——谁在耗电,耗了多少,PMU 都有寄存器记录。
举个例子,Android 的 suspend-to-RAM 流程:
系统要休眠,内核会通知 PMU 准备断电。
PMU 先检查各个外设的「休眠许可」——比如 Wi-Fi 是不是还在传数据?
如果都 OK,PMU 就切断大部分电源域,只保留唤醒逻辑。
这时候,整机电流应该降到 mA 级别。
我在项目中遇到过一个问题:手机休眠后电流死活降不下来。
查了两天,最后发现是某个 I2C 设备没注册休眠回调。
PMU 等它响应,它一直不吭声,系统就卡在休眠入口。
嗯,这种坑,你光看代码是看不出来的,得上工具抓。
个人经验:PMU 的寄存器 dump 是调试利器。我每次遇到功耗异常,第一件事就是拉 PMU 的寄存器快照,看哪个电源域还开着。
1.3 调试工具链概览
低功耗调试,光靠眼睛看代码是不够的。
你得有一套趁手的工具。我这些年攒下来的工具链,大概分三层:
| 层级 | 工具 | 用途 |
|---|---|---|
| 软件层 | dumpsys batterystats |
查看应用级耗电统计 |
| 内核层 | trace-cmd / ftrace |
跟踪内核电源管理事件 |
| 硬件层 | 万用表 / 示波器 / 电流探头 | 测量实际电流波形 |
先说软件层。dumpsys batterystats 是 Android 自带的工具。
你跑一下 adb shell dumpsys batterystats --reset,然后正常使用手机。
过一段时间再跑 adb shell dumpsys batterystats,就能看到每个 App 的耗电排行。
这个工具适合做「粗筛」——先找出嫌疑对象,再深入分析。
内核层,我推荐 ftrace。它轻量、无侵入,适合在生产环境用。
比如你想看系统为什么没进深度休眠,可以这样:
# 开启电源管理相关 trace
echo 1 > /sys/kernel/debug/tracing/events/power/enable
# 抓取 10 秒
cat /sys/kernel/debug/tracing/trace_pipe > /data/trace.log
# 分析
grep "suspend" /data/trace.log
硬件层,说实话,这是最准的。
软件统计再精确,也不如直接拿电流探头怼上去看。
我习惯用示波器抓休眠唤醒的电流波形——
波形里能清楚看到:系统什么时候进休眠,什么时候被唤醒,唤醒源是谁。
注意:硬件测量时,一定要确保探头的地线夹得足够短。地线太长会引入噪声,测出来的波形全是毛刺,根本没法看。我曾经因为这个浪费了整整一个下午。
最后,我想说一句:工具是死的,思路是活的。
低功耗调试,核心就三件事:
- 找到谁在耗电
- 找到它为什么耗电
- 找到怎么让它不耗电
后面的章节,我会带着大家一步步走完这个过程。
嗯,准备好了吗?