1@page page_component_pm Power Management: PM
2
3The purpose of low power management of embedded system is to reduce system energy consumption as much as possible to prolong the standby time of equipment on the premise of satisfying users'performance requirements. The contradiction between high performance and limited battery energy is most prominent in embedded systems. The combination of hardware low power design and software low power management has become an effective means to solve the contradiction. Nowadays, all kinds of MCUs provide management interfaces in low power consumption more or less. For example, adjusting the frequency of the main control clock, changing the working voltage, adjusting or even closing the bus frequency, closing the working clock of peripheral equipment, etc. With the support of hardware, reasonable software design becomes the key to energy saving. Generally, low power management can be divided into three categories:
4
5- Processor Power Management
6
7  - The main ways of realization are dynamic management of CPU frequency and adjustment of working mode when the system is idle.
8
9- Power management of equipment
10
11  - The main way to achieve this is to shut down individual idle devices
12
13- Power Management of System Platform
14
15  - The main way to realize it is to specific customization of infrequent devices on specific system platforms.
16
17With the rise of the Internet of Things (IoT), the demand for power consumption of products becomes more and more intense. Sensor nodes as data acquisition usually need to work long-term when the battery is powered, and SOC connected to the network also needs fast response function and low power consumption.
18
19In the initial stage of product development, the first consideration is to complete the development of product functions as soon as possible. After the function of the product is gradually improved, it is necessary to add the power management (PM) function. To meet this need of IoT, RT-Thread provides power management components. The idea of power management components is to be as transparent as possible, making it easier for products to add low power functions.
20
21# Introduction of PM Components
22
23RT-Thread's PM components adopt a layered design idea, separating architecture and chip-related parts, and extracting common parts as the core. While providing a common interface to the upper layer, it also makes it easier for the bottom driver to adapt components.
24
25![PM Component Overview](figures/pm_system.png)
26
27## Main Features
28
29The main features of RT-Thread PM components are as follows:
30
31- It manages power consumption based on mode, dynamically adjusts working mode in idle time, and supports multiple levels of sleeping.
32- Transparent to applications, components automatically complete power management at the bottom layer.
33- It supports dynamic frequency conversion in running mode and updates the frequency configuration of equipment automatically according to the mode to ensure normal operation in different running modes.
34- Support equipment power management, automatically manage device suspending and resuming according to the mode, ensure correct suspending and resuming in different sleep mode.
35- Optional sleep time compensation is supported to make OS Tick dependent applications transparent.
36- Provide the device interface to the upper layer. If the devfs component is opened, it can also be accessed through the file system interface.
37
38## Working Principle
39
40The essence of low power consumption is that when the system is idle, the CPU stops working, interrupts or resumes working after the event wakes up. In RTOS, there is usually an IDLE task, which has the lowest priority and remains ready. When the high priority task is not ready, the OS executes the IDLE task. Generally, the CPU executes empty instructions in IDLE tasks without low power processing. The power management component of RT-Thread can effectively reduce the power consumption of the system by managing CPU, clock and equipment in IDLE tasks.
41
42![PM工作原理](figures/pm_description.png)
43
44As shown in the figure above, when the high priority thread runs out or is suspended, the system enters the IDLE thread . After the IDLE thread is executed, it will determine whether the system can go to sleep (to save power). If the system goes to sleep, Some hardware modules will be shut down depending on the chip condition, and OS Tick is also very likely to enter a pause state. At this time, the power management framework will calculate the next timeout point according to the system timer situation, and set a low-power timer, so that the device can wake up at that point, and carry out follow-up work. When the system is awakened (low power timer interrupt or other wake-up interrupt source), the system also needs to know how long it sleeps, and compensate for OS Tick, so that the OS tick value of the system is adjusted to a correct value.
45
46# PM Framework
47
48In RT-Thrad PM components, peripherals or applications vote on the required power consumption mode by voting mechanism. When the system is idle, the appropriate power consumption mode is decided according to the voting number, and the abstract interface is called to control the chip to enter a low power consumption state, so as to reduce the power consumption of the system. When no vote is taken, it is entered in the default mode (usually idle mode). Unlike applications, some peripherals may perform specific operations when they enter a low-power state and take measures to recover when they exit a low-power state, which can be achieved by registering PM devices. By registering PM devices, `suspend` callbacks of registered devices will be triggered before entering a low power state. Developers can perform their own operations in the callbacks. Similarly, `resume` callbacks will be triggered when exiting from a low power state.
49
50![PM Framework](figures/pm_architecture.png)
51
52# Low Power State and Mode
53
54The RT-Thread PM component divides the system into two states: RUN(running state) and Sleep(sleeping state).
55
56Running state controls the frequency of CPU, which is suitable for frequency conversion scenarios. Sleeping state realizes sleeping CPU according to SOC characteristics to reduce power consumption. The two states are controlled independently using different API interfaces.
57
58- **Sleeping state**
59
60Sleeping state is also a low power state in the usual sense. By closing the peripherals and executing the SOC power management interface, the system power consumption is reduced.
61
62The state of sleeping is divided into six patterns, which take the form of pyramids. As the mode increases, the power consumption decreases step by step. The following is the definition of the mode in the sleeping state. Developers can implement the corresponding mode according to the specific SOC, but they need to follow the characteristics of power consumption decreasing step by step.
63
64| Patterns               | Level | Description                                                  |
65| ---------------------- | ----- | ------------------------------------------------------------ |
66| PM_SLEEP_MODE_NONE     | 0     | The system is active without any power reduction.            |
67| PM_SLEEP_MODE_IDLE     | 1     | The idle mode, which stops CPU and part of the clock when the system is idle. Any event or interrupt can wake up system. |
68| PM_SLEEP_MODE_LIGHT    | 2     | Light sleep modes, CPU stops, most clocks and peripherals stop, and time compensation is required after wake-up. |
69| PM_SLEEP_MODE_DEEP     | 3     | Deep sleep mode, CPU stops, only a few low power peripheral work, can be awakened by special interrupts |
70| PM_SLEEP_MODE_STANDBY  | 4     | Standby mode, CPU stops, device context loss (can be saved to special peripherals), usually reset after wake-up |
71| PM_SLEEP_MODE_SHUTDOWN | 5     | Shutdown mode, lower power consumption than Standby mode, context is usually irrecoverable, reset after wake-up |
72
73>Note: The implementation of power management varies from chip to chip. The above description only gives some recommended scenarios, not all of which need to be implemented. Developers can choose several of them to implement according to their own situation, but they need to follow the principle of higher level and lower power consumption.
74
75- **Running state**
76
77Running state is usually used to change the running frequency of CPU, independent of sleep mode. Current operation status is divided into four levels: high-speed, normal-speed, medium-speed and low-speed, as follows:
78
79| Patterns                 | Description                                                  |
80| ------------------------ | ------------------------------------------------------------ |
81| PM_RUN_MODE_HIGH_SPEED   | High-speed mode, suitable for some over-frequency scenarios  |
82| PM_RUN_MODE_NORMAL_SPEED | Normal-speed mode, which is the default running state        |
83| PM_RUN_MODE_MEDIUM_SPEED | Medium-speed mode, reduce CPU running speed, thereby reducing power consumption |
84| PM_RUN_MODE_LOW_SPEED    | Low-speed mode, CPU frequency further reduced                |
85
86## Request and release of patterns
87
88In PM components, upper applications can actively participate in power management by requesting and releasing sleep modes. Applications can request different sleep modes according to scenarios and release them after processing. As long as any application or device requests higher-level power mode, it will not switch to a lower mode. Therefore, the requests and releases of sleep mode usually occur in pairs and can be used to protect a certain stage, such as the peripheral DMA transmission process.
89
90## Device Sensitive to Mode Changes
91
92In PM components, switching to a new mode of operation may lead to changes in CPU frequency. If peripherals and CPUs share a part of the clock, the peripheral clock will be affected. When entering the new sleep mode, most clock sources will be stopped. If the peripheral does not support the freezing function of sleep, then the peripheral clock needs to be reconfigured when waking up from sleep. So PM components support PM mode sensitive PM devices. It enables the device to work normally when switching to a new operation mode or a new sleep mode. This function requires the underlying driver to implement the relevant interface and register as a device sensitive to mode changes.
93
94# The calling process
95
96![PM Sequence](figures/pm_sequence.png)
97
98Firstly, the application layer sets the callback function of entering and exiting the dormancy state, and then calls `rt_pm_request` to request the sleeping mode to trigger the sleeping operation. The PM component checks the number of sleeping modes when the system is idle, and gives the recommended mode according to the number of votes. Then the PM component calls `notfiy` to inform the application that it is going to enter the sleep mode, and then suspends the registered PM device and executes the sleep mode implemented by SOC after returning to OK. The system enters the sleep state (if the enabling time is compensated, the low-power timer will be started before the sleep). At this point, the CPU stops working and waits for an event or interrupt to wake up. When the system is awakened, because the global interruption is closed, the system continues to execute from there, gets the sleep time to compensate the OS tick of the system, wakes up the device in turn, and notifies the application to exit from the sleep mode. Such a cycle is completed, exits, and waits for the system to be idle next time.
99
100# Introduction to APIs
101
102## Request Sleep Mode
103
104```c
105void rt_pm_request(uint8_t sleep_mode);
106```
107
108| Parameter  | Mode                     |
109| ---------- | ------------------------ |
110| sleep_mode | Request Sleep mode level |
111
112Sleep_mode takes the following enumeration values:
113
114```c
115enum
116{
117    /* sleep modes */
118    PM_SLEEP_MODE_NONE = 0,    /* active state */
119    PM_SLEEP_MODE_IDLE,        /* idle mode (default) */
120    PM_SLEEP_MODE_LIGHT,       /* Light Sleep Mode */
121    PM_SLEEP_MODE_DEEP,        /* Deep Sleep Mode */
122    PM_SLEEP_MODE_STANDBY,     /* Standby Mode */
123    PM_SLEEP_MODE_SHUTDOWN,    /* Shutdowm Mode */
124    PM_SLEEP_MODE_MAX,
125};
126```
127
128Calling this function adds the corresponding pattern count to 1 and locks the pattern. At this point, if a lower level of power mode is requested, it will not be accessible. Only after releasing (unlocking) the previously requested mode, the system can enter a lower level of power mode; requests to higher power mode are not affected by this. This function needs to be used in conjunction with `rt_pm_release` to protect a certain stage or process.
129
130## Release  Sleep Mode
131
132```c
133void rt_pm_release(uint8_t sleep_mode);
134```
135
136| Parameter  | Mode             |
137| ---------- | ---------------- |
138| sleep_mode | Sleep mode level |
139
140Calling this function decreases the corresponding pattern count by 1, and releases the previously requested pattern in conjunction with `rt_pm_request`.
141
142## Setting up Running Mode
143
144```c
145int rt_pm_run_enter(uint8_t run_mode);
146```
147
148| Parameter | Mode               |
149| --------- | ------------------ |
150| run_mode  | Running mode level |
151
152`run_mode` can take the following enumeration values:
153
154```c
155enum
156{
157    /* run modes*/
158    PM_RUN_MODE_HIGH_SPEED = 0,    /* high speed */
159    PM_RUN_MODE_NORMAL_SPEED,      /* Normal speed(default) */
160    PM_RUN_MODE_MEDIUM_SPEED,      /* Medium speed */
161    PM_RUN_MODE_LOW_SPEED,         /* low speed */
162    PM_RUN_MODE_MAX,
163};
164```
165
166Calling this function changes the CPU's running frequency, thereby reducing the power consumption at runtime. This function only provides levels, and the specific CPU frequency should depend on the actual situation during the migration phase.
167
168## Setting up callback notifications for entering/exiting sleep mode
169
170```c
171void rt_pm_notify_set(void (*notify)(uint8_t event, uint8_t mode, void *data), void *data);
172```
173
174| Parameter | Mode              |
175| --------- | ----------------- |
176| notify    | callback function |
177| data      | Private data      |
178
179Evet is the following two enumeration values, identifying entry/exit sleep mode respectively.
180
181```c
182enum
183{
184    RT_PM_ENTER_SLEEP = 0,    /* entry sleep mode */
185    RT_PM_EXIT_SLEEP,         /* exit sleep mode */
186};
187
188```
189
190# Instruction for Use
191
192## Setting Low Power Level
193
194If the system needs to enter a specified level of low power consumption, it can be achieved by calling rt_pm_request. For example, into deep sleep mode:
195
196```c
197/* Request for Deep Sleep Mode */
198rt_pm_request(PM_SLEEP_MODE_DEEP);
199```
200
201> Note: If higher power consumption modes, such as Light Mode or Idle Mode, are requested elsewhere in the program, then the corresponding mode needs to be released before the deep sleep mode can be entered.
202
203## Protect a stage or process
204
205In special cases, for example, the system is not allowed to enter a lower power mode at a certain stage, which can be protected by rt_pm_request and rt_pm_release. For example, deep sleep mode (which may cause peripherals to stop working) is not allowed during I2C reading data, so the following processing can be done:
206
207```c
208/* Request light sleep mode (I2C peripheral works normally in this mode) */
209rt_pm_request(PM_SLEEP_MODE_LIGHT);
210
211/* Reading Data Procedure */
212
213/* Release this model */
214rt_pm_release(PM_SLEEP_MODE_LIGHT);
215
216```
217
218## Changing CPU Running Frequency
219
220Reducing the running frequency can effectively reduce the power consumption of the system, and the running frequency of the CPU can be changed through the `rt_pm_run_enter` interface. Generally speaking, frequency reduction means that CPU performance decreases and processing speed decreases, which may lead to the increase of task execution time and need to be weighed reasonably.
221
222```c
223/* Enter Medium Speed Mode */
224rt_pm_run_enter(PM_RUN_MODE_MEDIUM_SPEED);
225```
226
227# Migration instructions
228
229Low power management is a very meticulous task. Developers need not only to fully understand the power management of the chip itself, but also to be familiar with the peripheral circuit of the board and deal with it one by one when they enter the low power state, so as to avoid leakage of the peripheral circuit and pull up the overall power consumption.
230
231RT-Thread PM components Abstract each part and provide different OPS interfaces for developers to adapt. The following points need to be paid attention to when they migration:
232
233```c
234/**
235 * low power mode operations
236 */
237struct rt_pm_ops
238{
239    /* Sleep interface for adapting chip-related low power characteristics */
240    void (*sleep)(struct rt_pm *pm, uint8_t mode);
241    /* Run Interface for Frequency Conversion and Voltage Conversion in Running Mode */
242    void (*run)(struct rt_pm *pm, uint8_t mode);
243    /* The following three interfaces are used to start a low-power timer after cardiac arrest to compensate for the OS tick */
244    void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout);
245    void (*timer_stop)(struct rt_pm *pm);
246    rt_tick_t (*timer_get_tick)(struct rt_pm *pm);
247};
248
249/* The OPS is used to manage the power consumption of peripherals */
250struct rt_device_pm_ops
251{
252    /* Suspending the peripheral before entering sleeping mode and return to non-zero to indicate that the peripheral is not ready and cannot enter */
253    int (*suspend)(const struct rt_device *device, uint8_t mode);
254    /* Resume peripherals after exiting from sleep mode */
255    void (*resume)(const struct rt_device *device, uint8_t mode);
256    /* When the mode changes, notify peripheral processing in the running state */
257    int (*frequency_change)(const struct rt_device *device, uint8_t mode);
258};
259
260/* Register a PM device */
261void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops);
262```
263
264## Power Consumption Characteristics of Chips
265
266```c
267void (*sleep)(struct rt_pm *pm, uint8_t mode);
268```
269
270Each chip has different definitions and management of low power mode. PM component abstracts chip-related characteristics into sleep interface. The interface adapts to low power management related to chips. When entering different `sleep` modes, some hardware-related configurations, storage and other related processing are needed.
271
272## Time Compensation for Sleep Mode
273
274```c
275void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout);
276void (*timer_stop)(struct rt_pm *pm);
277rt_tick_t (*timer_get_tick)(struct rt_pm *pm);
278```
279
280In some sleep modes (Light Sleep or Deep Sleep), the OS Tick timer in the kernel may be stopped. At this time, it is necessary to start a timer to measure the time of sleep and compensate for the OS Tick after waking up. Time compensated timer must still be able to work properly in this mode and wake up the system, otherwise it is meaningless!
281
282- **timer_start**: Start a low-power timer, and the input parameter is the latest next task readiness time.
283- **timer_get_tick**: Get the sleep time when the system is awakened;
284- **timer_stop**: Used to stop low-power timers after system wake-up.
285
286**Note**: Time compensation for sleep mode needs to be turned on at the initialization stage by setting the bit control of the corresponding mode of timer_mask. For example, if time compensation in Deep Sleep mode needs to be turned on, then after implementing the timer-related OPS interface, the corresponding bit is set at initialization:
287
288```c
289rt_uint8_t timer_mask = 0;
290
291/* Set the bit corresponding to Deep Sleep mode to enable sleep time compensation */
292timer_mask = 1UL << PM_SLEEP_MODE_DEEP;
293
294/* initialize system pm module */
295rt_system_pm_init(&_ops, timer_mask, RT_NULL);
296
297```
298
299## Frequency Conversion in Running Mode
300
301```
302void (*run)(struct rt_pm *pm, uint8_t mode);
303```
304
305The frequency conversion of operation mode is realized by adapting the `run` interface in `rt_pm_ops`, and the appropriate frequency is selected according to the use scenario.
306
307## Power management of peripherals
308
309Power processing of peripherals is an important part of low power management system. When entering some level of sleep mode, it is usually necessary to process some peripherals, such as emptying DMA, closing clock or setting IO to reset state, and recover after quitting sleep.
310
311In this case, PM devices can be registered through rt_pm_device_register interface, suspend and resume callbacks of registered devices will be executed when entering/exiting Sleeping mode, and frequency_change callbacks of devices will also be triggered by frequency changes in Running mode.
312
313A more detailed migration case can be referred to stm32l476-nucleo BSP in the RT-Thread repository.
314
315# MSH Commands
316
317## Request Sleep Mode
318
319The `pm_request` command can be used to request related patterns, using an example as follows:
320
321```c
322msh />pm_request 0
323msh />
324```
325
326The range of parameter values is 0-5, corresponding to the following enumeration values:
327
328```c
329enum
330{
331    /* sleep modes */
332    PM_SLEEP_MODE_NONE = 0,    /* active state */
333    PM_SLEEP_MODE_IDLE,        /* idle mode (default) */
334    PM_SLEEP_MODE_LIGHT,       /* Light Sleep Mode */
335    PM_SLEEP_MODE_DEEP,        /* Deep Sleep Mode */
336    PM_SLEEP_MODE_STANDBY,     /* Standby Mode */
337    PM_SLEEP_MODE_SHUTDOWN,    /* Shutdowm Mode */
338    PM_SLEEP_MODE_MAX,
339};
340```
341
342## Release Sleep Mode
343
344You can use the `pm_release` command to release the sleep mode. The range of parameters is 0-5, and the examples are as follows:
345
346```c
347msh />pm_release 0
348msh />
349```
350
351## Setting up Running Mode
352
353You can use the `pm_run` command to switch the mode of operation with parameters ranging from 0 to 3, as shown in the following example
354
355```c
356msh />pm_run 2
357msh />
358```
359
360The range of parameters is 0 to 3:
361
362```c
363enum
364{
365    /* run modes*/
366    PM_RUN_MODE_HIGH_SPEED = 0,
367    PM_RUN_MODE_NORMAL_SPEED,
368    PM_RUN_MODE_MEDIUM_SPEED,
369    PM_RUN_MODE_LOW_SPEED,
370    PM_RUN_MODE_MAX,
371};
372```
373
374## View mode status
375
376You can use the `pm_dump` command to view the mode state of the PM component, as shown in the following example
377
378```c
379msh >
380msh >pm_dump
381| Power Management Mode | Counter | Timer |
382+-----------------------+---------+-------+
383|             None Mode |       0 |     0 |
384|             Idle Mode |       0 |     0 |
385|       LightSleep Mode |       1 |     0 |
386|        DeepSleep Mode |       0 |     1 |
387|          Standby Mode |       0 |     0 |
388|         Shutdown Mode |       0 |     0 |
389+-----------------------+---------+-------+
390pm current sleep mode: LightSleep Mode
391pm current run mode:   Normal Speed
392msh >
393```
394
395In the pattern list of `pm_dump`, the priority of sleep mode is arranged from high to low.
396
397The `Counter` column identifies the count of requests. The graph shows that the Light Sleep mode is requested once, so the current work is in a slight sleep state.
398
399The `Timer` column identifies whether to turn on sleep time compensation. In the figure, only Deep Sleep mode is used for time compensation.
400
401The bottom part identifies the current sleep mode and running mode level respectively.
402
403# Common problems and debugging methods
404
405- When the system enters the low power mode, the power consumption is too high.
406
407According to the peripheral circuit, check whether the equipment is in a reasonable state to avoid leakage of peripheral equipment.
408
409According to the product's own situation, turn off the peripherals and clocks that are not used during the corresponding sleep mode.
410
411- Unable to enter lower levels of power consumption
412
413Check whether the higher-level power consumption mode is not released. RT-Thread's PM component uses `rt_pm_request` to request dormancy mode. If it is not released after requesting high-power consumption mode, the system will not be able to switch to lower-level power consumption.
414
415For example, after requesting Light Sleep mode, then requesting Deep Sleep mode, the system is still in Light Sleep mode. By calling the interface `rt_pm_request` to release the Light Sleep mode, the system will automatically switch to the Deep Sleep mode.
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431