Android功耗调试汇总

1. 工具准备

1.1 安装QXDM
1.2 安装QPST(确认DCVS 使能时需要查看efs 文件,下载nv 也需要使用QPST)
1.3 电流源(带GPIB 卡接口)/电流测试软件

测试环境相关 :
◆ 电流表或数字电源本身的电流误差是多少,并保证其工作正常,感觉有问题时,可以换表尝试
◆ 要正确设置DRX、MFRM、T3212等参数,可以参考高通文档80-VE263-8
◆ 综测仪分CMU200、Agilent 8960等多个厂家型号,可以判断一下是否综测仪相关
◆ 在屏蔽房内和屏蔽房外分别进行测试,看是否有所区别

高通文档参考:
◆《80-P0955-1SC_功耗调试通用指南》
  很详细的功耗debug 中文手册,里面有各种case debug的步骤,以及如何来抓取各种 log 。功耗优化的必备资料。
◆《80 -P0956 -1》Android功耗概述
◆《80-N6837-1_M_Power_Consumption_Measurement_MSM_Android_MDM_Devices》
◆《80-NL239-48_POWER CONSUMPTION OPTIMIZATION AND DEBUGGING FOR MSM8916 DEVICES》
◆《80-N9858-1_MODEM POWER CONSUMPTION DEBUGGING METHODS》


2. 测试机设置

2.1 NV 项设置
需要修改的NV项设置如下:
在这里插入图片描述
2.2 禁掉netstats 功能
To disable the data monitor “Netstats” for Jelly Bean(JB)/Ice Cream Sanwich(ICS):
◆ 打开ADB shell,输入如下命令:
adb shell ndc bandwidth disable
◆ 检查data monitor是否已经关闭:
adb shell iptables -L
显示如下:
在这里插入图片描述
2.3 编译performance boot 版本
保证禁掉了所有的debug 和logging 功能。在编译release 版本
时内核配置文件应选用“perf_defconfig”替换“defconfig”文件,或者在“defconfig”文件中删
除debug 调试相关的宏定义。
Remove “Debug” features
Double check if “CORESIGHT” config is removed
Double check if “CONFIG_MSM_DEBUG_LAR_UNLOCK” config is removed

2.4 删除不必要的高频率的调试打印日志
设置串口打印等级:
echo 8 > /proc/sys/kernel/printk 并查看是否生效:
cat /proc/sys/kernel/printk
8 6 1 7

2.5 在国内测试电流需要首先排除GMS 的影响
由于国内GMS 连接不上Google 服务,GMS 一直持有wakelock锁不释放,这会导致手机的待机电流偏高。需要在测试前连接专门网络(如CTS/GTS WIFI),同步Google 账号后,查看电流是否降到3mA 左右。VPN 连接成功后,状态栏会显示小锁。

2.6 RBCPR feature
RBCPR feature对功耗非常重要,请确保测试功耗的版本里面没有禁止掉VDD_APC, VDD_CX, VDD_MX, VDD_MODEM CPR feature。具体检查方法请查看《功耗调试通用指南》“ 如何确认CPR 工作状态” 章节。


3. 调试过程

3.1 底电流
3.1.1 影响底电流的原因有如下方面:
在这里插入图片描述
按照上图的分类先定位电流大的原因是软件问题还是硬件导致的,可以先切换到飞行模式,该模式下,射频相关的底层与上层模块均已关闭,没有DRX等操作,所测得的低电流应该很稳定。这样就可以很精确的对手机的低电流相关问题进行分析与调试。可以方便分析AP、modem等子系统是否进入了待机模式来区分大的方向。

3.1.2 测量飞行模式下的各路LDO
参考高通平台提供的飞行模式下的LDO通断以及消耗情况,对比测试自己的样机状况,确认有哪些LDO没有关闭,或者是消耗过大;甚至是外围器件的倒灌消耗。以8953为例,参考如下:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

3.1.3 分析底电流波形
波形分析对功耗调试至关重要,能够提供问题的本质和正确的调试方向的信息。
底电流波形可以分为以下几个部分:
◆ 基底电流
◆ 唤醒,例如电量计唤醒和PMIC看门狗唤醒
下图是捕捉自MSM8994芯片组的底电流用例波形的快照。
在这里插入图片描述
从在被测端上捕捉的底电流波形可以与QTI参考波形相比较,从而确定基底电流是否较高并且/或者是否出现异常唤醒。

3.1.4 验证XO关闭和VDD最小化
XO关闭和VDD最小化计数的adb shell命令
■ 输入以下命令获取RPM数据:
mount -t debugfs none /sys/kernel/debug
cat /sys/kernel/debug/rpm_stats
以下内容是以上命令的输出;计数代表XO关闭和VDD最小化出现的数量。
RPM Mode:xosd
count:0
time in last mode(msec):0
time since last mode(sec):791
actual last sleep(msec):0
client votes: 0x00020001
RPM Mode:Vdd Min
count:28
time in last mode(msec):8000
time since last mode(sec):475
actual last sleep(msec):233000
client votes: 0x00000000
■ 或者检查以下RPM RAM转储的变量,以确定XO关闭和VDD最小化的计数。
– sleep_stats[0] – XO关闭计数(系统进入XO关闭的次数)
– sleep_stats[1] – VDD最小化计数
注意: 若系统进入VDD最小化状态,则只有VDD最小化计数会增加。VDD最小化是最低的功耗状态,包含XO关闭。仅当系统未成功进入VDD最小化而进入了XO关闭时,XO关闭计数才会增加。

3.1.5 确认AP 待机
■ 修改kernel 打印等级,查看串口,可以确认AP 是否待机,参考如下:

[ 1043.284883] PM: Syncing filesystems ... done.
[ 1043.292613] Freezing user space processes ... 
[ 1043.297018] Error: returning -512 value
(elapsed 0.009 seconds) done.
[ 1043.307019] Freezing remaining freezable tasks ... (elapsed 0.004 seconds) done.
[ 1043.317585] Suspending console(s) (use no_console_suspend to debug)

■ 还可以查看wakelock,确认是否持有锁:
Android wakelock 分为两层:linux 层和应用层

a. 查看linux 的waklock
cat /sys/power/wake_lock
PowerManagerService.Display
PowerManagerService.WakeLocks
PowerManagerService.Display这是屏亮状态下PowerManagerService 对linux 层设的wakelock;
PowerManagerService.WakeLocks: 这是应用层设的wakelock, 所有应用程序设的wakelock 在linux 层
表现成这个wakelock。PowerManagerService 会维护所有应用程序的一个wakelock 表,当不为空时,
向linux 层设置PowerManagerService.WakeLocks;为空时取消这个wakelock

b. 查看应用程序 的waklock
确认有PowerManagerService.WakeLocks 后查看应用程序 的waklock:
dumpsys power
Wake Locks: size=1
PARTIAL_WAKE_LOCK ‘import_contacts’ (uid=1000, pid=4784, ws=null)

■ 检查抑制XO关闭和VDD最小化的时钟

3.1.6 确认modem是否待机
可以配置RPM的log查看modem的sleep情况。详细查看《80-nl239-48 power_consumption_optimization_and_debugging_for_msm8916_devices》的2.1.5 Ensuring modem sleep。

3.1.7 检查wcnss是否待机

3.2 待机电流 (待完善)
待机电流由底电流和唤醒电流平均组成。总的平均待机电流主要依赖于平均底电流的电流消耗。若尚未优化底电流,则待机优化的第一步是优化底电流的电流消耗。理论上,手机待机时,电流应该是比较规则的按照DRX周期进行唤醒。电流消耗捕捉工具提供的波形非常有助于分析寻呼唤醒产生的唤醒损失。
下图展示了DRX寻呼周期中所涉及的不同系统模块的活动阶段的寻呼唤醒波形的关联部分。
在这里插入图片描述
对比寻呼唤醒周期的波形以确定唤醒的哪一部分消耗了较多时间或电流。
■ 系统唤醒时间
■ RF唤醒
■ RF/协议处理
■ RF睡眠
■ 系统睡眠

3.3 通话
3.4 数据
3.5 音频
3.6 视频
3.7 游戏
3.8 浏览器
3.9 BT/WIFI
3.10 其他场景


4. 其他电流问题汇总

4.1 某些器件比如天线开关、sensor以及其他第三方元件没有进入低功耗模式
  ★在调试低电流过程中遇到,发现断掉射频SP9T天线开关电源后,手机低电流有明显下降。查看其SPEC,该开关未明确说明有SLEEP模式,也没有提供相应SLEEP模式下的电流,只给出了工作时的电流,大概在0.8mA左右,这与我们将它电源断掉后,手机低电流的下降值基本吻合。可以确认该开关存在一定的待机问题。项目后来改用其他带SLEEP模式的天线开关,问题得到解决 。

4.2 GPIO的上下拉配置
  ★GPIO的使用与配置是我们进行待机调试时的重要方面一定要逐个引脚进行确认,不要形成漏电回路。并注意,不要使引脚处于无上下拉的输入状态。

4.3 qxdm打开导致电流大
  ★现象:连接手机到PC,通过QXDM抓取log信息,之后拔掉数据线,手机不能待机。通过调试,发现此时diag任务阻止了手机的正常休眠。修改,将SLEEP_DIAG_OKTS_SIG从SLEEP_OK_MASK中去掉,该问题解决。
4.4 gsm联通某些小区比移动电流大
4.5 开机后需要较长时间才进入待机
4.6 热插拔SIM卡不待机
4.7 某些应用导致的待机电流大
4.8 滑屏电流大
4.9 并发场景(游戏+音乐)如:捕鱼达人/天天酷跑电流大
4.10 录音界面亮屏电流大
4.11 上网电流大
4.12 关于对齐唤醒
在这里插入图片描述
4.13 sensor供电和i2c上拉电源不一致导致的电流问题
4.14 usb otg 控制器没有关闭导致的电流问题
4.15 modem没有正常起来以及模式不对造成的电流异常
4.16 otg的休眠


5. 补充要点

5.1 runtime PM机制参考
系统在非睡眠状态时,设备在空闲时可以进入runtime suspend状态同时不依赖系统wake_lock机制;非空闲时执行runtime resume使得设备进入正常工作状态。

主要代码放在Runtime.c (drivers\base\power)中,同时附带的Runtime_pm.txt (documentation\power)有详细说明。要使得设备可以进入runtime_idle与runtime_suspend必须满足device的2个参数usage_count与child_count同时为0。
①: 操作usage_count参数通常在HOST控制器驱动中,使用辅助runtime函数来完成。
②: 操作child_count通常由子设备来完成父设备child_count的增加与减少。child_count可以理解该设备活跃的子设备的个数。
通常由子设备睡后来让父设备进入休眠,依次递归进行。

简单理解就是:看有几个使用者,如果没有就可以休眠,不依赖于android的wake_lock机制。通常linux中通讯总线都会采用runtime电源管理机制,当I/O非busy时自动休眠,也就是通讯没有数据交互的时候的总线自动进入suspend,电源管理采用不用则停的方略,以此来减少功耗。

RPM的核心机制是这样的:
①为每个设备维护一个引用计数(device->power.usage_count),用于指示该设备的使用状态。

② 需要使用设备时,device driver调用pm_runtime_get(或pm_runtime_get_sync)接口,增加引用计数;不再使用设备时,device driver调用pm_runtime_put(或pm_runtime_put_sync)接口,减少引用计数。

③ 每一次put,RPM core都会判断引用计数的值。如果为零,表示该设备不再使用(idle)了,则使用异步(ASYNC)或同步(SYNC)的方式,调用设备的.runtime_idle回调函数。

④.runtime_idle的存在,是为了在idle和suspend之间加一个缓冲,避免频繁的suspend/resume操作。因此它的职责是:判断设备是否具备suspend的条件,如果具备,在合适的时机,suspend设备。

RPM core会使用异步(ASYNC)或同步(SYNC)的方式,调用设备的.runtime_suspend回调函数,suspend设备,同时记录设备的PM状态;

可以调用RPM core提供helper函数(pm_runtime_autosuspend_expiration、pm_runtime_autosuspend、pm_request_autosuspend),要求在指定的时间后,suspend设备。

⑤pm_runtime_autosuspend、pm_request_autosuspend等接口,会起一个timer,并在timer到期后,使用异步(ASYNC)或同步(SYNC)的方式,调用设备的.runtime_suspend回调函数,suspend设备,同时记录设备的PM状态。

⑥ 每一次get,RPM core都会判断设备的PM状态,如果不是active,则会使用异步(ASYNC)或同步(SYNC)的方式,调用设备的.runtime_resume回调函数,resume设备。

注1:Runtime PM中的“suspend”,不一定要求设备必须进入低功耗状态,而是要求设备在suspend后,不再处理数据,不再和CPUs、RAM进行任何的交互,直到设备的.runtime_resume被调用。因为此时设备的parent(如bus controller)、CPU是、RAM等,都有可能因为suspend而不再工作,如果设备再有任何动作,都会造成不可预期的异常。“Documentation\power\runtime_pm.txt”中有详尽解释供参考。

猜你喜欢

转载自blog.csdn.net/cornerstone1/article/details/113183193
今日推荐