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项设置如下:

Android功耗调试汇总
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 分析底电流波形

波形分析对功耗调试至关重要,能够提供问题的本质和正确的调试方向的信息。

底电流波形主要分为以下两个部分:
◆ 基底电流:系统处于XO关闭和VDD最小化时的最小电流,此时XO是关闭的,各路LDO电处于最小化的状态。
◆ 唤醒,例如电量计唤醒和PMIC看门狗唤醒
下图是捕捉自MSM8994芯片组的底电流用例波形的快照。

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

3.1.4 检查飞行模式下的各路LDO

参考高通平台提供的飞行模式下的LDO通断以及消耗情况(对应平台的linux_android_current_consumption_data文档),对比测试自己的样机状态,确认有哪些LDO没有关闭,或者是消耗过大;甚至是外围器件的倒灌消耗。以8953为例,参考如下:

Android功耗调试汇总
Android功耗调试汇总
可以观察到,如图左侧的时钟日志所示,有27个时钟显示为已启用,但系统却在没有任何问题的情况下进入了XO关闭/VDD最小化。RPM稍后会关闭这些时钟/PLL,这些时钟是BIMC、系统总线和子系统PLL等主要共享资源的一部分。

如图右侧的时钟日志所示,有35个时钟已启用,但少数时钟具有区别性特征。
– APSS请求CXO时钟源。
– MDP(显示子系统)时钟已启用,表明驱动程序抑制了CXO进入电力休眠。

(4)检查中断
中断频率较高会抑制系统进入XO关闭/VDD最小化。

3.1.5.2 确认modem是否待机

可以配置RPM的log查看modem的sleep情况。详细查看《80-nl239-48 power_consumption_optimization_and_debugging_for_msm8916_devices》的2.1.5 Ensuring modem sleep。

3.1.5.3 检查wcnss是否待机

3.1.6 检查异常唤醒

3.1.6.1检查APSS的唤醒

启用适当记录功能的kernel日志能够指示APSS是否从其睡眠状态中唤醒以及唤醒原因(如果唤醒)。可以打开以下调试掩码,以便在kernel日志中记录中断信息:
echo 1 > /sys/module/msm_show_resume_irq/parameters/debug_mask
检查kernel日志中的输出数以确定哪个中断唤醒了APSS。以下代码段显示,是电源键按下中断qpnp_kpdpwr_status唤醒了APSS。

3.1.7 检查外部器件的电流消耗

如果终端进入VDD最小化后,基底电流仍然大于预期值,则可以判断:终端中存在某个或者多个泄漏源,导致了总电流的消耗。可能有如下原因:
(1)睡眠期间未使用但启用了的SMPS和LDO的泄漏(一般该原因较少)
(2)GPIO的上下拉配置不正确导致的电流消耗
(3)外围器件未进行低功耗模式配置(通过最小系统版本,逐步拆除硬件的方式来逐步排除)

3.2 待机电流(待完善)

待机电流由底电流和唤醒电流平均组成。总的平均待机电流主要依赖于平均底电流的电流消耗。若尚未优化底电流,则待机优化的第一步是优化底电流的电流消耗。理论上,手机待机时,电流应该是比较规则的按照DRX周期进行唤醒。电流消耗捕捉工具提供的波形非常有助于分析寻呼唤醒产生的唤醒损失。
下图展示了DRX寻呼周期中所涉及的不同系统模块的活动阶段的寻呼唤醒波形的关联部分。

Android功耗调试汇总
4.13 sensor供电和i2c上拉电源不一致导致的电流问题
4.14 usb otg 控制器没有关闭导致的电流问题
4.15 modem没有正常起来以及模式不对造成的电流异常
4.16 otg的休眠
4.17 某项目在滑屏解锁后再待机电流就大15mA左右(和uart的功能配置有关系)
4.18 9×07某项目未使用的GPIO没有正确配置上下拉导致的底电流大4-5mA
4.19 某项目modem侧定时器造成的100ms的定时唤醒
Android功耗调试汇总

5. 补充要点

5.1 runtime PM机制参考

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

主要代码放在Runtime.c (driversbasepower)中,同时附带的Runtime_pm.txt (documentationpower)有详细说明。要使得设备可以进入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而不再工作,如果设备再有任何动作,都会造成不可预期的异常。“Documentationpowerruntime_pm.txt”中有详尽解释供参考。

来源:归心2020

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年11月6日
下一篇 2022年11月6日

相关推荐