This topic summarizes how to manage device power. Information is provided on the Legato power management framework implementation with guidelines how to write power-efficient Legato apps.
See Power Management for general info on managing device power.
Legato uses Linux power management techniques to minimize device power consumption:
While CPUIDLE and CPUFREQ seamlessly run in the O/S background, Legato apps have significant impact on the efficiency of system SUSPEND functionality.
Legato uses Linux wakeup sources (called wake locks in Android) to control the system power state. If a component with appropriate privileges wants to prevent the system from entering SUSPEND state, it acquires a wakeup source.
If a component with appropriate privileges has no interest in keeping the system powered, it releases a wakeup source. Linux auto-sleep component monitors the use of all system-wide wakeup sources and triggers entry into SUSPEND state when none of the wakeup sources are held.
Wakeup sources can roughly be classified as:
/sys/power/wake_lock
to create and acquire wakeup source, and write the same name to file /sys/power/wake_unlock
to release the wakeup source.The Legato Power Manager is the only Legato component with the privilege to write to /sys/power/wake_lock
and /sys/power/wake_unlock
files. Other components that need control over system power state must have the Linux CAP_BLOCK_SUSPEND capability assigned, and perform the following Legato calls to request service from the Power Manager:
le_pm_NewWakeupSource() create a wakeup source with a particular tag,
le_pm_StayAwake() acquire a wakeup source, and
le_pm_Relax() release a wakeup source.
When the Power Manager receives a request from another component via le_pm_NewWakeupSource(), it'll prefix the requested tag with string legato_
and post-fix it with the requestor’s process ID resulting in the wakeup source name format
legato_<tag>_<process-id>
This name format allows for easy traceability of wakeup sources. The process ID refers to a particular Legato app and the tag refers to a particular wakeup source within that app.
A wakeup source using this name is then created on behalf of the requesting component and a reference to the wakeup source is passed back to the requestor to use it in le_pm_StayAwake() and le_pm_Relax() calls.
Stale wakeup sources are automatically released by the Power Manager when their requestor exits and/or disconnects from the Power Manager.
Legato apps run in an event-driven model so the app remains idle until there's an event to be processed. Once an event occurs, Legato detects it and dispatches it to one of its threads for processing.
From a power management aspect, there's no reason for the system to stay powered while it's idle. Also, events may not have the same processing importance, so Legato classifies them like this:
These event types are defined in the fdMonitor
object. To classify the fdMonitor event as wakeup or deferrable, the app should call le_fdMonitor_SetDeferrable() with the appropriate ‘isDeferrable’ flag. By default, if le_fdMonitor_SetDeferrable() is not called; all events on that object will be assumed to be wakeup events.
The underlying Linux mechanism of waiting for wakeup events from fdMonitor’s
file descriptor uses epoll_wait() in conjunction with EPOLLWAKEUP
flag. When an epoll_wait() event occurs on a file descriptor that has this flag is set, epoll_wait() will unblock the caller and an eventpoll kernel wakeup source will be signaled. This causes the system to stay awake until one of these conditions are met:
or
This way, callbacks for this fdMonitor
event will be executed while eventpoll wakeup source is held. This guarantees the system stays awake until all callbacks are executed. If a Legato component needs to keep the system powered beyond the scope of a Legato callback, it should acquire its own wakeup source.
This diagram shows a simple Legato app with process ID 25 that needs to keep the system powered between two Legato events using wakeup source tagged lock. Wakeup sources are handed off to achieve this functionality. The system remains powered from the moment the first event occurs until the second event is fully processed.
App components that subscribe to wakeup events must have CAP_BLOCK_SUSPEND Linux capability assigned. If not, all events will be assumed deferrable and calling le_fdMonitor_SetDeferrable() will have no effect.
Using wakeup sources and EPOLLWAKEUP provides a simple programming model to write Power Manager clients. Here are some guidelines:
System doesn't suspend.
Probable cause
A wakeup source is being held
Test
Dump contents of /sys/kernel/debug/wakeup_sources to find the fields that have a non-zero active_since field. Also dump contents of /sys/power/wake_lock
to find active user-space wakeup sources.
Command
cat /sys/kernel/debug/wakeup_sources |sed -e s/"^ "/"unnamed"/ | awk '{print $6 "\t" $1}' | grep -v "^0" |sort –n cat /sys/power/wake_lock
System perpetually suspends and resumes.
Probable cause
Interrupt is constantly triggered.
Test
Dump contents of /proc/interrupts
to find the IRQ that's constantly incrementing.
Command
cat
/proc/interrupts
System doesn't resume.
Probable cause
Wakeup interrupts aren't configured.
Test
Dump contents of all
/sys/devices/*/power/wakeup
files and check which devices have wakeup interrupts enabled.
Command
find /sys/devices –name wakeup –exec cat “{}” “;” -print
Copyright (C) Sierra Wireless Inc. Use of this work is subject to license.