Power Management
Introduction
Android supports its own Power Management (on top of the standard Linux Power Management) designed with the premise that the CPU shouldn’t consume power if no applications or services require power. For more information regarding standard Linux power management, please see Linux Power Management Support at http://kernel.org.
Android requires that applications and services request CPU resources with «wake locks» through the Android application framework and native Linux libraries. If there are no active wake locks, Android will shut down the CPU.
The image below illustrates the Android power management architecture.
Solid elements represent Android blocks and dashed elements represent partner-specific blocks.
Wake Locks
Wake locks are used by applications and services to request CPU resources.
A locked wakelock, depending on its type, prevents the system from entering suspend or other low-power states. This document describes how to employ wakelocks.
There are two settings for a wakelock:
- WAKE_LOCK_SUSPEND : prevents a full system suspend.
- WAKE_LOCK_IDLE : low-power states, which often cause large interrupt latencies or that disable a set of interrupts, will not be entered from idle until the wakelocks are released.
Unless the type is specified, this document refers to wakelocks of type WAKE_LOCK_SUSPEND .
If the suspend operation has already started when locking a wakelock, the system will abort the suspend operation as long it has not already reached the suspend_late stage. This means that locking a wakelock from an interrupt handler or a freezeable thread always works, but if you lock a wakelock from a suspend_late handler, you must also return an error from that handler to abort suspend. You can use wakelocks to allow the user-space to decide which keys should wake the full system and turn on the screen. Use set_irq_wake or a platform-specific API to ensure that the keypad interrupt wakes up the CPU. Once the keypad driver has resumed, the sequence of events can look like this:
- The Keypad driver receives an interrupt, locks the keypad-scan wakelock, and starts scanning the keypad matrix.
- The keypad-scan code detects a key change and reports it to the input-event driver.
- The input-event driver sees the key change, enqueues an event, and locks the input-event-queue wakelock.
- The keypad-scan code detects that no keys are held and unlocks the keypad-scan wakelock.
- The user-space input-event thread returns from select/poll, locks the process-input-events wakelock, and calls read in the input-event device.
- The input-event driver dequeues the key-event and, since the queue is now empty, unlocks the input-event-queue wakelock.
- The user-space input-event thread returns from read. It determines that the key should not wake up the full system, releases the process-input-events wakelock, and calls select or poll.
The simple sequence diagram below illustrates these steps:
Driver API
A driver can use the wakelock API by adding a wakelock variable to its state and calling wake_lock_init , as illustrated in the snippet below:
When the driver determines that it needs to run (usually in an interrupt handler), it calls wake_lock :
When it no longer needs to run, it calls wake_unlock :
It can also call wake_lock_timeout to release the wakelock after a delay:
This works whether or not the wakelock is already held. It is useful if the driver woke up other parts of the system that do not use wakelocks but still need to run. Avoid this when possible, since it will waste power if the timeout is long or may fail to finish needed work if the timeout is short.
User-space API
Write lockname or lockname timeout to /sys/power/wake_lock lock and, if needed, create a wakelock. The timeout here is specified in nanoseconds. Write lockname to /sys/power/wake_unlock to unlock a user wakelock.
Do not use randomly generated wakelock names as there is no API to free a user-space wakelock.
Types of Wake Locks
Wake Lock | Description |
---|---|
ACQUIRE_CAUSES_WAKEUP | Normally wake locks don’t actually wake the device, they just cause it to remain on once it’s already on. Think of the video player app as the normal behavior. Notifications that pop up and want the device to be on are the exception; use this flag to be like them. |
FULL_WAKE_LOCK | Wake lock that ensures that the screen and keyboard are on at full brightness. |
ON_AFTER_RELEASE | When this wake lock is released, poke the user activity timer so the screen stays on for a little longer. |
PARTIAL_WAKE_LOCK | Wake lock that ensures that the CPU is running. The screen might not be on. |
SCREEN_BRIGHT_WAKE_LOCK | Wake lock that ensures that the screen is on at full brightness; the keyboard backlight will be allowed to go off. |
SCREEN_DIM_WAKE_LOCK | Wake lock that ensures that the screen is on, but the keyboard backlight will be allowed to go off, and the screen backlight will be allowed to go dim. |
Exploring a Wake Lock Example
All power management calls follow the same basic format:
- Acquire handle to the PowerManager service.
- Create a wake lock and specify the power management flags for screen, timeout, etc.
- Acquire wake lock.
- Perform operation (play MP3, open HTML page, etc.).
- Release wake lock.
The snippet below illustrates this process.
PowerManager class
The Android Framework exposes power management to services and applications through the PowerManager class.
User space native libraries (any hardware function in //device/lib/hardware/ meant to serve as supporting libraries for Android runtime) should never call into Android Power Management directly (see the image above). Bypassing the power management policy in the Android runtime will destabilize the system.
All calls into Power Management should go through the Android runtime PowerManager APIs.
Registering Drivers with the PM Driver
You can register Kernel-level drivers with the Android Power Manager driver so that they’re notified immediately before power down or after power up. For example, you might set a display driver to completely power down when a request comes in to power down from the user space (see the Android MSM MDDI display driver for a sample implementation).
To register drivers with the Android PM driver, implement call-back handlers and register them with the Android PM, as illustrated in the snippet below:
It is critical in a drive to return immediately and not wait for anything to happen in the call back.
Early Suspend
The early-suspend API allows drivers to get notified when user-space writes to /sys/power/request_state to indicate that the user visible sleep state should change. Suspend handlers are called in order of low to high (4 — 1 below) and resume handlers are called in order of high to low (1 — 4 below).
- EARLY_SUSPEND_LEVEL_BLANK_SCREEN :
- on suspend: the screen should be turned off but the framebuffer must still be accessible.
- on resume: the screen can be turned back on.
- EARLY_SUSPEND_LEVEL_STOP_DRAWING :
- on suspend: this level notifies user-space that it should stop accessing the framebuffer and it waits for it to complete.
- on resume: it notifies user-space that it should resume screen access. Two methods are provided, console switch or a sysfs interface.
- EARLY_SUSPEND_LEVEL_DISABLE_FB : Turn off the framebuffer
- on suspend: turn off the framebuffer
- on resume: turn the framebuffer back on.
- EARLY_SUSPEND_LEVEL_STOP_INPUT :
- on suspend: turn off input devices that are not capable of wakeup or where wakeup is disabled.
- on resume: turn the same devices back on.
Источник
Русские Блоги
Android Power Management
в целом Android Управление питанием относительно просто , В основном через блокировку и таймер для переключения состояния системы , Минимизировать энергопотребление системы , Схема архитектуры управления питанием всей системы выглядит следующим образом : ( Обратите внимание, что картина исходит от Steve Guo)
Далее мы начнем с Java Уровень применения , Android framework Уровни , Linux Подробные обсуждения на уровне ядра :
Использование прикладного уровня :
Android Обеспечивает готовые android.os.PowerManager категория , Этот класс используется для управления переключением состояния питания устройства .
Этот класс имеет три интерфейсные функции :
void goToSleep(long time); // Принудительное устройство ввода Sleep состояние
Попробуйте вызвать эту функцию на прикладном уровне , Но не может добиться успеха , Ошибка, кажется, недостаточно прав , Но в Framework следующий Service Можно позвонить .
newWakeLock(int flags, String tag);// Получить соответствующий уровень блокировки
flags Описание параметра :
PARTIAL_WAKE_LOCK: Screen off, keyboard light off
SCREEN_DIM_WAKE_LOCK: screen dim, keyboard light off
SCREEN_BRIGHT_WAKE_LOCK: screen bright, keyboard light off
FULL_WAKE_LOCK: screen bright, keyboard bright
ACQUIRE_CAUSES_WAKEUP: Принудительно открывать после блокировки запроса Screen и keyboard light
ON_AFTER_RELEASE: При снятии блокировки reset activity timer
Если применяется partial wakelock, Тогда даже если вы нажмете Power облигация , Система не войдет Sleep, в качестве Music При игре
Если вы подали заявку на другие wakelocks, пресс Power облигация , Система все равно войдет Sleep
void userActivity(long when, boolean noChangeLights);//User activity Событие происходит , Устройство будет переключено на Full on Состояние , В то же время Reset Screen off timer.
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock (PowerManager.SCREEN_DIM_WAKE_LOCK, “My Tag”);
1. В приложениях, которые используют вышеуказанные функции , Должно быть Manifest.xml Добавьте следующие разрешения в файл :
2. Все замки должны использоваться в парах , Если заявка на участие и не была выпущена вовремя, это приведет к сбою системы . Если применяется partial wakelock, Без своевременного выпуска , Тогда система никогда не сможет войти Sleep режим .
Android Framework Уровни :
Основной файл кода выглядит следующим образом :
среди PowerManagerService.java Это ядро , Power.java Обеспечить интерфейс функции низкого уровня , и JNI Взаимодействие слоев , JNI Код слоя находится в основном в файле android_os_Power.cpp в , и Linux kernel Взаимодействие через Power.c Для достижения , Andriod с Kernel Взаимодействие в основном через sys Путь документа , Для получения подробной информации, пожалуйста, обратитесь к Kernel Введение слоя .
Функции этого слоя относительно сложны , Такие как переключение состояния системы , Регулировка подсветки и выключатель ,Wake Lock Заявка и выпуск и т. Д. , Но этот слой не имеет ничего общего с аппаратной платформой , И по Google Ответственный за обслуживание , Будет меньше проблем , Заинтересованные друзья могут просматривать связанные коды самостоятельно .
Основной код находится в следующем месте :
Это право Kernel Предоставленные функции интерфейса
EXPORT_SYMBOL(android_init_suspend_lock); // инициализация Suspend lock, Должен быть инициализирован перед использованием
EXPORT_SYMBOL(android_uninit_suspend_lock); // релиз suspend lock Связанные ресурсы
EXPORT_SYMBOL(android_lock_suspend); // приложение lock, Должен позвонить в соответствующий unlock Чтобы выпустить это
EXPORT_SYMBOL(android_lock_suspend_auto_expire);// приложение partial wakelock, Это будет автоматически выпущено после таймера
EXPORT_SYMBOL(android_unlock_suspend); // релиз lock
EXPORT_SYMBOL(android_power_wakeup); // Разбудить систему, чтобы on
EXPORT_SYMBOL(android_register_early_suspend); // Зарегистрироваться early suspend Вождение
EXPORT_SYMBOL(android_unregister_early_suspend); // Отменить уже зарегистрирован early suspend Вождение
Обеспечить Android Framework Слои proc Файл выглядит следующим образом :
«/sys/android_power/acquire_partial_wake_lock» // приложение partial wake lock
«/sys/android_power/acquire_full_wake_lock» // приложение full wake lock
«/sys/android_power/release_wake_lock» // Отпустить соответствующий wake lock
«/sys/android_power/request_state» // Запрос на изменение состояния системы , вводить standby И обратно wakeup Два состояния
«/sys/android_power/state» // Указывает текущее состояние системы
Android Из управления питанием в основном через Wake lock Для достижения , На самом низком уровне управление достигается через следующие три очереди :
Все инициализировано lock Будет вставлен в g_inactive_locks В очереди , И в настоящее время активный partial wake lock Будет вставлен в g_active_partial_wake_locks В очереди , деятельность full wake lock Был вставлен в g_active_full_wake_locks В очереди , любой partial wake lock и full wake lock После истечения срока или unlock Будет перемещен в inactive очередь , В ожидании следующего звонка .
в Kernel Использование слоя wake lock Шаги следующие :
1. Функция вызова android_init_suspend_lock Инициализировать один wake lock
2. Приложение, связанное с вызовом lock Функция android_lock_suspend или android_lock_suspend_auto_expire запрос lock, Вы можете подать заявку только здесь partial wake lock, Если вы хотите подать заявку Full wake lock, Вам нужно вызвать функцию android_lock_partial_suspend_auto_expire( Функция не EXPORT Выходи ), Это название немного странно , Не следуй за фронтом android_lock_suspend_auto_expire Confused .
3. Если да auto expire из wake lock Вы можете игнорировать , В противном случае, связанные wake lock Освобожденный , В противном случае это приведет к длительной работе системы в состоянии высокого энергопотребления. .
4. Удалить или больше не использовать драйвер Wake lock Не забудьте позвонить вовремя android_uninit_suspend_lock Освободите ресурсы .
USER_AWAKE, //Full on status
USER_NOTIFICATION, //Early suspended driver but CPU keep on
USER_SLEEP // CPU enter sleep mode
Принципиальная схема его состояния переключения выглядит следующим образом :
После нормального запуска системы введите AWAKE состояние , Backlight Будет медленно настраиваться от ярчайшего до яркости, установленной пользователем , система screen off timer(settings->sound & display-> Display settings -> Screen timeout) Время начала , До истечения таймера , Если есть activity Событие происходит , в качестве Touch click, keyboard pressed Ждать событий , воли Reset screen off timer, Система остается в AWAKE состояние . Если заявка подается в течение этого времени Full wake lock, Тогда система также останется на AWAKE состояние , Если пользователь не нажимает power key. в AWAKE Если заряд батареи низкий или используется AC Блок питания screen off timer Время истекло и выбрано Keep screen on while pluged in опции ,backlight Будет вынужден DIM Состояние .
если Screen off timer Время истекло, а не Full wake lock Или пользователь нажал power key, Тогда состояние системы будет переключено на NOTIFICATION, И позвоните всем зарегистрированным g_early_suspend_handlers функция , Обычно ставят LCD и Backlight Регистрация водителя early suspend тип , При необходимости вы можете зарегистрировать другие драйверы как early suspend, Это будет закрыто на первом этапе . Далее система определит, есть ли partial wake lock acquired, Если есть, дождитесь его выпуска , Если есть user activity Событие происходит , Система немедленно возвращается AWAKE состояние ; Если нет partial wake lock acquired, Система немедленно вызовет функцию pm_suspend Закройте другие связанные драйверы , Сделать CPU Иди спать .
Система в Sleep Если какой-либо из них обнаружен во время статуса Wakeup source, тогда CPU Это будет от Sleep Государство пробуждено , И позвоните соответствующему водителю resume функция , Тогда сразу звоните предварительно зарегистрированным early suspend управляемый resume функция , Наконец, статус системы возвращается AWAKE состояние . Проблема здесь в том, что все зарегистрированные early suspend Функция S Suspend Первый этап называется понятным , Но в resume время , Linux Сначала позвоню всем водителям resume функция , А затем позвоните предварительно зарегистрированным early suspend управляемый resume Что означает функция ? Лично чувствую android Из этого early suspend и late resume Функции должны быть объединены Linux следующий suspend и resume Использовать вместе , Вместо использования единой очереди для управления .
Поскольку я долгое время не изучал Android, возможно, некоторые из них не правильно поняты или даже неправильно, пожалуйста, поймите. Если вы обнаружите какие-либо вопросы, вы также можете обсудить их, если вам интересно.
Источник