一、休眠概述
休眠,简而言之就是设备在不需要工作的时候把一些部件、外设关掉(掉电或让它进入低功耗模式)。
为什么要休眠呢?一言以蔽之:省电。
休眠分主动休眠和被动休眠。主动休眠:比如我电脑不用了,就通过设置让系统进入休眠模式;被动休眠:系统检测到自己闲的慌,为了节约故,自己就休眠去了。
废话不叙。
二、Android休眠
休眠是内核的核心工作,而Android是基于Linux内核的,所以Android休眠和内核有着千丝万缕的联系;由于Android的特殊应用场景:移动设备,所以Android休眠和内核又有着特别的需求。
1、联系:
Android设备停止使用,系统没有什么事情可做,进入休眠状态的功能最终是由内核去实现的;每一类硬件都有自己的驱动,具体的驱动决定怎么进入休眠以及处于何种层次的休眠。比如:对于platform_device,就按照platform_driver定义的规则,在suspend调用的时候,去做上面提到的事情:
-
struct platform_driver { -
int (*probe)(struct platform_device *); -
int (*remove)(struct platform_device *); -
void (*shutdown)(struct platform_device *); -
int (*suspend)(struct platform_device *, pm_message_t state); -
int (*resume)(struct platform_device *); -
struct device_driver driver; -
const struct platform_device_id *id_table; -
};
2、Android的特别需求:
比如对于自己的电脑,不用让它休眠好了;但是对于我们形影不离的手机,在休眠的时候还要睁一只眼:来电了要通知你,QQ啊微信啊什么的由信息了也要通知你,所以Android在Linux内核休眠机制之上,提出了“Opportunistic Suspend”。
三、休眠实践
絮絮叨叨这么多,下面让我们切切实实体验下休眠。
1、休眠模式
休眠是分好几种模式的,不同模式实现方式、耗电量不同,以下来自Documentation/power/states.txt:
-
The kernel supports four power management states generically, though -
one is generic and the other three are dependent on platform support -
code to implement the low-level details for each state. -
This file describes each state, what they are -
commonly called, what ACPI state they map to, and what string to write -
to /sys/power/state to enter that state -
state: Freeze / Low-Power Idle -
ACPI state: S0 -
String: "freeze" -
This state is a generic, pure software, light-weight, low-power state. -
It allows more energy to be saved relative to idle by freezing user -
space and putting all I/O devices into low-power states (possibly -
lower-power than available at run time), such that the processors can -
spend more time in their idle states. -
This state can be used for platforms without Standby/Suspend-to-RAM -
support, or it can be used in addition to Suspend-to-RAM (memory sleep) -
to provide reduced resume latency. -
State: Standby / Power-On Suspend -
ACPI State: S1 -
String: "standby" -
This state offers minimal, though real, power savings, while providing -
a very low-latency transition back to a working system. No operating -
state is lost (the CPU retains power), so the system easily starts up -
again where it left off. -
We try to put devices in a low-power state equivalent to D1, which -
also offers low power savings, but low resume latency. Not all devices -
support D1, and those that don't are left on. -
State: Suspend-to-RAM -
ACPI State: S3 -
String: "mem" -
This state offers significant power savings as everything in the -
system is put into a low-power state, except for memory, which is -
placed in self-refresh mode to retain its contents. -
System and device state is saved and kept in memory. All devices are -
suspended and put into D3. In many cases, all peripheral buses lose -
power when entering STR, so devices must be able to handle the -
transition back to the On state. -
For at least ACPI, STR requires some minimal boot-strapping code to -
resume the system from STR. This may be true on other platforms. -
State: Suspend-to-disk -
ACPI State: S4 -
String: "disk" -
This state offers the greatest power savings, and can be used even in -
the absence of low-level platform support for power management. This -
state operates similarly to Suspend-to-RAM, but includes a final step -
of writing memory contents to disk. On resume, this is read and memory -
is restored to its pre-suspend state.
虽说kernel支持上述四种休眠模式,但具体哪几种可用取决于你的硬件。那么怎么知道自己的Android设备支持的休眠模式呢?
答案:通过/sys/文件系统。查询支持的休眠模式可以cat文件/sys/power/state:
-
cat /sys/power/state -
freeze mem
如果我们往/sys/power/state文件echo上面的某一种模式的字符串,系统就会进入相应的休眠模式:
echo "mem" > /sys/power/state
如果你搜索过Android休眠相关的内容,在老版本的Android(4.4版本之前)会见有提到PowerManager的setPowerState()方法,该方法即是通过以上方式使系统进入休眠。但自从引入Autosleep后,就不在这么做了,setPowerState()方法也销声匿迹。
2、/sys/power/目录下文件

文件简介:
- /sys/power/state:用来控制系统的Power状态。读取该文件可以获取系统支持的休眠模式,写入该文件休眠模式的一种,系统进入到指定的休眠模式。如上所示例。
- /sys/power/autosleep:从Android wakelocks补丁集中演化而来,用于取代Android wakelocks中的自动休眠功能。向该文件写入/sys/power/state返回值的某一种,系统会在适当的时候进入指定的休眠的模式;读取该文件返回之前写入的数值。
- /sys/power/wake_lock、/sys/power/wake_unlock:即我们常说的休眠锁,如果应用持有休眠锁,系统将无法进入休眠模式。在Android wakelocks时代,写wake_lock获取锁,写wake_unlock释放锁;在AutoSleep时代,具体参见【Android休眠】之AutoSleep
- wakeup_count:用于解决“system suspend和system wakeup events之间的同步问题”。
- /sys/power/pm_async:状态切换开关,允许/禁止User空间对设备进行异步的suspend和resume操作。
- /sys/power/pm_freeze_timeout:系统在执行休眠动作的时候要冻结(freeze)用户控件的进程和内核空间的允许冻结的内核线程,执行这些操作要耗时间吧?该文件指定所需时间的最大值。
四、其他需要明了的问题
1、Android设备屏幕暗下来的时候,并不是立即就进入了休眠模式;当所有唤醒源都处于de-avtive状态后,系统才会进入休眠。
2、Android设备连着adb线到其他设备的情况下,设备是不会进入休眠模式的。
3、有休眠操作就有唤醒,就需要唤醒源。唤醒源有很多种,在内核注册,比如常用的Power按键。
4、曾经困惑的一个问题:系统怎么知道自己应该进入休眠模式了?它的判断依据是什么?
- 在wakelock时代,系统休眠过程中去检测休眠锁;如果系统中没有其他部件持有休眠锁,就尝试进入休眠模式,没有异常事件发生的话就进入休眠模式。
- Android从4.4开始使用autosleep机制,只要不存在任何active的唤醒源(wakeup_source)了,就进入休眠模式。
5、系统Power Manager整体流程:

转载地址:https://blog.csdn.net/u013686019/article/details/53645646
本文深入探讨了Android设备的休眠机制,包括休眠的概念、主动与被动休眠的区别、内核与Android休眠的关系,以及Android特有的Opportunistic Suspend机制。详细介绍了四种休眠模式:Freeze/Low-Power Idle、Standby/Power-On Suspend、Suspend-to-RAM、Suspend-to-Disk,以及如何通过/sys/power/state文件控制休眠模式。
1938

被折叠的 条评论
为什么被折叠?



