ARTICLE · 1279739
AI辅助移动开发|Android驱动调试:深度休眠中充电异常亮屏,是谁在wakeup?
AI辅助移动开发|Android驱动调试:深度休眠中充电异常亮屏,是谁在wakeup?最近在跑充放电测试,出现一个奇怪的现象:同样一台机器,两个人测试,结果却不一样。对比测试手法,设置为“永不休眠”可以正常充电完成,曲线正常;但默认不设置,却大概率出现无法充到 100%、一直卡在 99% 的问题,而且在该测试情景下,设备会不时地亮起屏幕。 分析串口日志,找到唤醒源,三个可唤醒中断: 实际唤醒系统来源于 gpio0_b0,是 RTC 的中断: 亮屏日志: Health 中默认配置:插电时每 60 秒更新,未插电深睡时每 600 秒更新: 先初步排除 RTC 本身的原因;同时对比不接充电器的情况,休眠没有出现亮屏。于是最先怀疑充电部分。 先接入 GPT 跑一下流程: 这里 GPT 找到一个非常有效的问题点: 这里 chg=a -> chg= -> chg=a 可以判断:外部电源充电有抖动,RTC 唤醒之后,充电器有一个类似拔插的动作。 参照代码: 配合 dumpsys power 信息: 可以看出,当系统检测到电源插拔状态发生变化的时候,会唤醒屏幕。到这,整个事件发生流程就变得很明了: 最直接的修改办法:config_unplugTurnsOnScreen 修改为 false。修改后验证: 测试休眠唤醒情况: 
基本符合 Health 采样频次,而且不会再有亮屏情况。到这,关于亮屏的问题就基本已经解决了。而且也可以解释,为什么电量一直卡在 99% 到不了 100%。 我们知道在恒压充电阶段:当电池电压达到一个预设的上限值(例如 4.2V),充电器会保持电压恒定,不再升高,而充电电流则会开始逐渐减小。这个阶段充电速度明显变慢,一直持续到电流小到某个阈值,系统便判定电池已充满,结束充电。 我们设置的满电停充电流为 110mA。快接近满电的情况下,充电电流才 100 多mA,比较小;而定期唤醒时充电器断开且亮屏所消耗的电池容量,要高于深睡期充进电池的电量,这才导致一直无法满电。实际测试的结果也符合预期。 你以为到这,问题解决,事情就结束了吗? 其实并没有。毕竟唤醒情况下充电器有一个断开的状态还是存在的。基于此情况,充电断开下系统也有一定的功耗,这样必然也导致充满电的时间会比理论上的要长一些。加之,如果碰到有些需要插拔唤醒系统亮屏功能的需求,应该怎么办呢?我们继续深入分析。 回到最初,我们知道根因在于 RTC 唤醒时充电有个断开重连的状态,我们需要分析出:为什么充电会断开? 按照之前的对比实验,可以确认这个断开动作只在休眠唤醒时才会出现,而且跟外部的电源没有关系。唯一的解释,充电 IC 的中断 IO 出现了异常。既然如此,我们直接抓波形来佐证,确认中断 IO gpio0_d5 确实存在一个高低的变化。查看所在电源域确认: 休眠状态保持了高电平,那为什么还会出现此种情况呢?这个跟 logic 电压休眠关闭以及休眠策略配置有关:rockchip_suspend。但是这个项目这路电不能动,只能另寻他法。 我们换个思路:如果这个中断必然存在,我们就想办法让它造成的影响降到最低。这里我想到了两个方案: 将我的想法告诉 GPT,让它帮我实现对应的代码即可。到这,问题才算有最终的结论。 这次问题整个过程:RTC定时唤醒系统的情况下 出现充电检测出现短暂抖动: chg 的变化系统判断为插拔,pm按照xml宏配置的策略点亮屏幕,而亮屏耗电又抵消了恒压末段的小电流充入的电量,导致电量卡在 99%。初步的解决方案,修改亮屏策略,虽然验证可以,而且唤醒频次也符合 Health 采样周期,但是根本的原因还在:充电ic 中断检测脚gpio0_d5 在休眠唤醒时存在电平变化。后续可以通过防抖或者禁用gpio0_d5作为唤醒源,具体的方案可以根据项目是否需要保留usb插拔亮屏功能。 AI在这次排查中主要是做两件事:第一,分析日志抓取到外部电源异常抖动的关键信息;第二,辅助实现防抖功能和唤醒源调整的相关代码。但是我们自身也要清晰了解整个流程,包括RTC唤醒判断,亮屏策略确认,波形分析,以及最终方案的定夺,都需要认为的判断,不能全依赖于AI。 以上,是全部的内容,有兴趣的朋友可以一起留言讨论。
INFO: gpio0_d5 // chargeINFO: gpio0_b0 // rtcINFO: gpio3_a2
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
#define DEFAULT_PERIODIC_CHORES_INTERVAL_FAST (60 * 1)// Periodic chores fast interval in seconds#define DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW (60 * 10)
描述充电和不充电两者测试下的现象。 分析两者测试下的 log。 找到导致退出休眠以及亮屏的因素。 给出修改和调试建议。
休眠前 chg=a......唤醒后277.005903 chg=277.031928 chg=277.044344 PM: suspend exit277.245023 vop2_crtc_atomic_enable278.231560 chg=a
/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>
mWakeUpWhenPluggedOrUnpluggedConfig=trueRTC 定时唤醒 CPU→ USB/充电检测恢复,电源在线状态短暂变化→ health 上报“拔电”→ PowerManagerService 按插拔策略亮屏→ 充电状态重新稳定
dumpsys powermWakeUpWhenPluggedOrUnpluggedConfig=false

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>;};};
增加一个防抖的操作,触发中断之后,延时判断一下 GPIO 的状态,来确认外部电源是否真的断开。 禁用 gpio0_d5 作为唤醒源,如果是 USB 可以通过 CC 检测来唤醒,这样就相当于细分了 mWakeUpWhenPluggedOrUnpluggedConfig 的策略。















































































