Power Management
Last updated
Last updated
Assoc. Prof. Wiroon Sriborrirux, Founder of Advance Innovation Center (AIC) and Bangsaen Design House (BDH), Electrical Engineering Department, Faculty of Engineering, Burapha University
The purpose of low-power management in embedded systems is to reduce system energy consumption as much as possible to extend device standby time while meeting user performance requirements. The contradiction between high performance and limited battery energy is most prominent in embedded systems, and the combined application of hardware low-power design and software low-power management has become an effective means to resolve the contradiction. Various MCUs now provide management interfaces in terms of low power consumption to a greater or lesser extent. For example, the adjustment of the main control clock frequency, the change of the operating voltage, the adjustment or even shutdown of the bus frequency, the shutdown of the peripheral device working clock, etc. With hardware support, reasonable software design becomes the key to energy saving. Generally, low-power management can be divided into three categories:
The main implementation methods of processor power management are: dynamic management of CPU frequency and adjustment of working mode when the system is idle.
The main implementation method of device power management is to shut down individual idle devices.
The main implementation method of system platform power management is: specific customization for uncommon devices on a specific system platform.
With the rise of the Internet of Things (IoT), the demand for power consumption of products is becoming increasingly strong. Sensor nodes for data collection usually need to work for a long time when powered by batteries, while SOCs for networking also need to have fast response functions and low power consumption.
At the beginning of product development, the first consideration is to complete the product function development as soon as possible. After the product functions are gradually improved, it is necessary to add power management (PM) functions. In order to meet the needs of IoT, RT-Thread provides a power management component. The concept of the power management component is to be as transparent as possible, making it easier to add low-power functions to the product.
RT-Thread's PM component adopts a layered design concept, separating the architecture and chip-related parts, and extracting the common parts as the core. While providing a common interface to the upper layer, it also makes it easier for the underlying driver to adapt to the component.
The main features of RT-Thread PM components are as follows:
Manage power consumption based on mode, dynamically adjust working mode when idle, and support multiple levels of sleep.
Transparent to applications, components automatically complete power management at the bottom layer.
Supports dynamic frequency conversion in operating mode, automatically updates the frequency configuration of the device according to the mode, and ensures normal operation in different operating modes.
Supports device power management, automatically manages device suspend and resume according to the mode, and ensures correct suspend and resume in different sleep modes.
Supports optional sleep time compensation, allowing applications that rely on OS Tick to use it transparently.
Provides a device interface to the upper layer. If the devfs component is enabled, it can also be accessed through the file system interface.
The essence of low power consumption is that the CPU stops working when the system is idle, and continues to work after being woken up by an interrupt or event. In RTOS, there is usually an IDLE task, which has the lowest priority and always remains in a ready state. When a high-priority task is not ready, the OS executes the IDLE task. Generally, when low power consumption processing is not performed, the CPU loops and executes empty instructions in the IDLE task. In the IDLE task, the power management component of RT-Thread manages the CPU, clock, and devices, thereby effectively reducing the power consumption of the system.
As shown in the figure above, when the high-priority task ends or is suspended, the system will enter the IDLE task. After the IDLE task is executed, it will determine whether the system can enter the sleep state (to save power). If it can enter the sleep state, some hardware modules will be turned off according to the chip situation, and OS Tick is also very likely to enter the pause state. At this time, the power management framework will calculate the next timeout point according to the system timer situation, and set the low-power timer so that the device can wake up at this time point and perform subsequent work. When the system is awakened by (low-power timer interrupt or other wake-up interrupt source), the system also needs to know the length of the sleep time and compensate the OS Tick to adjust the system's OS tick value to a correct value.
In the RT-Thread PM component, peripherals or applications vote on the required power consumption mode through a voting mechanism. When the system is idle, the appropriate power consumption mode is determined based on the number of votes, and the abstract interface is called to control the chip to enter a low-power state, thereby reducing system power consumption. When no vote is performed, it enters the default mode (usually idle mode). Unlike applications, some peripherals may perform specific operations when entering a low-power state, and take measures to recover when exiting low power. This can be achieved by registering PM devices. By registering a PM device, the suspend callback of the registered device will be triggered before entering the low-power state, and the developer can perform his own operations in the callback; similarly, the resume callback will be triggered when exiting from a low-power state.
The RT-Thread PM component divides the system into two states: Run and Sleep. The Run state controls the CPU frequency and is suitable for variable frequency scenarios; the Sleep state implements the sleep CPU according to the SOC characteristics to reduce power consumption. The two states use different API interfaces and are independently controlled.
Hibernation
The sleep state is a low-power state in the usual sense. It reduces system power consumption by shutting down peripherals and executing the SOC power management interface. The sleep state is divided into six modes, which are presented in the form of a pyramid. As the modes increase, the power consumption decreases step by step. The following is the definition of the modes in the sleep state. Developers can implement the corresponding modes according to the specific SOC, but they need to follow the characteristics of the power consumption decreasing step by step.
model | level | describe |
PM_SLEEP_MODE_NONE | 0 | The system is in an active state and no power reduction state is adopted |
PM_SLEEP_MODE_IDLE | 1 | Idle mode, in which the CPU and some clocks are stopped when the system is idle, and any event or interrupt can wake up |
PM_SLEEP_MODE_LIGHT | 2 | Light sleep mode, CPU stops, most clocks and peripherals stop, time compensation is required after waking up |
PM_SLEEP_MODE_DEEP | 3 | Deep sleep mode, CPU stops, only a few low-power peripherals work, can be woken up by special interrupts |
PM_SLEEP_MODE_STANDBY | 4 | Standby mode, CPU stopped, device context lost (can be saved to special peripherals), usually reset after wakeup |
PM_SLEEP_MODE_SHUTDOWN | 5 | Shutdown mode, lower power consumption than Standby mode, context is usually not recoverable, reset after wakeup |
Note: Due to differences in chips from different manufacturers, the implementation of power management is also different. The above description only gives some recommended scenarios, not all of which need to be implemented. Developers can choose a few of them to implement according to their own situation, but they need to follow the principle that the higher the level, the lower the power consumption!
Running status
The operating state is usually used to change the CPU's operating frequency, independent of the sleep mode. The current operating state is divided into four levels: high speed, normal speed, medium speed, and low speed, as follows:
model | describe |
PM_RUN_MODE_HIGH_SPEED | High speed mode, suitable for some overclocking scenarios |
PM_RUN_MODE_NORMAL_SPEED | Normal mode, which is the default operating state |
PM_RUN_MODE_MEDIUM_SPEED | Medium speed mode reduces CPU speed and thus reduces power consumption |
PM_RUN_MODE_LOW_SPEED | Low speed mode, CPU frequency is further reduced |
In the PM component, upper-level applications can actively participate in power management by requesting and releasing sleep modes. Applications can request different sleep modes based on scenarios and release them after processing. As long as any application or device requests a high-level power mode, it will not switch to a lower mode. Therefore, the request and release operations of sleep mode usually appear in pairs, which can be used to protect a certain stage, such as the DMA transfer process of peripherals.
In the PM component, switching to a new operating mode may cause the CPU frequency to change. If the peripherals and the CPU share a part of the clock, the peripheral clock will be affected; when entering a new sleep mode, most clock sources will be stopped. If the peripheral does not support the freeze function of sleep, then when waking up from sleep, the peripheral clock needs to be reconfigured. Therefore, the PM component supports PM devices that are sensitive to PM mode. This allows the device to work normally when switching to a new operating mode or a new sleep mode. This function requires the underlying driver to implement the relevant interface and register as a device that is sensitive to mode changes.
First, the application sets the callback function for entering and exiting the sleep state, and then calls rt_pm_request to request the sleep mode, triggering the sleep operation; the PM component checks the sleep mode count when the system is idle, and gives a recommended mode based on the number of votes; then the PM component calls notify to notify the application that it is about to enter the sleep mode; then the registered PM device is suspended, and after returning OK, the sleep mode implemented by the SOC is executed, and the system enters the sleep state (if time compensation is enabled, the low power timer will be started before sleep). At this time, the CPU stops working and waits for events or interrupts to wake up. When the system is awakened, since the global interrupt is turned off, the system continues to execute from there, obtains the heartbeat of the sleep time compensation system, wakes up the devices in turn, and notifies the application to exit from the sleep mode. In this way, a cycle is completed, exits, and waits for the next idle time of the system.
Request sleep mode
parameter | model |
sleep_mode | Requested sleep mode level |
sleep_mode takes the following enumeration values:
Calling this function will increase the corresponding mode count by 1 and lock the mode. If you request a lower power mode at this time, you will not be able to enter. Only after releasing (unlocking) the previously requested mode can the system enter a lower mode; requests for higher power modes are not affected by this. This function needs to be used in conjunction with rt_pm_release to protect a certain stage or process.
Release sleep mode
parameter | model |
sleep_mode | Released sleep mode level |
Calling this function will reduce the corresponding mode count by 1, and can be used with rt_pm_request to release the previously requested mode.
Set the operating mode
parameter | model |
run_mode | Set the operating mode level |
run_mode can take the following enumeration values:
Call this function to change the CPU operating frequency, thereby reducing the power consumption during operation. This function only provides the level, and the specific CPU frequency should be determined according to the actual situation during the transplantation stage.
Set callback notification for entering/exiting sleep mode
parameter | model |
notify | Application callback function |
data | Private Data |
event is one of the following two enumeration values, which respectively indicate entering/exiting sleep mode.
Setting low power consumption level
If the system needs to enter a specified level of low power consumption, it can be achieved by calling rt_pm_request. For example, to enter deep sleep mode:
Note: If a higher power consumption mode is requested elsewhere in the program, such as Light Mode or Idle Mode, the corresponding mode needs to be released before the deep sleep mode can be entered.
Protect a stage or process
In special cases, such as when the system is not allowed to enter a lower power mode at a certain stage, the process can be protected by rt_pm_request and rt_pm_release. For example, during I2C reading data, entering deep sleep mode is not allowed (which may cause the peripheral to stop working), so the following processing can be done:
Change CPU operating frequency
Lowering the operating frequency can effectively reduce the power consumption of the system. The CPU operating frequency can be changed through the rt_pm_run_enter interface. Generally speaking, lowering the frequency means that the CPU performance is reduced and the processing speed is slowed down, which may lead to an increase in the execution time of the task, and a reasonable trade-off needs to be made.
Low power management is a very detailed task. When porting, developers not only need to fully understand the power management of the chip itself, but also need to be familiar with the peripheral circuits of the board and process them one by one when entering the low power state to avoid the situation where the peripheral circuit leakage increases the overall power consumption. The RT-Thread PM component abstracts each part and provides different ops interfaces for developers to adapt. The parts that need to be paid attention to during porting are as follows:
The power consumption characteristics of the chip itself
Each chip has different definitions and management of low-power modes. The PM component abstracts chip-related features into a sleep interface. This interface adapts to chip-related low-power management. When entering different sleep modes, some hardware-related configurations, saves, and other related processes are performed.
Sleep time compensation
In some sleep modes (Light Sleep or Deep Sleep), the heartbeat timer may be stopped. In this case, you need to start a timer to measure the sleep time and compensate the heartbeat after waking up. The timer for time compensation must still work normally in this mode and wake up the system, otherwise it is meaningless!
timer_start
: Start the low power timer, the input parameter is the nearest task ready time; timer_get_tick
: Get the sleep time when the system is awakened; timer_stop
: Used to stop the low power timer after the system wakes up.
Note : The time compensation of sleep mode needs to be enabled during the initialization phase by setting the bit control of the corresponding mode of timer_mask. For example, if you need to enable the time compensation of Deep Sleep mode, after implementing the timer-related ops interface, set the corresponding bit during initialization:
Operation mode variable frequency
The frequency conversion of the running mode is achieved by adapting the run interface in rt_pm_ops, and the appropriate frequency is selected according to the usage scenario.
Power management of peripherals
Peripheral power consumption processing is an important part of the low power management system. When entering certain levels of sleep mode, some peripherals usually need to be processed, such as clearing DMA, turning off the clock, or setting IO to reset state; and recovering after exiting sleep. In this case, you can register the PM device through the interface. When entering/exiting sleep mode, the and callbacks rt_pm_device_register
of the registered device will be executed ; frequency changes in the running mode will also trigger the device's callback.suspendresumefrequency_change
For more detailed porting examples, please refer to the stm32l476-nucleo bsp in the RT-Thread repository.
You can use pm_request
the command request mode. The usage example is as follows:
The parameter value is 0-5, corresponding to the following enumeration values:
You can use pm_release
the command to release the mode. The parameter value is 0-5. The usage example is as follows:
You can use pm_run
the command to switch the operation mode. The parameter value is 0-3. The usage example is as follows
Parameter value 0-3
You can use pm_dump
the command to view the mode status of the PM component. The usage example is as follows:
In pm_dump
the mode list, the priority of sleep mode is arranged from high to low. Counter
One column indicates the request count value. The figure shows that the LightSleep mode is requested once, so the current work is in light sleep state; Timer
one column indicates whether to enable sleep time compensation. In the figure, only the DeepSleep mode performs time compensation. The bottom indicates the current sleep mode and operating mode level.
The power consumption is high after the system enters low power mode
According to the peripheral circuit, check whether the device is in a reasonable state to avoid peripheral leakage; according to the product itself, turn off the peripherals and clocks that are not used during the corresponding sleep mode.
Unable to enter lower power consumption levels
Check whether the high-level power consumption mode has not been released. The PM component of RT-Thread uses rt_pm_request
request sleep mode. If a high-power consumption mode is requested but not released, the system will not be able to switch to a lower level of power consumption. For example, after requesting the Light Sleep mode, the Deep Sleep mode is then requested, and the system is still in the Light Sleep mode. By calling the interface rt_pm_release
to release the Light Sleep mode, the system will automatically switch to the Deep Sleep mode.