完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1.用户态睡眠流程
framework/base/services/core/java/com/android/server/power/PowerManagerService.java updatePowerStateLocked()-> updateSuspendBlockerLocked()->setHalAutoSuspendModeLocked()->nativeSetAutoSuspend(); 调用此接口陷入jni调用: framework/base/services/core/jni/com_android_server_power_PowerManagerService.cpp nativeSetAutoSuspend()->autosuspend_enable(); 直接调用掉libautosuspend中的配置函数 system/core/libsuspend/autosuspend.c autosuspend_enable()中通过回调autosuspend_ops->enable();调用到autosuspend_earlysuspend_enable()中,在此函数中执行write系统调用。 将mem的字符串通过sys虚拟文件系统,写入/sys/power/state引起kernel中的休眠流程。 2.kernel中的休眠流程: /kernel/kernel/power/main.c state_store()通过decode_state()函数确认当前的睡眠状态,调用pm_suspend();引起睡眠; 调用到enter_state() static int enter_state(suspend_state_t state) { int error; if (!valid_state(state)) return -ENODEV; if (!mutex_trylock(&pm_mutex)) return -EBUSY; if (state == PM_SUSPEND_FREEZE) freeze_begin(); printk(KERN_INFO "PM: Syncing filesystems ... "); sys_sync(); printk("done.n"); pr_debug("PM: Preparing system for %s sleepn", pm_states[state]); error = suspend_prepare(state); if (error) goto Unlock; if (suspend_test(TEST_FREEZER)) goto Finish; pr_debug("PM: Entering %s sleepn", pm_states[state]); pm_restrict_gfp_mask(); error = suspend_devices_and_enter(state); pm_restore_gfp_mask(); Finish: pr_debug("PM: Finishing wakeup.n"); suspend_finish(); Unlock: mutex_unlock(&pm_mutex); return error; } 个人感觉比较重要的是suspend_prepare()和suspend_devices_and_enter() static int suspend_prepare(suspend_state_t state) { int error; if (need_suspend_ops(state) && (!suspend_ops || !suspend_ops->enter)) return -EPERM; pm_prepare_console(); error = pm_notifier_call_chain(PM_SUSPEND_PREPARE);//通过内核通知链通知所有期望的得到SUSPEND_PREPARE消息模块 if (error) goto Finish; error = suspend_freeze_processes();//冻结进程,首先usr进程,然后kernel workqueue if (!error) return 0; suspend_stats.failed_freeze++; dpm_save_failed_step(SUSPEND_FREEZE); Finish: pm_notifier_call_chain(PM_POST_SUSPEND); pm_restore_console(); return error; } 对于int suspend_devices_and_enter(suspend_state_t state) { int error; bool wakeup = false; if (need_suspend_ops(state) && !suspend_ops) return -ENOSYS; trace_machine_suspend(state); if (need_suspend_ops(state) && suspend_ops->begin) { error = suspend_ops->begin(state); if (error) goto Close; } suspend_console(); ftrace_stop(); suspend_test_start(); error = dpm_suspend_start(PMSG_SUSPEND); //通过此函数调用到device_suspend();引起各个设备注册suspend函数被调用 if (error) { printk(KERN_ERR "PM: Some devices failed to suspendn"); goto Recover_platform; } suspend_test_finish("suspend devices"); if (suspend_test(TEST_DEVICES)) goto Recover_platform; do { error = suspend_enter(state, &wakeup);//系统从此函数真正进入休眠。 } while (!error && !wakeup && need_suspend_ops(state) && suspend_ops->suspend_again && suspend_ops->suspend_again()); Resume_devices: suspend_test_start(); dpm_resume_end(PMSG_RESUME); suspend_test_finish("resume devices"); ftrace_start(); resume_console(); Close: if (need_suspend_ops(state) && suspend_ops->end) suspend_ops->end(); trace_machine_suspend(PWR_EVENT_EXIT); return error; Recover_platform: if (need_suspend_ops(state) && suspend_ops->recover) suspend_ops->recover(); goto Resume_devices; } static int suspend_enter(suspend_state_t state, bool *wakeup) { int error; if (need_suspend_ops(state) && suspend_ops->prepare) { error = suspend_ops->prepare(); if (error) goto Platform_finish; } error = dpm_suspend_end(PMSG_SUSPEND); if (error) { printk(KERN_ERR "PM: Some devices failed to power downn"); goto Platform_finish; } if (need_suspend_ops(state) && suspend_ops->prepare_late) { error = suspend_ops->prepare_late(); if (error) goto Platform_wake; } if (suspend_test(TEST_PLATFORM)) goto Platform_wake; /* * PM_SUSPEND_FREEZE equals * frozen processes + suspended devices + idle processors. * Thus we should invoke freeze_enter() soon after * all the devices are suspended. */ if (state == PM_SUSPEND_FREEZE) { freeze_enter(); goto Platform_wake; } error = disable_nonboot_cpus(); if (error || suspend_test(TEST_CPUS)) goto Enable_cpus; arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); error = syscore_suspend(); //使真正的内核进入休眠。 if (!error) { *wakeup = pm_wakeup_pending(); if (!(suspend_test(TEST_CORE) || *wakeup)) { error = suspend_ops->enter(state); events_check_enabled = false; } syscore_resume(); //当有中断打破当前的睡眠状态,将引起系统的唤醒,首先是core唤醒,后续返回到int suspend_devices_and_enter(suspend_state_t state) //继续执行唤醒流程 } arch_suspend_enable_irqs(); BUG_ON(irqs_disabled()); Enable_cpus: enable_nonboot_cpus(); Platform_wake: if (need_suspend_ops(state) && suspend_ops->wake) suspend_ops->wake(); dpm_resume_start(PMSG_RESUME); Platform_finish: if (need_suspend_ops(state) && suspend_ops->finish) suspend_ops->finish(); return error; } 原作者:greatmandon |
|
相关推荐
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1984 浏览 3 评论
rk1126实现BT601输入,输入不带IIC接口的驱动程序
3733 浏览 0 评论
2330 浏览 1 评论
3556 浏览 3 评论
RK3568 Android11让系统ntp校准时间生效,需要设置些什么
3818 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-9-28 23:13 , Processed in 0.649637 second(s), Total 69, Slave 53 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号