Android休眠唤醒流程


标准linux休眠过程:
power management notifiers are executed with PM_SUSPEND_PREPARE
tasks are frozen
target system sleep state is announced to the platform-handling code
devices are suspended
platform-specific global suspend preparation methods are executed
non-boot CPUs are taken off-line
interrupts are disabled on the remaining (main) CPU
late suspend of devices is carried out (一般有一些BUS driver的动作进行)‏
platform-specific global methods are invoked to put the system to sleep
标准linux唤醒过程:
the main CPU is switched to the appropriate mode, if necessary
early resume of devices is carried out (一般有)
platform-specific global resume preparation methods are invoked
devices are woken up
tasks are thawed
power management notifiers are executed with PM_POST_SUSPEND
用户可以通过sys文件系统控制系统进入休眠一些BUS driver的动作进行)‏
interrupts are enabled on the main CPU
non-boot CPUs are enabled :
查看系统支持的休眠方式:
#cat /sys/power/state
常见有standby(suspend to RAM)、mem(suspend to RAM)和disk(suspend to disk),只是standby耗电更多,返回到正常工作状态的时间更短。
#echo mem > /sys/power/state 让系统进入休眠。
#echo on > /sys/power/state 使系统唤醒。
Android休眠与唤醒
android是在传统的linux内核电源管理设计的基础上,结合手机设计的实际需求而进化出的一套电源管理系统,其核心内容有:wakelock 、early_suspend与late_resume。
wakelock在Android的电源管理系统中扮演一个核心的角色。wakelock是一种锁的机制, 只要有人拿着这个锁,系统就无法进入休眠,可以被用户态程序和内核获得。这个锁可以是有超时的或者是没有超时的,超时的锁会在时间过去以后自动解锁。如果没有锁了或者超时了,内核就会启动休眠的那套机制来进入休眠。
当系统在启动完毕后,会自己去加一把名为“main“的锁,而当系统有意愿去睡眠时则会先去释放这把“main”锁,在android中,在early_suspend的最后一步会去释放“main”锁(wake_unlock: main)。释放完后则会去检查是否还有其他存在的锁,如果没有则直接进入睡眠过程。
它的缺点是,如果有某一应用获锁而不释放或者因一直在执行某种操作而没时间来释放的话,则会导致系统一直进入不了睡眠状态,功耗过大。
early_suspend:先与linux内核的睡眠过程被调用。一般在手机系统的设计中对背光的操作等采用此类方法,因为背光需要的能耗过大。当然此操作与late_resume是配套使用的。一些在内核中要预先进行处理的事件可以先注册上early_suspend函数,当系统要进入睡眠之前会首先调用这些注册的函数。

本文中,linux kernel版本为 linux-3.10,android版本为 android 4.4
与android休眠唤醒主要相关的文件主要有:
kernel/power/main.c
kernel/power/earlysuspend.c
kernel/power/wakelock_android.c
kernel/power/userwakelock.c
driver/base/power/main.c
arch/xxx/mach-xxx/pm.c或linux_source/arch/xxx/plat-xxx/pm.c
Android 休眠过程如下:
1 suspend state
Suspend/Resume是Linux系统电源管理的一个重要功能,suspend可以在系统不使用的情况下进入低功耗活休眠状态下从而节省系统电源。Linux系统的suspend有四种状态,对于不同的体系结构或者电源管理接口来说,状态的含义不一定完全相同,但是不会有太大的差别。下面的是ACPI电源接口的含义及其对应的Sleep State。
On (on) S0 - Working
Standby (standby) S1 - CPU and RAM are powered but not executed
Suspend to RAM (mem) S3 - RAM is powered and the running content is saved to RAM
Suspend to Disk,Hibernation (disk) S4 - All contect is saved to Disk and power down
2 suspend用户空间接口
Linux系统的电源管理Suspend框架跟Linux系统的驱动模型(Linux Driver Model) 是相关的,也是基于Linux的驱动模型来实现的。Linux的Suspend系统分为两部分,一部分是平台无关的核心层,另一个是平台相关的平台层。操作接口都在平台无关的核心层里了。
根据Linux系统驱动模型,device结构描述了一个设备,device_driver是设备的驱动,而class、type和bus分别描述了设备所属的类别、类型和总线。而设备的电源管理也根据此模型分为class级的、type级的、bus级的和驱动级的。如果一个设备的class或者bus确切的知道如何管理一个设备的电源的时候,驱动级别的suspend/resume就可以为空了。这极大的提高了电源管理的高效性和灵活性。
Linxux系统的suspend核心代码位于kernel/power目录下,主要的文件是main.c 和 suspend.c。平台相关的代码一般位于平台(arch)的电源管理模块里。
kernel/power/main.c
power_attr(state);
宏展开,等价于:
static struct kobj_attribute state_attr = {
.attr = {
.name = “state”,
.mode = 0644,
},
.show = state_show,
.store = state_store,
}
创建细节同power_attr(wake_lock);
至此,在sysfs中的应用接口为/sys/power/state创建。
3 suspend流程
3.1 state_store()
当用户读写/sys/power/state时,state_store()函数会被调用。
static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n)
{
suspend_state_t state;
int error;

error = pm_autosleep_lock();
if (error)
	return error;

if (pm_autosleep_state() > PM_SUSPEND_ON) {
	error = -EBUSY;
	goto out;
}

/*decode suspend状态,
#define PM_SUSPEND_ON ((__force suspend_state_t) 0)
#define PM_SUSPEND_FREEZE ((__force suspend_state_t) 1)
#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 2)
#define PM_SUSPEND_MEM ((__force suspend_state_t) 3)
#define PM_SUSPEND_MIN PM_SUSPEND_FREEZE
#define PM_SUSPEND_MAX ((__force suspend_state_t) 4)
*/
state = decode_state(buf, n);
if (state < PM_SUSPEND_MAX)
{
#ifdef CONFIG_EARLYSUSPEND
//android early_suspud由宏控制
//if 唤醒或者可支持的睡眠(mem)
if (state == PM_SUSPEND_ON || valid_state(state)) {
error = 0;
request_suspend_state(state);
}
#else
//linux标准的suspend流程
error = pm_suspend(state);
#endif
}
else if (state == PM_SUSPEND_MAX)
error = hibernate();
else
error = -EINVAL;

out:
pm_autosleep_unlock();
return error ? error : n;
}

bool valid_state(suspend_state_t state)
{
if (state == PM_SUSPEND_FREEZE) {
#ifdef CONFIG_PM_DEBUG
if (pm_test_level != TEST_NONE &&
pm_test_level != TEST_FREEZER &&
pm_test_level != TEST_DEVICES &&
pm_test_level != TEST_PLATFORM) {
printk(KERN_WARNING "Unsupported pm_test mode for "
"freeze state, please choose "
“none/freezer/devices/platform.\n”);
return false;
}
#endif
return true;
}
/*
* PM_SUSPEND_STANDBY and PM_SUSPEND_MEMORY states need lowlevel
* support and need to be valid to the lowlevel
* implementation, no valid callback implies that none are valid.
*/
return suspend_ops && suspend_ops->valid && suspend_ops->valid(state);
}

static const struct platform_suspend_ops *suspend_ops;
void suspend_set_ops(const struct platform_suspend_ops *ops)
{
lock_system_sleep();
suspend_ops = ops;
unlock_system_sleep();
}
在板级相关的文件中设置:
/arch/arm/plat-samsung/pm.c
static const struct platform_suspend_ops s3c_pm_ops = {
.enter = s3c_pm_enter,
.prepare = s3c_pm_prepare,
.finish = s3c_pm_finish,
.valid = suspend_valid_only_mem,
};
int suspend_valid_only_mem(suspend_state_t state)
{
return state == PM_SUSPEND_MEM;
}
只支持mem。
3.2 request_suspend_state()
on(唤醒)和mem(睡眠)。
void request_suspend_state(suspend_state_t new_state)
{
unsigned long irqflags;
int old_sleep;

spin_lock_irqsave(&state_lock, irqflags);

//static int state;全局变量
old_sleep = state & SUSPEND_REQUESTED;
if (debug_mask & DEBUG_USER_STATE) {
struct timespec ts;
struct rtc_time tm;
getnstimeofday(&ts);
rtc_time_to_tm(ts.tv_sec, &tm);
pr_info(“request_suspend_state: %s (%d->%d) at %lld "
“(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n”,
new_state != PM_SUSPEND_ON ? “sleep” : “wakeup”,
requested_suspend_state, new_st

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

android framework

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值