待机异常2


2023年12月20日发(作者:intel显卡驱动)

待机异常篇待机异常篇待机异常1:按Powerkey后,连early_suspend都没进。待机异常2:可以进early_suspend,但进不了suspend待机异常3:可以进suspend,但出现:PM:Somedevicesfailedtosuspend待机异常4:可以进入到suspend_enter,suspend流程走完了,但很快被唤醒待机异常5:可以进入到suspend_enter,也不被唤醒,但电流很大,CPU也较烫

关于early_suspend:由于/sys/power/autosleep在处理suspend时,并没有像/sys/power/state那样,有对earlysuspend的兼容处理,如:Kernel/kernel/power/cssize_tstate_store(structkobject*kobj,structkobj_attribute*attr,constchar*buf,size_tn){....#ifdefCONFIG_EARLYSUSPENDif(state==PM_SUSPEND_ON||valid_state(state)){error=0;request_suspend_state(state);}#elseerror=pm_suspend(state);#endif进入request_suspend_state会先处理earlysuspend,然后再进入suspend。而autosleep在处理时,是直接进入pm_suspend,不会去处理earlysuspend。因此,不同平台处理earlysuspend的方式也不同,如Intel平台是通过将所有/sys/power/early_suspend/xxdevic/early_suspend文件写1使其对应的设备进入earlysuspend(代码路径:hardwarelibhardwaremodulespower),该操作发生在上图

ANDROID待机流程的blankAllDisplays,在blankAllDisplays函数里,会先调用nativeSetInteractive进入early_suspend,再调用nativeSetAutoSuspend进入suspend。/sys/power/early_suspend/xxdevic/early_suspend节点通过下面接口生成:device_create_file(&dev->pdev->dev,&dev_attr_early_suspend);register_early_suspend_device(&dev->pdev->dev);待机异常1:按Powerkey后,连early_suspend都没进。问题分析这种情况发生在Android待机流程中的goToSleepInternal,由于不满足待机条件而无法进入待机。不能进入待机的条件:privatebooleangoToSleepNoUpdateLocked(longeventTime,intreason){if(eventTime调试方法mBootCompleted在收到_BOOT_COMPLETED广播后置1,而_BOOT_COMPLETED广播是在进入到Launcher后发出的,fra,因此当系统启动异常时进入不到Launcher,就无法待机;还有一种情问,多Launcher选择界面时也因没进入Launcher而不发ACTION_BOOT_COMPLETED广播而造成待不了机。当ActivityManagerService跑起来就表示mSystemReady为true,可以通过查看logcat,如果看到有“ActivityManager”的log表示已跑ActivityManagerService,如果看到“************Failurestartingbootstrapservice”,表示启动失败。待机异常2:可以进early_suspend,但进不了suspend问题分析进入suspend时,会调用pm_get_wakeup_count,如果系统存在wake_lock就会卡在这个函数里,如:pm_get_wakeup_count:

prepare_to_wait(&wakeup_count_wait_queue,&wait,TASK_INTERRUPTIBLE);当wake_lock释放完毕时才会唤醒该wait,如下inpr=0:wakeup_source_deactivate:if(!inpr&&waitqueue_active(&wakeup_count_wait_queue))wake_up(&wakeup_count_wait_queue);调试方法在串口终端下,不要连接USB,连USB会产生wake_lock,cat/sys/power/wakeup_count,这时会去调用pm_get_wakeup_count,如果cat也卡住,说明存在suspend确实是卡在wake_lock上。Wake_lock有些是android进程加的和有些是kernel进程加的。可以通过命令cat/sys/kernel/debug/wakeup_sources来查看所有的wake_lock,如下:active_since所在列,如果有数值大于0,表示其所对应的行是当前活动的wake_lock,如上图,cks和dwc_wake_lock是活动的。原代码的打印有可能对不齐,下面的改动可以让其对齐:---a/kernel/drivers/base/power/wakeup.c+++b/kernel/drivers/base/power/wakeup.c@@-842,8+842,7@@staticintprint_wakeup_source_stats(structseq_file*m,-ret=seq_printf(m,"%-12st%lutt%lutt%lutt%lutt"-"%lldtt%lldtt%lldtt%lldtt%lldn",+ret=seq_printf(m,"%-35s%-15lu%-15lu%-15lu%-15lu%-15lld%-15lld%-15lld%-15lld%-15lldn",ws->name,active_count,ws->event_count,ws->wakeup_count,ws->expire_count,ktime_to_ms(active_time),ktime_to_ms(total_time),@@-863,9+862,8@@staticintwakeup_sources_stats_show(structseq_file*m,void*unused){-seq_puts(m,"namettactive_counttevent_counttwakeup_countt"

-"expire_counttactive_sincettotal_timetmax_timet"-"last_changetprevent_suspend_timen");+seq_printf(m,"%-35s%-15s%-15s%-15s%-15s%-15s%-15s%-15s%-15s%-15sn",+"name","active_count","event_count","wakeup_count","expire_count","active_since","total_time","max_time","last_changandroid加的wake_lock可以通过命令cat/sys/power/wake_lock来查看,再在kernel/kernel/power/main.c的wake_lock_store函数里加上打印:printk("pid%dwirte%sto/sys/power/wake_lockn",current->pid,buf);,将pid打印出来,然后cat/proc/进程ID/status来查看具体进程(也可以ps进程ID号来查看)。待机异常3:可以进suspend,但出现:PM:Somedevicesfailedtosuspend问题分析有些设备在待机时失败了。调试方法首先用命令cat/sys/kernel/debug/suspend_stats查看待机异常发生在哪个阶段,如下:success:3fail:1failed_freeze:0failed_prepare:0failed_suspend:1failed_suspend_late:0failed_suspend_noirq:0failed_resume:0failed_resume_early:0failed_resume_noirq:0failures:last_failed_dev:last_failed_errno:last_failed_step:-160suspendfailed_suspend的记数大于0表示在device_suspend阶段异常。从log可以看到,如果是这样的字段:activewakeupsource:event3-556PM:Somedevicesfailedtosuspend则表示有些活动wakeup锁还没释放。在kernel/drivers/base/power/wakeup.c的

wakeup_source_add函数里添加打印:printk("%s:%sn",__FUNCTION__,ws->name);dump_stack();跟踪出哪个驱动,然后在该驱动里跟踪wakeup锁。如果log是这样的:PM:Devicexxxfailedtoxxx:errorxPM:Somedevicesfailedtosuspend则表示有设备在待机时失败,根据设备名到相应驱动,然后跟踪该驱动suspend失败的原因。另外,将kernel/kernle/printk.c里的ignore_loglevel置1:Kernel/kernel/cbool__read_mostlyignore_loglevel=1;用命令echo1>/sys/power/pm_print_times打开kernel/drivers/base/power/main.c里的initcall_debug_report打印,这样,在待机时就可以打印出哪些设备待机成功或失败。待机异常4:可以进入到suspend_enter,suspend流程走完了,但很快被唤醒问题分析Suspend流程走完后被唤醒,说明有唤醒源异常,造成异常唤醒。调试方法首先用命令cat/sys/kernel/debug/suspend_stats查看待机过程是否正常,如果正常,那么需要出唤醒源。打开kernel/kernel/irq/pm.c的resume_irqs函数里的打印信息:#ifdefCONFIG_PM_DEBUGif(desc->istate&IRQS_PENDING){printk(KERN_DEBUG"WakeupfromIRQ%d%sn",irq,desc->action&&desc->action->name?desc->action->name:"");}#endif/*CONFIG_PM_DEBUG*/从打印信息里可以看出是哪个中断号唤醒的,命令cat/proc/interrupts可以查看所有中断。另外,在kernel/kernel/irq/manage.c的__setup_irq函数里加打印及dump_stack,跟踪哪个驱动注册了该irq号:printk("%s:irq=%d,name=%sn",__FUNCTION__,irq,new->name?new->name:"");dump_stack();

待机异常5:可以进入到suspend_enter,也不被唤醒,但电流很大,CPU也较烫问题分析进入suspend_enter且不被唤醒,说明系统已进入待机,应该是SOC没进入待机状态造成调试方法可以在suspend_enter加SOCpowerstate的寄存器的打印,或者跟vendor要soc待机的调试手段,比如intel平台,可以通过查询cat/sys/kernel/debug/mid_pmu_states查询cpu有几次进入待机状态。


本文发布于:2024-09-24 16:22:21,感谢您对本站的认可!

本文链接:https://www.17tex.com/fanyi/16708.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:待机   进入   唤醒   调试   打印
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议