Android电源管理-休眠简要分析
一、开篇
1.Linux 描述的电源状态
- 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 content is saved to Disk and power down
S3 aka STR(suspend to ram),挂起到内存,简称待机。计算机将目前的运行状态等数据存放在内存,关闭硬 盘、外设等设备,进入等待状态。此时内存仍然需要电力维持其数据,但整机耗电很少。恢复时计算机从内存读出数据,回到挂起前的状态,恢复速度较快。对 DDR的耗电情况进行优化是S3性能的关键,大多数手持设备都是用S3待机。
S4 aka STD(suspend to disk),挂起到硬盘,简称休眠。把运行状态等数据存放在硬盘上某个文件或者某个特定的区域,关闭硬盘、外设等设备,进入关机状态。此时计算机完全关闭,不耗电。恢复时计算机从休眠文件/分区中读出数据,回到休眠前的状态,恢复速度较慢。电子书项目中,见过一款索尼的电子书,没有定义关机状态,只定义了S4,从而提高开机速度。
以上摘录自:http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763104
6893b4c4380147d8c8c4668d4e419ce3b4c413037bfa6663f405a8e906b6075fc
4d5bedfb6079370123b598938f4a85ac925f75ce786a6459db0144dc5bf0dc475
5d627e44de8df4aa0fcad7384afa28d880311dd52756d87849c5b704f9634b6&p
=c933cc16d9c116f51ebd9b7d0a13cd&newp=8366c54ad5c444e411b3c22d0214cf2
31610db2151d6db10349dcd1e&user=baidu&fm=sc&query=pm_autosleep_init&qid=&p1=1
在阅读下面的内容之前,强烈建议阅读下。
Android在Linux内核原有的睡眠唤醒机制上面新增了三个,如下:
• Wake Lock 唤醒锁机制;
• Early Suspend 预挂起机制;
• Late Resume 迟唤醒机制;
我们来看一张Android睡眠唤醒机制的框架图:
• Android特有的earlysuspend: request_suspend_state(state)
• Linux标准的suspend: enter_state(state)
二、相关代码涉及文件
• Frameworks
// 供给上层应用程序调用的接口
frameworks/base/core/java/android/os/PowerManager.java
// 具体实现PowerManager类中的接口
frameworks/base/services/java/com/android/server/PowerManagerService.java
// 被PowerManagerService类调用
frameworks/base/core/java/android/os/ Power.java
• JNI
// 实现Power类中的JNI接口
frameworks/base/core/jni/android_os_Power.cpp
• HAL
// 进行sysfs用户接口的操作
hardware/libhardware_legacy/power/power.c
• Kernel
kernel/kernel/power/main.c
kernel/kernel/power/earlysuspend.c
kernel/kernel/power/suspend.c
kernel/kernel/power/wakelock.c
kernel/kernel/power/userwakelock.c
在应用程序框架层中,PowerManager类是面向上层应用程序的接口类,提供了Wake Lock机制(同时也是睡眠唤醒子系统)的基本接口(唤醒锁的获取和释放)。上层应用程序通过调用这些接口,实现对系统电源状态的监控。
• PowerManager类通过IBinder这种Android中特有的通信模式,与PowerManagerService 类进行通信。
• PowerManagerService 是PowerManager 类中定义的接口的具体实现,并进一步调用Power 类来与下一层进行通信。PowerManagerService 类是WakeLock 机制在应用程序框架层的核心,他们对应用程调用PowerManager类接口时所传递的参数进行初步的分析和对应的设置,并管理一个唤醒锁队列,然后配合其他模块(例如WatchDog、BatteryService、ShutdownThread 等)的状态信息,做出决策,调用Power类的对应接口,最终通过JNI 接口,调用到硬件抽象层中的函数,对sysfs 的用户接口进行操作,从而触发内核态实现的功能。
三、Kernel用户空间接口分析
1. sysfs的属性文件
电源管理内核层给应用层提供的接口就是sysfs 文件系统,所有的相关接口都通过sysfs实现。Android上层frameworks也是基于sysfs做了包装,最终提供给Android java应用程序的是java类的形式。
Android系统会在sysfs里面创建以entry:
/sys/power/state
/sys/power/wake_lock
/sys/power/wake_unlock
echo mem > /sys/power/state或echo standby > /sys/power/state: 命令系统进入earlysuspend状态,那些注册了early suspend handler的驱动将依次进入各自的earlysuspend 状态。
echo on > /sys/power/state: 将退出early suspend状态
echo disk > /sys/power/state: 命令系统进入hibernation状态
echo lockname > /sys/power/wake_lock: 加锁“lockname”
echo lockname > /sys/power/wake_unlock: 解锁“lockname”
上述是分别加锁和解锁的命令,一旦系统中所有wakelock被解锁,系统就会进入suspend状态,可见Linux中原本使系统 suspend 的操作(echo mem > /sys/power/state 等)在Android被替换成使系统进入early suspend;而wake lock 机制成为用户命令系统进入suspend状态的唯一途径。
Kernel与HAL接口是通过/sys/power下面的一系统文件来实现的,如:/sys/power/state.在用户空间接口中,定义了一组sysfs的属性文件,其中一个定义是:
1 power_attr(state)
这个宏的代码如下:
1 #define power_attr(_name) \
2 static struct kobj_attribute _name##_attr = { \
3 .attr = { \
4 .name = __stringify(_name), \
5 .mode = 0644, \
6 }, \
7 .show = _name##_show, \
8 .store = _name##_store,
展开后的代码是:
1 #define power_attr(state) \
2 static struct kobj_attribute state_attr = { \
3 .attr = { \
4 .name = "state", \
5 .mode = 0644, \
6 }, \
7 .show = state_show, \
8 .store = state_store,
2. 创建sysfs文件
1 static int __init pm_init(void)
2 {
3 int error = pm_start_workqueue();
4 if (error)
5 return error;
6 hibernate_image_size_init();
7 hibernate_reserved_size_init();
8 power_kobj = kobject_create_and_add("power", NULL);
9 if (!power_kobj)
10 return -ENOMEM;
11 error = sysfs_create_group(power_kobj, &attr_group); //创建sys文件接口
12 if (error)
13 return error;
14 pm_print_times_init();
15 return pm_autosleep_init(); //创建auto_sleep工作队列,也把用户态向autosleep 写入当作wakeup_source
16 }
17
18 core_initcall(pm_init) //调用pm_init
pm_init函数执行后,会创建/sys/power目录,且目录下会建立一系列属性文件,其中一个是/sys/power/state文件。用户空间写该文件将会导致state_store被调用,读该文件将会导致state_show函数被调用。
2. 标准的Linux内核调用suspend流程
1 static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
2 const char *buf, size_t n)
3 {
4 suspend_state_t state;
5 int error;
6
7 error = pm_autosleep_lock();
8 if (error)
9 return error;
10
11 if (pm_autosleep_state() > PM_SUSPEND_ON) { // autosleep是android内核为了跟主线内核兼容所引入的
12 error = -EBUSY;
13 goto out;
14 }
15
16 state = decode_state(buf, n);
17 if (state < PM_SUSPEND_MAX)
18 error = pm_suspend(state); // 进入suspend 的模式
19 else if (state == PM_SUSPEND_MAX)
20 error = hibernate(); // 进入冬眠模式
21 else
22 error = -EINVAL;
23
24 out:
25 pm_autosleep_unlock();
26 return error ? error : n;
当底层接受到上层传递到的值进行一些列的操作,有很多的state 状态:
1 #define PM_SUSPEND_ON ((__force suspend_state_t) 0) // S0
2 #define PM_SUSPEND_STANDBY ((__force suspend_state_t) 1) // S1
3 #define PM_SUSPEND_MEM ((__force suspend_state_t) 3) // S2
4 #define PM_SUSPEND_MAX ((__force suspend_state_t) 4) // S3
在state_store中,若定义了CONFIG_EARLYSUSPEND,则执行 request_suspend_state(state)以先进入earlysuspend,然后根据wake_lock的状态决定是否进入 suspend;否则直接执行enter_state(state)以进入suspend状态。我们来看下pm_suspend的原生代码:
1 int pm_suspend(suspend_state_t state)
2 {
3 int error;
4
5 if (state <= PM_SUSPEND_ON || state >= PM_SUSPEND_MAX) // state参数无效
6 return -EINVAL;
7
8 pm_suspend_marker("entry");
9 error = enter_state(state);
10 if (error) {
11 suspend_stats.fail++;
12 dpm_save_failed_errno(error);
13 } else {
14 suspend_stats.success++;
15 }
16 pm_suspend_marker("exit");
17 return error;
三、Android 休眠(suspend)
1. 相关文件
• kernel/kernel/power/main.c
• kernel/kernel/power/earlysuspend.c
• kernel/kernel/power/wakelock.c
2. 特性介绍
1) Early Suspend
Early suspend 是android 引进的一种机制,这种机制在上游备受争议,这里不做评论。 这个机制作用是在关闭显示的时候,一些和显示有关的设备,比如LCD背光、重力感应器、 触摸屏都会关掉,但是系统可能还是在运行状态(这时候还有wake lock)进行任务的处理,例如在扫描 SD卡上的文件等。 在嵌入式设备中,背光是一个很大的电源消耗,所以android会加入这样一种机制。
2) Late Resume
Late Resume 是和suspend 配套的一种机制,是在内核唤醒完毕开始执行的。主要就是唤醒在Early Suspend时休眠的设备。
3) Wake Lock
wake_lock 在Android的电源管理系统中扮演一个核心的角色。wake_lock是一种锁的机制,只要有人拿着这个锁,系统就无法进入休眠,可以被用户态程序和 内核获得。这个锁可以是有超时的或者是没有超时的,超时的锁会在超时以后自动解锁。如果没有锁了或者超时了,内核就会启动休眠的那套机制来进入休眠。
3. Android Suspend
main.c文件是整个框架的入口。用户可以通过读写sys文件/sys/power/state实现控制系统进入低功耗状态。用户对于/sys /power/state的读写会调用到main.c中的state_store(),用户可以写入const char * const pm_states[] 中定义的字符串, 比如“on”,“mem”,“standby”,“disk”。
1 const char *const pm_states[PM_SUSPEND_MAX] = {
2 [PM_SUSPEND_FREEZE] = "freeze",
3 [PM_SUSPEND_STANDBY] = "standby",
4 [PM_SUSPEND_MEM] = "mem",
5 }
state_store()首先判断用户写入的是否是“disk”字符串,如果是则调用hibernate()函数命令系统进入hibernation状 态。如果是其他字符串则调用request_suspend_state()(如果定义 CONFIG_EARLYSUSPEND)或者调用enter_state()(如果未定义CONFIG_EARLYSUSPEND)。 request_suspend_state()函数是android相对标准linux改动的地方,它实现在earlysuspend.c中。在标准 linux内核中,用户通过 sysfs 写入“mem”和“standby”时,会直接调用enter_state()进入suspend模式,但在android中则会调用request_suspend_state()函数进入early suspend状态。request_suspend_state()函数代码如下:
TAG:
1 const char * const OLD_PATHS[] = {
2 "/sys/android_power/acquire_partial_wake_lock",
3 "/sys/android_power/release_wake_lock",
4 };
5
6 const char * const NEW_PATHS[] = {
7 "/sys/power/wake_lock",
8 "/sys/power/wake_unlock",
9 };
1 static inline void
2 initialize_fds(void)
3 {
4 // XXX: should be this:
5 //pthread_once(&g_initialized, open_file_descriptors);
6 // XXX: not this:
7 if (g_initialized == 0) {
8 if(open_file_descriptors(NEW_PATHS) < 0)
9 open_file_descriptors(OLD_PATHS);
10 g_initialized = 1;
11 }
未完待续......
本文很多内容参考且摘录自:
http://blog.csdn.net/myarrow/article/details/8136691
http://blog.csdn.net/myarrow/article/details/8137952
http://blog.csdn.net/myarrow/article/details/8137566
http://blog.csdn.net/sunweizhong1024/article/details/17102047
Android电源管理-休眠简要分析的更多相关文章
- Android电源管理基础知识整理
前言 待机.睡眠与休眠的区别? Android开发者官网当中提到"idle states",该如何理解,这个状态会对设备及我们的程序造成何种影响? 进入Doze模式中的idle状态 ...
- Android初级教程通过简要分析“土司”源码,来自实现定义土司理论探讨
由于系统自带的土司瞬间即逝,而且非常难看.因此我们就希望自定义自己的土司风格.有些实例就是基于自定义土司完成的,例如金山卫士的火箭发射,基本原理就是个土司.但是在做出自己的土司风格之前,还是要简要分析 ...
- Android 电源管理 -- wakelock机制
转载地址:http://blog.csdn.net/wh_19910525/article/details/8287202 Wake Lock是一种锁的机制, 只要有人拿着这个锁,系统就无法进入休眠, ...
- 1.Linux电源管理-休眠与唤醒
1.休眠方式 在内核中,休眠方式有很多种,可以通过下面命令查看 # cat /sys/power/state //来得到内核支持哪几种休眠方式. 常用的休眠方式有freeze,standby, mem ...
- 1.Linux电源管理-休眠与唤醒【转】
转自:https://www.cnblogs.com/lifexy/p/9629699.html 1.休眠方式 在内核中,休眠方式有很多种,可以通过下面命令查看 # cat /sys/power/st ...
- linux驱动程序之电源管理之标准linux休眠与唤醒机制分析(一)
1. Based on linux2.6.32, only for mem(SDR) 2. 有兴趣请先参考阅读: 电源管理方案APM和ACPI比较.doc Linux系统的休眠与唤醒简介.doc 3 ...
- Android线程管理(三)——Thread类的内部原理、休眠及唤醒
线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用. ...
- Android线程管理(三)——Thread类的内部原理、休眠及唤醒
线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用. ...
- [专业名词·硬件] 2、DC\DC、LDO电源稳压基本常识(包含基本原理、高效率模块设计、常见问题、基于nRF51822电源管理模块分析等)·长文
综述先看这里 第一节的1.1简单介绍了DC/DC是什么: 第二节是关于DC/DC的常见的疑问答疑,非常实用: 第三节是针对nRF51822这款芯片电源管理部分的DC/DC.LDO.1.8的详细分析,对 ...
随机推荐
- matrix_last_acm_3
the first CCPC password 123 A http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97380#problem/ ...
- ios 缓存相关信息收集
链接:http://www.cnblogs.com/pengyingh/category/353093.html 使用NSURLCache让本地数据来代替远程UIWebView请求 摘要: 原文作者: ...
- Swift-3-字符串和字符
// Playground - noun: a place where people can play import UIKit var someString = "some string ...
- Centos编译安装PHP 5.5笔记
本篇是在 Centos 6.4 32bit 下编译安装 php 5.5.5 的笔记,接上篇 Centos编译安装Apache 2.4.6笔记.php 5.5.x 和 centos 源里面的 php 5 ...
- [工作积累] Android: Hide Navigation bar 隐藏导航条
https://developer.android.com/training/system-ui/navigation.html View decorView = getWindow().getDec ...
- 也可以使用如下命令更改您的默认 Shell
也可以使用如下命令更改您的默认 Shell chsh -s /bin/zsh (需要输入您的密码)
- 《深入浅出JavaScript》
第一章JS入门 第二章数据和判定常用的转义序列\b 回退 \f换页 \n换行 \r回车 \t制表符 \'单引 \"双引 \\反斜乘除求余的优先级相同,从左向右执行string对象indexO ...
- Javascript的怪癖
1.匿名函数在不闭包的情况下this对象为window,而在双匿名闭包的情况下内部匿名函数的this对象为window. 2.在函数中定义变量,在函数外部想使用该变量,如果变量声明时有var,则访问不 ...
- HTML5程序设计--SVG
SVG(Scalable Vector Graphics):可缩放矢量图形,一种二维图形表示语言. 借助SVG,我们可以实现很多同Canvas API类型的绘制操作,但在Canvas元素上绘制文本的时 ...
- iOS视频录制裁剪合成
网址链接: 视频裁剪合并:http://blog.sina.com.cn/s/blog_64ea868501018jx3.html 视频之定义裁剪高宽度:http://www.cocoachina.c ...