一、休眠概述

休眠,简而言之就是设施在不须要工作的时候把一些部件、外设关掉(掉电或让它进入低功耗模式)。
为什么要休眠呢?一言以蔽之:省电。
休眠分被动休眠和被动休眠。被动休眠:比方我电脑不必了,就通过设置让零碎进入休眠模式;被动休眠:零碎检测到本人闲的慌,为了节约故,本人就休眠去了。

二、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, thoughone is generic and the other three are dependent on platform supportcode to implement the low-level details for each state.This file describes each state, what they arecommonly called, what ACPI state they map to, and what string to writeto /sys/power/state to enter that state state:        Freeze / Low-Power IdleACPI state:    S0String:        "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 userspace and putting all I/O devices into low-power states (possiblylower-power than available at run time), such that the processors canspend more time in their idle states.This state can be used for platforms without Standby/Suspend-to-RAMsupport, or it can be used in addition to Suspend-to-RAM (memory sleep)to provide reduced resume latency.  State:        Standby / Power-On SuspendACPI State:    S1String:        "standby" This state offers minimal, though real, power savings, while providinga very low-latency transition back to a working system. No operatingstate is lost (the CPU retains power), so the system easily starts upagain where it left off.  We try to put devices in a low-power state equivalent to D1, whichalso offers low power savings, but low resume latency. Not all devicessupport D1, and those that don't are left on.   State:        Suspend-to-RAMACPI State:    S3String:        "mem" This state offers significant power savings as everything in thesystem is put into a low-power state, except for memory, which isplaced in self-refresh mode to retain its contents.  System and device state is saved and kept in memory. All devices aresuspended and put into D3. In many cases, all peripheral buses losepower when entering STR, so devices must be able to handle thetransition back to the On state.  For at least ACPI, STR requires some minimal boot-strapping code toresume the system from STR. This may be true on other platforms.   State:        Suspend-to-diskACPI State:    S4String:        "disk" This state offers the greatest power savings, and can be used even inthe absence of low-level platform support for power management. Thisstate operates similarly to Suspend-to-RAM, but includes a final stepof writing memory contents to disk. On resume, this is read and memoryis 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整体流程