Power Management Wakelock Usage Guide
[ English | 简体中文 ]
This document provides a detailed guide for openvela developers on the Wakelock mechanism in Power Management (PM). Unlike the reactive approach of using prepare callbacks at the driver level, a Wakelock allows the application layer or middleware to proactively request that the system remain at a specified power level when it anticipates the need for system activity, thereby preventing unnecessary sleep states.
Prerequisite Reading: Before you begin, we highly recommend reading the Power Management Framework Guide to fully understand the core concepts of the PM framework.
I. Core Concepts and Use Cases
In embedded development, certain tasks—such as file writes, network data transfers, or firmware updates—require preventing the system from entering a low-power state for a period to ensure task integrity and real-time performance.
The traditional method is to implement a prepare callback in a device driver to veto a sleep request. However, this approach has two main problems:
- Performance Overhead: The
preparecallback is invoked every time the system attempts to enter a low-power state, even during non-critical tasks. This increases the interrupt-disabled time in the Idle Loop and adds to the overall system overhead. - High Sleep Failure Rate: This is a post-facto check. The PM framework has already decided to sleep before it asks drivers for their consent. If a driver vetoes the transition, it results in a failed power state change attempt and a state rollback, which harms the efficiency of power management.
The Wakelock mechanism solves these issues through a proactive request model. When a task begins, it acquires a Wakelock; when the task ends, it releases the Wakelock. The PM framework will only attempt to transition the system into a deeper sleep state when no active Wakelocks exist.
In short: Prioritize using a Wakelock whenever you can predict the need to prevent system sleep at the business logic level.
II. API Reference
Wakelock functionality is provided through a series of pm_wakelock_* interfaces in pm.h.
pm_wakelock_init
Initializes a Wakelock instance.
void pm_wakelock_init(FAR struct pm_wakelock_s *wakelock,
FAR const char *name, int domain,
enum pm_state_e state)
-
Use Case: Call this function during the initialization phase of a module or driver to create a named
Wakelock. -
Parameters:
wakelock: A pointer to an instance of a user-definedpm_wakelock_sstructure.name: The name string for the lock. This name is used for identification and debugging in Procfs.domain: The target Power Domain for thisWakelock.state: The minimum power state the system can enter while thisWakelockis held. For example, if set toPM_IDLE, holding this lock will prevent the system from enteringPM_STANDBYorPM_SLEEP.
pm_wakelock_stay
Acquires the specified Wakelock.
void pm_wakelock_stay(FAR struct pm_wakelock_s *wakelock)
- Use Case: Call this function before a critical operation begins to notify the PM framework that the system needs to remain active.
- Description: This function internally maintains a reference count. You can call
pm_wakelock_staymultiple times, but a corresponding number ofpm_wakelock_relaxcalls are required to fully release the lock.
pm_wakelock_relax
Releases the specified Wakelock.
void pm_wakelock_relax(FAR struct pm_wakelock_s *wakelock)
- Use Case: Call this function after a critical operation is complete to inform the PM framework that the system may enter sleep states normally.
- Description: This function decrements the
Wakelock's reference count. TheWakelockis only fully released when its reference count reaches zero. It must be used in matching pairs withpm_wakelock_stay.
pm_wakelock_staytimeout
Acquires a Wakelock with an automatic timeout release.
void pm_wakelock_staytimeout(FAR struct pm_wakelock_s *wakelock, int ms);
- Use Case: Suitable for operations that need to keep the system active for a fixed duration.
- Description: After calling this function, the
Wakelockwill be held formsmilliseconds and then automatically released. If this function is called again before the timeout expires, the timer will be reset.
pm_wakelock_staycount
Gets the current reference count of a Wakelock.
int pm_wakelock_staycount(FAR struct pm_wakelock_s *wakelock);
- Use Case: Primarily for debugging. You can check the current hold count of a lock before calling
pm_wakelock_relaxto prevent asymmetrical release operations.
III. Key Advantages
Adopting the Wakelock mechanism provides the following significant benefits for your system:
1. Reduced System Overhead
By using proactive locking, the system avoids iterating through and calling the prepare callbacks of all drivers during every idle cycle. This effectively reduces the interrupt-disabled time and improves system responsiveness.
2. Improved Power Management Efficiency
The status of Wakelocks is checked early in the PM framework's decision-making process. This significantly reduces power state rollbacks caused by driver vetoes during the prepare phase, leading to smoother and more efficient power state transitions.
3. Enhanced Debuggability
If Procfs (CONFIG_FS_PROCFS) is enabled, you can view the real-time status of all Wakelocks in the system by accessing the /proc/pm/wakelock filesystem node. This includes their names, hold counts, and cumulative active time, greatly simplifying the debugging of power consumption issues.
For more details, see PM procfs usage.