专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
电源
android 休眠唤醒机制分析(三) — suspend
2019-07-14 02:09
发布
生成海报
站内文章
/
电源技术
12597
0
1205
前面我们分析了休眠的第一个阶段即浅度休眠,现在我们继续看休眠的第二个阶段 — 深度休眠。在深度休眠的过程中系统会首先冻结所有可以冻结的进程,然后依次挂起所有设备的电源,
挂起顺序与设备注册的顺序相反
,这样保证了设备之间电源的依赖性;直至最后进入省电模式,等待用户或者RTC唤醒;在唤醒过程中则会按照设备注册的顺序依次恢复每个设备的电源进入正常工作状态,解冻相关的进程,然后再进行浅度休眠的唤醒流程。
1、深度休眠入口
根据wake_lock一节的分析我们知道driver层进入深度休眠的入口有4个,分别为expire_timer、wake_lock、wake_lock_timeout、wake_unlock,这几个入口函数将根据相应的条件启动suspend_work里面的pm_suspend()函数进入深度休眠流程,代码在linux/kernel/power/suspend.c中:
[cpp]
view plain
copy
// 进入深度休眠流程
int
enter_state(suspend_state_t state)
{
int
error;
// 判断平台是否支持该状态
if
(!valid_state(state))
return
-ENODEV;
if
(!mutex_trylock(&pm_mutex))
return
-EBUSY;
// 同步缓存
printk(KERN_INFO
"PM: Syncing filesystems ... "
);
sys_sync();
printk(
"done. "
);
pr_debug(
"PM: Preparing system for %s sleep "
, pm_states[state]);
// 做好休眠准备
error = suspend_prepare();
if
(error)
goto
Unlock;
// suspend_test
if
(suspend_test(TEST_FREEZER))
goto
Finish;
pr_debug(
"PM: Entering %s sleep "
, pm_states[state]);
// 设备休眠
error = suspend_devices_and_enter(state);
Finish:
pr_debug(
"PM: Finishing wakeup. "
);
suspend_finish();
Unlock:
mutex_unlock(&pm_mutex);
return
error;
}
int
pm_suspend(suspend_state_t state)
{
if
(state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX)
return
enter_state(state);
return
-EINVAL;
}
EXPORT_SYMBOL(pm_suspend);
在enter_state()中首先进入状态的判断,根据平台的特性判断是否支持此状态;然后再同步缓存;接着调用suspend_prepare()冻结大部分进程;然后再通过suspend_devices_and_enter()开始挂起设备。
2、冻结进程
[cpp]
view plain
copy
static
int
suspend_prepare(
void
)
{
int
error;
if
(!suspend_ops || !suspend_ops->enter)
return
-EPERM;
pm_prepare_console();
// 通知进行休眠准备
error = pm_notifier_call_chain(PM_SUSPEND_PREPARE);
if
(error)
goto
Finish;
// 禁止usermodehelper
error = usermodehelper_disable();
if
(error)
goto
Finish;
// 冻结所有可以冻结的进程
error = suspend_freeze_processes();
if
(!error)
return
0;
// 解冻所有进程
suspend_thaw_processes();
// 使能usermodehelper
usermodehelper_enable();
Finish:
// 通知休眠结束
pm_notifier_call_chain(PM_POST_SUSPEND);
pm_restore_console();
return
error;
}
这里有一个notifier机制后面要专门分析下。
3、挂起设备
[cpp]
view plain
copy
int
suspend_devices_and_enter(suspend_state_t state)
{
int
error;
if
(!suspend_ops)
return
-ENOSYS;
// 处理器的休眠开始函数
if
(suspend_ops->begin) {
error = suspend_ops->begin(state);
if
(error)
goto
Close;
}
// 休眠串口
suspend_console();
suspend_test_start();
// 设备休眠
error = dpm_suspend_start(PMSG_SUSPEND);
if
(error) {
printk(KERN_ERR
"PM: Some devices failed to suspend "
);
goto
Recover_platform;
}
suspend_test_finish(
"suspend devices"
);
if
(suspend_test(TEST_DEVICES))
goto
Recover_platform;
// 处理器休眠
suspend_enter(state);
Resume_devices:
suspend_test_start();
// 设备唤醒
dpm_resume_end(PMSG_RESUME);
suspend_test_finish(
"resume devices"
);
// 唤醒串口
resume_console();
Close:
// 处理器的休眠结束函数
if
(suspend_ops->end)
Ta的文章
更多
>>
android 休眠唤醒机制分析(三) — suspend
0 个评论
热门文章
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮