和你一起终身学习,这里是程序员Android
经典好文推荐,通过阅读本文,您将收获以下知识点:
一、手机功耗问题浅析博文
二、Sleep 、suspend
三、SPM (System Power Manager)
四、Deep idle
五、SODI (screen on deep idle)
六、systrace/ftrace
七、wireshark
八、layerdump
九、如何确定阻止进入suspend的原因
十、如何分析wakelock(wakeup source)持锁问题
十一、如何看SPM的状态是否正确
十二、如何查找待机唤醒源
十三、如何找到阻止进入deep idle / SODI的元凶
一、手机功耗问题浅析博文
手机功耗问题直接影响到手机的待机时长,因此,解决功耗问题对于智能机十分必要。
之前有写过一个功耗浅析的文章,可以先参考下:
手机功耗问题浅析博文
二、Sleep 、suspend
这里的suspend
确切的说是MCU(ARM )
的 suspend
,也就是cpu
进入Wait for interrupt
状态(WFI
);因为对整个系统来说,CPU
进WFI
是整个系统睡眠的先决条件,我们debug
也是从CPU
是否进入WFI
开始,从Linux
的角度来说,CPU
进入suspend
就是SW
完全不跑了,停在suspend workqueue
里面。
从灭屏到CPU
进入suspend
的大体流程框架如下:
从灭屏到`CPU`进入suspend的大体流程框架
相关code路径:
/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
/frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
/system/core/libsuspend/
/kernel-x.x/kernel/power/
三、SPM (System Power Manager)
因为整个系统不只是AP(MCU)
,还包括modem、connectivity
等子系统;
CPU 进入 WFI 后,整个系统就依靠一颗 SCP:SPM
来控制睡眠/唤醒的流程,它会去关注各个子系统的状态
SPM =System Power Manager
它掌控着cpu suspend
之后系统是否能掉到最小电流的关键逻辑,你可以把它理解成一个投票机制,当系统的关键资源(memory、clock
)没有任何人使用的时候,它就会让系统进入一个真正的深睡状态(最小电流)只要它检测到有任何资源请求还没释放,系统就无法降到底电
所以在底电问题上的debug
流程中,我们不仅仅要看cpu
有没有suspend
成功,还要看SPM
的状态是否正确,SPM
里面有一个可编程控制器PCM(Programmable Command Master)
。CPU
在进去WFI
之前会把SPM
的firmware
写入PCM
,然后PCM
就依据firmware
的逻辑来控制SPM
的工作
跟SPM
强相关的一个东西就是系统中的时钟请求信号,也就是26M
时钟开关的控制逻辑;因为系统工作在最小电流的时候,SPM
只依靠32K
时钟工作;因此要判断系统是不是已经到深睡状态,就要看26M
有没有关闭
26M
时钟的控制逻辑概要如下图
26M 时钟控制逻辑
所以从上图我们就可以看到, 26M
有没有关,就只要看SCLKENA
这个信号有没有关闭;而SPM
对这个信号的输出以及子系统的信号输入,都会记录在SPM
的寄存器里面,这个就是我们通过log
排查的依据
代码路径/kernel-x.x/drivers/misc/mediatek/base/power/spm_vx/
四、Deep idle
Deep idle 基本概念
首先顾名思义,这是一种CPU
进入空闲后的状态,也就是在idle
进程中执行的
简单地说,Mediatek
会在CPU
进入空闲的情况下,再去关闭一些不必要的power domain
,以达到最省电的目的,因为CPU
空闲的时候,其实系统中有不少的domain
也是不需要运行的,不这样做的话,就仅仅是CPU
这块的电省下来 ,达不到省电的目的。
Mediatek的做法是在CPU
在进入idle
进程后,会去判断当前系统的状态是否满足进入更省电状态的条件,首先就会检查是否能进入deep idle
,因为dpidle最省电
系统进入dpidle需要满足的条件是
单核(BY_CPU)
预设的能block deep idle的所有clock都已经关闭(BY_CLOCK)
CPU在2ms内没有从idle task调度出去的需求(BY_TMR)
BY_VTG / BY_OTH的case很少(BY_OTH在个别平台跟TEE(SPI指纹模块)有关)
我们可以从波形上检查系统是否进入deep idle
下图中电流的底部就是deep idle
的状态,在MP3
播放的状态大约20mA
;
如果没有进deep idle
,这个底部会被抬高