android 休眠唤醒机制分析(三) — suspend

前面我们分析了休眠的第一个阶段即浅度休眠,现在我们继续看休眠的第二个阶段 — 深度休眠。在深度休眠的过程中系统会首先冻结所有可以冻结的进程,然后依次挂起所有设备的电源,挂起顺序与设备注册的顺序相反,这样保证了设备之间电源的依赖性;直至最后进入省电模式,等待用户或者RTC唤醒;在唤醒过程中则会按照设备注册的顺序依次恢复每个设备的电源进入正常工作状态,解冻相关的进程,然后再进行浅度休眠的唤醒流程。

1、深度休眠入口

根据wake_lock一节的分析我们知道driver层进入深度休眠的入口有4个,分别为expire_timer、wake_lock、wake_lock_timeout、wake_unlock,这几个入口函数将根据相应的条件启动suspend_work里面的pm_suspend()函数进入深度休眠流程,代码在linux/kernel/power/suspend.c中:

// 进入深度休眠流程
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.\n");

	pr_debug("PM: Preparing system for %s sleep\n", 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\n", pm_states[state]);
	// 设备休眠
	error = suspend_devices_and_enter(state);

 Finish:
	pr_debug("PM: Finishing wakeup.\n");
	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、冻结进程

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、挂起设备

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);
  • 8
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值