【Android休眠】之Android休眠機制

1、休眠概述

休眠,簡而言之就是設備在不須要工做的時候把一些部件、外設關掉(掉電或讓它進入低功耗模式)。android

爲何要休眠呢?一言以蔽之:省電。微信

休眠分主動休眠和被動休眠。主動休眠:好比我電腦不用了,就經過設置讓系統進入休眠模式;被動休眠:系統檢測到本身閒的慌,爲了節約故,本身就休眠去了。app

廢話不敘。異步

2、Android休眠

休眠是內核的核心工做,而Android是基於Linux內核的,因此Android休眠和內核有着千絲萬縷的聯繫;因爲Android的特殊應用場景:移動設備,因此Android休眠和內核又有着特別的需求。async

一、聯繫:

Android設備中止使用,系統沒有什麼事情可作,進入休眠狀態的功能最終是由內核去實現的;每一類硬件都有本身的驅動,具體的驅動決定怎麼進入休眠以及處於何種層次的休眠。好比:對於platform_device,就按照platform_driver定義的規則,在suspend調用的時候,去作上面提到的事情:ide

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;
};

二、Android的特別需求:

好比對於本身的電腦,不用讓它休眠好了;可是對於咱們如影隨行的手機,在休眠的時候還要睜一隻眼:來電了要通知你,QQ啊微信啊什麼的由信息了也要通知你,因此Android在Linux內核休眠機制之上,提出了「Opportunistic Suspend」。ui

3、休眠實踐

絮絮不休這麼多,下面讓咱們切切實實體驗下休眠。this

一、休眠模式
休眠是分好幾種模式的,不一樣模式實現方式、耗電量不一樣,如下來自Documentation/power/states.txtspa

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()方法也銷聲匿跡。

二、/sys/power/目錄下文件

image

文件簡介:

  • /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)用戶控件的進程和內核空間的容許凍結的內核線程,執行這些操做要耗時間吧?該文件指定所需時間的最大值。

4、其餘須要明瞭的問題

一、Android設備屏幕暗下來的時候,並非當即就進入了休眠模式;當全部喚醒源都處於de-avtive狀態後,系統纔會進入休眠。

二、Android設備連着adb線到其餘設備的狀況下,設備是不會進入休眠模式的。

三、有休眠操做就有喚醒,就須要喚醒源。喚醒源有不少種,在內核註冊,好比經常使用的Power按鍵。

四、曾經困惑的一個問題:系統怎麼知道本身應該進入休眠模式了?它的判斷依據是什麼?

在wakelock時代,系統休眠過程當中去檢測休眠鎖;若是系統中沒有其餘部件持有休眠鎖,就嘗試進入休眠模式,沒有異常事件發生的話就進入休眠模式。
Android從4.4開始使用autosleep機制,只要不存在任何active的喚醒源(wakeup_source)了,就進入休眠模式。

五、系統Power Manager總體流程:

相關文章
相關標籤/搜索