Power Management

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

    void rt_pm_request(uint8_t sleep_mode);copymistakeCopy Success

    parameter

    model

    sleep_mode

    Requested sleep mode level

sleep_mode takes the following enumeration values:

enum
{
    /* sleep modes */
    PM_SLEEP_MODE_NONE = 0,    /* 活跃状态 */
    PM_SLEEP_MODE_IDLE,        /* 空闲模式(默认) */
    PM_SLEEP_MODE_LIGHT,       /* 轻度睡眠模式 */
    PM_SLEEP_MODE_DEEP,        /* 深度睡眠模式 */
    PM_SLEEP_MODE_STANDBY,     /* 待机模式 */
    PM_SLEEP_MODE_SHUTDOWN,    /* 关断模式 */
    PM_SLEEP_MODE_MAX,
};copymistakeCopy Success

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

    void rt_pm_release(uint8_t sleep_mode);copymistakeCopy Success

    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

    int rt_pm_run_enter(uint8_t run_mode);copymistakeCopy Success

    parameter

    model

    run_mode

    Set the operating mode level

run_mode can take the following enumeration values:

enum
{
    /* run modes*/
    PM_RUN_MODE_HIGH_SPEED = 0,    /* 高速 */
    PM_RUN_MODE_NORMAL_SPEED,      /* 正常(默认) */
    PM_RUN_MODE_MEDIUM_SPEED,      /* 中速 */
    PM_RUN_MODE_LOW_SPEED,         /* 低速 */
    PM_RUN_MODE_MAX,
};copymistakeCopy Success

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

    void rt_pm_notify_set(void (*notify)(uint8_t event, uint8_t mode, void *data), void *data);copymistakeCopy Success

    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.

enum
{
    RT_PM_ENTER_SLEEP = 0,    /* 进入休眠模式 */
    RT_PM_EXIT_SLEEP,         /* 退出休眠模式 */
};
copymistakeCopy Success

  • 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:

/* 请求进入深度睡眠模式 */
rt_pm_request(PM_SLEEP_MODE_DEEP);copymistakeCopy Success

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:

/* 请求轻度睡眠模式(I2C外设该模式下正常工作) */
rt_pm_request(PM_SLEEP_MODE_LIGHT);

/* 读取数据过程 */

/* 释放该模式 */
rt_pm_release(PM_SLEEP_MODE_LIGHT);
copymistakeCopy Success
  • 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.

/* 进入中等速度运行模式 */
rt_pm_run_enter(PM_RUN_MODE_MEDIUM_SPEED);copymistakeCopy Success

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:

/**
 * low power mode operations
 */
struct rt_pm_ops
{
    /* sleep 接口用于适配芯片相关的低功耗特性 */
    void (*sleep)(struct rt_pm *pm, uint8_t mode);
    /* run 接口用于运行模式的变频和变电压 */
    void (*run)(struct rt_pm *pm, uint8_t mode);
    /* 以下三个接口用于心跳停止后启动低功耗定时器以补偿心跳 */
    void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout);
    void (*timer_stop)(struct rt_pm *pm);
    rt_tick_t (*timer_get_tick)(struct rt_pm *pm);
};

/* 该 ops 用于管理外设的功耗 */
struct rt_device_pm_ops
{
    /* 进入休眠模式之前挂起外设,返回非 0 表示外设未就绪,不能进入 */
    int (*suspend)(const struct rt_device *device, uint8_t mode);
    /* 从休眠模式退出后恢复外设 */
    void (*resume)(const struct rt_device *device, uint8_t mode);
    /* 运行状态下模式改变通知外设处理 */
    int (*frequency_change)(const struct rt_device *device, uint8_t mode);
};

/* 注册一个 PM 设备 */
void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops);copymistakeCopy Success
  • The power consumption characteristics of the chip itself

    void (*sleep)(struct rt_pm *pm, uint8_t mode);copymistakeCopy Success

    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

void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout);
void (*timer_stop)(struct rt_pm *pm);
rt_tick_t (*timer_get_tick)(struct rt_pm *pm);copymistakeCopy Success

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:

rt_uint8_t timer_mask = 0;

/* 设置 Deep Sleep 模式对应的 bit,使能休眠时间补偿 */
timer_mask = 1UL << PM_SLEEP_MODE_DEEP;

/* initialize system pm module */
rt_system_pm_init(&_ops, timer_mask, RT_NULL);copymistakeCopy Success
  • Operation mode variable frequency

void (*run)(struct rt_pm *pm, uint8_t mode);copymistakeCopy Success

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_registerof 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_requestthe command request mode. The usage example is as follows:

msh />pm_request 0
msh />copymistakeCopy Success

The parameter value is 0-5, corresponding to the following enumeration values:

enum
{
    /* sleep modes */
    PM_SLEEP_MODE_NONE = 0,    /* 活跃状态 */
    PM_SLEEP_MODE_IDLE,        /* 空闲模式(默认) */
    PM_SLEEP_MODE_LIGHT,       /* 轻度睡眠模式 */
    PM_SLEEP_MODE_DEEP,        /* 深度睡眠模式 */
    PM_SLEEP_MODE_STANDBY,     /* 待机模式 */
    PM_SLEEP_MODE_SHUTDOWN,    /* 关断模式 */
    PM_SLEEP_MODE_MAX,
};copymistakeCopy Success

You can use pm_releasethe command to release the mode. The parameter value is 0-5. The usage example is as follows:

msh />pm_release 0
msh />copymistakeCopy Success

You can use pm_runthe command to switch the operation mode. The parameter value is 0-3. The usage example is as follows

msh />pm_run 2
msh />copymistakeCopy Success

Parameter value 0-3

enum
{
    /* run modes*/
    PM_RUN_MODE_HIGH_SPEED = 0,
    PM_RUN_MODE_NORMAL_SPEED,
    PM_RUN_MODE_MEDIUM_SPEED,
    PM_RUN_MODE_LOW_SPEED,
    PM_RUN_MODE_MAX,
};copymistakeCopy Success

You can use pm_dumpthe command to view the mode status of the PM component. The usage example is as follows:

msh >
msh >pm_dump
| Power Management Mode | Counter | Timer |
+-----------------------+---------+-------+
|             None Mode |       0 |     0 |
|             Idle Mode |       0 |     0 |
|       LightSleep Mode |       1 |     0 |
|        DeepSleep Mode |       0 |     1 |
|          Standby Mode |       0 |     0 |
|         Shutdown Mode |       0 |     0 |
+-----------------------+---------+-------+
pm current sleep mode: LightSleep Mode
pm current run mode:   Normal Speed
msh >copymistakeCopy Success

In pm_dumpthe mode list, the priority of sleep mode is arranged from high to low. CounterOne 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_requestrequest 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_releaseto release the Light Sleep mode, the system will automatically switch to the Deep Sleep mode.

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