Android 功耗分析(底层篇)
最近在网上发现关于功耗分析系列的文章很少,介绍详细的更少,于是便想记录总结一下功耗分析的相关知识,有不对的地方希望大家多指出,互相学习。本系列分为底层篇和上层篇。
大概从基础知识,测试手法,以及案例分析三个方面着手。
一、基础知识
底层篇主要介绍底电流的调试与分析。首先我们要明确什么是底电流,什么是待机电流。
1.1、概念
底电流:指机器完全睡眠时的最低电流。
待机电流:是指机器在待机一段时间内的平均电流,通常需要插卡进行测试。
1.2、为什么要测试底电流
主要目的是评估设备在最低功耗状态下的能耗表现,对于电池供电的设备(如手机、可穿戴设备、IoT 设备),底电流直接影响设备在长时间非使用场景下的待机时长。
- 测量底电流是评估产品功耗指标是否符合设计要求的关键步骤。
- 通过实际测量与设计目标对比,发现并解决功耗异常问题
- 底电流测试可以帮助开发者发现硬件设计中的电流泄漏问题,例如:
- 元器件未完全关闭。
- 电路设计不合理导致的静态电流消耗。
- 通过逐步排查电路中的模块,找到并优化功耗“热点。
测量底电流的最终目的是确保设备在低功耗状态下的能耗最小化。它不仅有助于排查和优化硬件设计,还能验证系统功耗策略的有效性,并最终延长设备的续航时间。对于任何需要长待机时间的电池驱动设备,底电流测试是不可或缺的一步。
二、底电流调试方法
这里主要介绍高通平台的调试方法。
2.1、首先要进行RF校准
射频QCN文件下载并进行射频校准。高通有专门的工具刷入机器里,因为QCN文件不下载射频不能正常工作,会引起漏电,继而引起底电流偏大。
2.2、排除其他因素
打开飞行模式,避免蓝牙、wifi、NFC、网络、FM等的一般影响。
关闭GPS,避免GPS对底电流的影响。
关闭自动旋转屏幕,排除sensor的影响。
关闭自动亮度,以及其他特效设置。
手动移除可以移除的所有外设以及驱动模块,例如:
lsmod
rmmod WLAN
2.3、进行待机测试
灭屏待机,连接power monitor 查看实时电流,分析机器是否进入睡眠状态,可以通过串口查看kernel日志,搜索关键字suspend entry查看是否进入睡眠。
2.4、分析kernel日志
kernel没有进入睡眠则查看是哪个模块引起的并有针对性分析相应模块。如果进入休眠电流还大,需要分析各个模块的clock有没有关闭。
2.5、抓取rpm dump日志进行分析
方法如下:
(1)ps_hold接地
在休眠状态下,接ps_hold到地少于200mS,机器会进入紧急下载状态,插入USB,QPST会自动得到memory dump,然后上传以下几个文件:
CODERAM.bin
MSGRAM.bin
DATARAM.bin
以及RPM_AAAAANAZR.elf(必须与机器的编译时间一致匹配的elf)
(2)改reset为download key
发这些命令改reset为download key:
cd /sys/kernel/debug/spmi/spmi-0
echo 0x844 > address
echo 4 > count # cat data 00840 -- -- -- -- 0F 07 04 00
echo 0x00 0x00 0x01 0x00 > data
cat data 00840 -- -- -- -- 00 00 01 00
echo 0x00 0x00 0x01 0x80 > data
cat data 00840 -- -- -- -- 00 00 01 80
然后长按下键,会进入download。之后抓取log方法同上
如果进不了download,需要确认
CONFIG_MSM_DLOAD_MODE=y
2.6、查看rmp_stats的状态
检查rpm_stats是否进入vdd min或者xo/no shutdown。使用下面的命令检查rpm lower power mode count:
adb shell mount -t debugfs none /sys/kernel/debug
adb cat /sys/kernel/debug/rpm_stats
如果vmin的count是0,则表明设备从来没有进入vdd min;non-zero则说明设备进入过vdd_min。
示例:
RPM Mode: xosd
count:0
time in last mode(msec):0
time since last mode(sec):794
actual last sleep(msec):0
RPM Mode:vmin
count:11
time in last mode(msec):0
time since last mode(sec):359
actual last sleep(msec):110000
可以dump出来完整详细的gpio/clk/pmic信息,排除休眠时候的状态异常。
2.7、查看modem是否休眠
可以通过检测TCXO引脚的状态来确定modem端是否休眠,在modem端tlmm_bsp.c文件下比对各个GPIO有无设置错误继而引起漏电。另外,sleep_target.c文件也值得分析。
三、待机电流优化
3.1、adb命令抓取日志
在优化前,我们需要通过日志来确定导致功耗偏高的原因。可以通过一些adb命令进行排查。
adb logcat -v time > YearMounthDayHourMinute_logcat.txt //main log
adb logcat -v time -b events > YearMounthDayHourMinute_logcat_event.txt //event log
adb logcat -v time -b radio > YearMounthDayHourMinute_logcat_radio.txt //radio log
adb shell dmesg > YearMounthDayHourMinute_dmesg.txt //kernel log
抓取对应的日志
adb shell mount -t debugfs none /sys/kernel/debug
用于将 debugfs
文件系统挂载到 Android 设备的 /sys/kernel/debug
目录,允许开发者访问内核的调试信息、性能数据和其他调试工具
adb shell "echo 8 > /proc/sys/kernel/printk"
将内核的日志级别设置为 8
,使得内核输出最详细的调试信息
除了上述的方法,我们也可以使用如下命令来打开指定文件的kernel log(以qpnp-adc-tm.c和qpnp-adc-common.c为例):
adb shell "echo 'file qpnp-adc-tm.c +p' > /sys/kernel/debug/dynamic_debug/control"
adb shell "echo 'file qpnp-adc-common.c +p' > /sys/kernel/debug/dynamic_debug/control"
我们也可以为指定的函数开启log
以qpnpint_handle_irq为例:
adb shell "echo 'func qpnpint_handle_irq +p' > /sys/kernel/debug/dynamic_debug/control"