一、低功耗调试概述

1.1 为什么要做低功耗调试?

说实话,我刚入行那会儿,对低功耗这事也不太在意。

觉得功能跑通了就行,功耗嘛,大不了多充几次电。

直到有一次,我负责的一个项目,整机待机电流超标了 3 倍。

客户反馈说手机放一晚上,早上起来掉了 20% 的电。

嗯,那场面,至今难忘。

低功耗调试,说白了就是跟「漏电」和「不该干活却在干活」的模块作斗争。

你想想看,一个 SoC 里几十个电源域,上百个时钟,几千个外设。

任何一个地方没关干净,电流就上去了。

为什么要做低功耗调试?我总结了三个核心原因:

  • 续航是用户体验的底线——功能再强,半天就没电,用户直接骂娘。
  • 发热会触发温控降频——功耗高了,温度上来,性能反而下降,得不偿失。
  • 过温可能损坏硬件——我在项目中见过 PMIC 因为持续过流烧掉的案例,板子直接冒烟。

核心观点:低功耗调试不是「锦上添花」,而是「生死存亡」。一个产品如果功耗不过关,连上市的机会都没有。

1.2 PMU 在 Android 系统中的角色

PMU,全称 Power Management Unit,电源管理单元。

很多人把它跟 PMIC(电源管理芯片)搞混,其实不一样。

PMIC 是硬件芯片,负责输出各路电压。

PMU 是 SoC 内部的一个逻辑模块,负责「管」这些电压和时钟。

PMU 在 Android 系统里到底扮演什么角色?我习惯用三个词概括:

  1. 调度员——谁该供电,谁该断电,PMU 说了算。
  2. 守门员——系统要进休眠,PMU 检查所有外设是否就绪。
  3. 记录员——谁在耗电,耗了多少,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

硬件层,说实话,这是最准的。

软件统计再精确,也不如直接拿电流探头怼上去看。

我习惯用示波器抓休眠唤醒的电流波形——

波形里能清楚看到:系统什么时候进休眠,什么时候被唤醒,唤醒源是谁。

注意:硬件测量时,一定要确保探头的地线夹得足够短。地线太长会引入噪声,测出来的波形全是毛刺,根本没法看。我曾经因为这个浪费了整整一个下午。

最后,我想说一句:工具是死的,思路是活的。

低功耗调试,核心就三件事:

  • 找到谁在耗电
  • 找到它为什么耗电
  • 找到怎么让它不耗电

后面的章节,我会带着大家一步步走完这个过程。

嗯,准备好了吗?