夜雨聆风学习资料网

ARTICLE · 1279739

AI辅助移动开发|Android驱动调试:深度休眠中充电异常亮屏,是谁在wakeup?

AI辅助移动开发|Android驱动调试:深度休眠中充电异常亮屏,是谁在wakeup?
最近在跑充放电测试,出现一个奇怪的现象:同样一台机器,两个人测试,结果却不一样。对比测试手法,设置为“永不休眠”可以正常充电完成,曲线正常;但默认不设置,却大概率出现无法充到 100%、一直卡在 99% 的问题,而且在该测试情景下,设备会不时地亮起屏幕。
分析串口日志,找到唤醒源,三个可唤醒中断:
INFO: gpio0_d5 // chargeINFO: gpio0_b0 // rtcINFO: gpio3_a2
实际唤醒系统来源于 gpio0_b0,是 RTC 的中断:
INFO: wake up status: 0x100INFO: the wake up information:INFO: GPIO0 interrupt wakeupINFO: GPIO0: 0x100
亮屏日志:
rockchip-vop2 fdd90000.vop: [drm:vop2_crtc_atomic_enable] Update mode to 1200x1920p60, type: 16(if:40) for vp2 dclk: 156000000rockchip-vop2 fdd90000.vop: [drm:vop2_crtc_atomic_enable] dclk_out2 div: 2 dclk_core2 div: 2rockchip-vop2 fdd90000.vop: [drm:vop2_crtc_atomic_enable] set dclk_vop2 to 156000000, get 156000000
Health 中默认配置:插电时每 60 秒更新,未插电深睡时每 600 秒更新:
#define DEFAULT_PERIODIC_CHORES_INTERVAL_FAST (60 * 1)// Periodic chores fast interval in seconds#define DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW (60 * 10)
先初步排除 RTC 本身的原因;同时对比不接充电器的情况,休眠没有出现亮屏。于是最先怀疑充电部分。
先接入 GPT 跑一下流程:
  1. 描述充电和不充电两者测试下的现象。
  2. 分析两者测试下的 log。
  3. 找到导致退出休眠以及亮屏的因素。
  4. 给出修改和调试建议。
这里 GPT 找到一个非常有效的问题点:
休眠前          chg=a......唤醒后277.005903      chg=277.031928      chg=277.044344      PM: suspend exit277.245023      vop2_crtc_atomic_enable278.231560      chg=a
这里 chg=a -> chg= -> chg=a 可以判断:外部电源充电有抖动,RTC 唤醒之后,充电器有一个类似拔插的动作。
参照代码:
/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.javafinal long now = mClock.uptimeMillis();if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,        dockedOnWirelessCharger)) {    wakeDisplayGroupNoUpdateLocked(Display.DEFAULT_DISPLAY_GROUP, now,            PowerManager.WAKE_REASON_PLUGGED_IN,            ”android.server.power:PLUGGED:” + mIsPowered, Process.SYSTEM_UID,            mContext.getOpPackageName(), Process.SYSTEM_UID);}
device/rockchip/common/overlay/frameworks/base/core/res/res/values/config.xml<!-- If this is true, the screen will come on when you unplug usb/power/whatever. --> <boolname="config_unplugTurnsOnScreen">true</bool>
配合 dumpsys power 信息:
mWakeUpWhenPluggedOrUnpluggedConfig=true
可以看出,当系统检测到电源插拔状态发生变化的时候,会唤醒屏幕。到这,整个事件发生流程就变得很明了:
RTC 定时唤醒 CPU→ USB/充电检测恢复,电源在线状态短暂变化→ health 上报“拔电”→ PowerManagerService 按插拔策略亮屏→ 充电状态重新稳定
最直接的修改办法:config_unplugTurnsOnScreen 修改为 false。修改后验证:
dumpsys powermWakeUpWhenPluggedOrUnpluggedConfig=false
测试休眠唤醒情况:
基本符合 Health 采样频次,而且不会再有亮屏情况。到这,关于亮屏的问题就基本已经解决了。而且也可以解释,为什么电量一直卡在 99% 到不了 100%。
我们知道在恒压充电阶段:当电池电压达到一个预设的上限值(例如 4.2V),充电器会保持电压恒定,不再升高,而充电电流则会开始逐渐减小。这个阶段充电速度明显变慢,一直持续到电流小到某个阈值,系统便判定电池已充满,结束充电。
我们设置的满电停充电流为 110mA。快接近满电的情况下,充电电流才 100 多mA,比较小;而定期唤醒时充电器断开且亮屏所消耗的电池容量,要高于深睡期充进电池的电量,这才导致一直无法满电。实际测试的结果也符合预期。
你以为到这,问题解决,事情就结束了吗?
其实并没有。毕竟唤醒情况下充电器有一个断开的状态还是存在的。基于此情况,充电断开下系统也有一定的功耗,这样必然也导致充满电的时间会比理论上的要长一些。加之,如果碰到有些需要插拔唤醒系统亮屏功能的需求,应该怎么办呢?我们继续深入分析。
回到最初,我们知道根因在于 RTC 唤醒时充电有个断开重连的状态,我们需要分析出:为什么充电会断开?
按照之前的对比实验,可以确认这个断开动作只在休眠唤醒时才会出现,而且跟外部的电源没有关系。唯一的解释,充电 IC 的中断 IO 出现了异常。既然如此,我们直接抓波形来佐证,确认中断 IO gpio0_d5 确实存在一个高低的变化。查看所在电源域确认:
vcc_1v8_s3: DCDC_REG10 {    regulator-always-on;    regulator-boot-on;    regulator-min-microvolt = <1800000>;    regulator-max-microvolt = <1800000>;    regulator-name = ”vcc_1v8_s3”;    regulator-state-mem {        regulator-on-in-suspend;        regulator-suspend-microvolt = <1800000>;    };};
休眠状态保持了高电平,那为什么还会出现此种情况呢?这个跟 logic 电压休眠关闭以及休眠策略配置有关:rockchip_suspend。但是这个项目这路电不能动,只能另寻他法。
我们换个思路:如果这个中断必然存在,我们就想办法让它造成的影响降到最低。这里我想到了两个方案:
  1. 增加一个防抖的操作,触发中断之后,延时判断一下 GPIO 的状态,来确认外部电源是否真的断开。
  2. 禁用 gpio0_d5 作为唤醒源,如果是 USB 可以通过 CC 检测来唤醒,这样就相当于细分了 mWakeUpWhenPluggedOrUnpluggedConfig 的策略。
将我的想法告诉 GPT,让它帮我实现对应的代码即可。到这,问题才算有最终的结论。
这次问题整个过程:RTC定时唤醒系统的情况下 出现充电检测出现短暂抖动: chg 的变化系统判断为插拔,pm按照xml宏配置的策略点亮屏幕,而亮屏耗电又抵消了恒压末段的小电流充入的电量,导致电量卡在 99%。初步的解决方案,修改亮屏策略,虽然验证可以,而且唤醒频次也符合 Health 采样周期,但是根本的原因还在:充电ic 中断检测脚gpio0_d5 在休眠唤醒时存在电平变化。后续可以通过防抖或者禁用gpio0_d5作为唤醒源,具体的方案可以根据项目是否需要保留usb插拔亮屏功能。
AI在这次排查中主要是做两件事:第一,分析日志抓取到外部电源异常抖动的关键信息;第二,辅助实现防抖功能和唤醒源调整的相关代码。但是我们自身也要清晰了解整个流程,包括RTC唤醒判断,亮屏策略确认,波形分析,以及最终方案的定夺,都需要认为的判断,不能全依赖于AI。
以上,是全部的内容,有兴趣的朋友可以一起留言讨论。

回首页,搜索你想要的文档

在首页搜索框输入关键词,快速定位资料

文库首页搜索指引 立即搜索

相关学习资料