• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..--

core/18-Mar-2025-1,661889

devices/18-Mar-2025-24,53015,382

images/18-Mar-2025-

README.mdD18-Mar-202521.4 KiB429273

README.md

1# Leveraging MCUXpresso SDK Power Manager for MCU class of devices
2
3## Table of content
41. [Introduction](#introduction)
52. [Glossary](#glossary)
63. [SDK Power Manager](#sdkpm)
7    1. [Features](#features)
8    2. [Architecture](#architecture)
94. [Application Example](#appex)
105. [APIs references](#apiref)
116. [Conclusion](#conclusion)
12
13
14## 1. Introduction <a id="introduction"></a>
15
16MCUs feature different low-power states for static power optimizations. Multiple states such as ON, retention (for memories) or OFF can be defined for each MCU low-power state, peripheral, memory or clock.  Each of these states can be specific to a device.
17
18The Power Manager component included in NXP’s MCUXpresso SDK is a software framework available for bare-metal code and FreeRTOS applications, aiming at facilitating its development. By abstracting the SoC architecture, the developer can easily integrate the management of low-power states in the application and speed up the time-to-market. The SDK Power Manager uses low-level drivers, offloads the full comprehension of the device by providing a resources and operating modes constraints mechanism, and optimizes the power consumption by shutting down the resources not required by the user.
19
20<br/>
21
22## 2. Glossary <a id="glossary"></a>
23
24- Bare-Metal – application/driver code without an Operating System.
25- EVK – Evaluation Kit / Evaluation Board.
26- MCU – Microcontroller Unit.
27- SDK – Software Development Kit.
28- SoC – System-on-Chip.
29
30<br/>
31
32## 3. SDK Power Manager <a id="sdkpm"></a>
33
34### 1. Features <a id="features"></a>
35
36<br/>
37
38Features of the SDK Power Manager are:
39- Manage the transition for the different operating modes by seamlessly modifying the registers based on resource constraints:
40    - SDK Power Manager turns all resources OFF by default, except the ones required by the user.
41- Ease the management of wakeup sources.
42- Notify upper layer (for example the application) about power transitions or wakeup events.
43- Gather constraints and/or find the lowest-power state achievable depending on user constraints or timing (if declared):
44    - The user can specify the low-power state to enter and the resource constraints. If the resource constraints or timing do not match the constraints of the low-power state, the SDK Power Manager will find a lighter low-power state that satisfies the required resource constraints and timing.
45    - The user is only required to specify the low-power state to enter. All the possible resources satisfying the low-power states will be turned off by the SDK Power Manager.
46    - The user is only required to specify the resource constraints. The SDK Power Manager will find the deepest low-power state to enter that satisfies the resource constraints.
47
48<br/>
49
50### 2. Architecture <a id="architecture"></a>
51
52<br/>
53
54The SDK power manager is composed of two parts.
55Firstly the “core” part, is generic across devices and provides APIs to be called in the application. This part is composed of different sub-modules:
56- The policy module: gathers all constraints and finds the deepest power state allowed.
57- The wakeup-source manager module: configures the wakeup sources and processes registered wakeup-source handler callbacks.
58- The notification module: Notifies the upper layer of specific power transitions and events.
59
60Then the “device” part, is specific for each device and describes the entry/exit sequences of the power modes, called the sequencer. There is also the description of all the resource constraints available: the pre-defined constraints for the low-power states. This part is not intended to be modified by the user.  Instead, the application defines the resource constraints to keep enabled for a given low-power state.
61
62<br/>
63
64![SDK Power Manager Architecture Diagram](images/SDK_PM_architecture.png "SDK Power Manager Architecture Diagram")
65
66<br/>
67
68The framework is defined and developed by NXP, exposing the pre-defined constraints and easy-to-use APIs to the user for application development.
69Here are examples of APIs to call in the application to leverage the SDK power manager:
70- **PM_CreateHandle** --> MANDATORY ; Initializes the power manager handler, to be called before using other Power Manager APIs.
71
72- **PM_RegisterNotify** --> OPTIONAL ; Registers a notify element into the selected group. The callback of the group will be called just before the entry to low-power state and just after the exit from the low-power state.
73
74- **PM_InitWakeupSource** --> OPTIONAL ; Initialize the wakeup source.
75
76- **PM_RegisterTimerController** --> OPTIONAL ; Register a timer as a wakeup source, to be called with **PM_InitWakeupSource**.
77
78- **PM_SetConstraints** --> MANDATORY ; Set constraints to Power Manager defined by the user, and/or for a low-power state. To easily define constraints, the user can define a macro.
79
80- **PM_EnablePowerManager** --> MANDATORY ; Enable/Disable Power Manager functions.
81
82- **PM_EnterLowPower** --> MANDATORY ; Find the ideal low-power state available, based on registered constraints, then notifies groups, and enters/exits the low-power state.
83
84<br/>
85
86There is also macros that the user can modify depending on the need, located in *fsl_pm_device_config.h*:
87
88- **FSL_PM_SUPPORT_NOTIFICATION** --> Allows the Power Manager to notify created notification groups of power transitions, i.e entry/exit of a state. It can be useful to re-enable a peripheral just after exiting the low-power state.
89
90- **FSL_PM_SUPPORT_WAKEUP_SOURCE_MANAGER** --> Allows the Power Manager to fully manage (create, disable, handle, trigger) wakeup sources.
91
92- **FSL_PM_SUPPORT_LP_TIMER_CONTROLLER** --> Allows the Power Manager to control timers.
93
94- **FSL_PM_SUPPORT_ALAWAYS_ON_SECTION** --> Allows to store variables in an always-on RAM.
95
96For more details on APIs available and description, please refer to the *fsl_pm_core* files.
97
98<br/>
99
100## 4. Application Example <a id="appex"></a>
101
102<br/>
103
104This example is a bare-metal application based on the [i.MX RT500 EVK](https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/i-mx-rt595-evaluation-kit:MIMXRT595-EVK). This example demonstrates low-power transition by leveraging the SDK Power Manager. In this application, the code is running in SRAM partition 16 (0x2010 0000) with a size of 256kB (0x40000) and stored in Octal flash using FlexSPI0.
105
106![iMXRT500 memory used](images/memory_example.png "iMXRT500 memory used")
107
108The first step defines the resources the user wants to keep ON/retain for a given low-power state. Each resource-constraint definition can be found in the file *fsl_pm_device.h*.
109
110`#define PM_RESC_ACMP_ACTIVE PM_ENCODE_RESC(PM_RESOURCE_FULL_ON, kResc_ACMP)`
111`#define PM_RESC_PQ_SRAM_ACTIVE PM_ENCODE_RESC(PM_RESOURCE_FULL_ON, kResc_SRAM_PQ)`
112`#define PM_RESC_FLEXSPI0_SRAM_ACTIVE PM_ENCODE_RESC(PM_RESOURCE_FULL_ON, kResc_SRAM_FLEXSPI0)`
113`#define PM_RESC_FLEXSPI0_SRAM_RETENTION PM_ENCODE_RESC(PM_RESOURCE_PARTABLE_ON1, kResc_SRAM_FLEXSPI0)`
114<br/>
115
116For example, defining **PM_RESC_ACMP_ACTIVE** will keep the resource ACMP active for a low-power state, if it matches with the system pre-defined constraints.
117
118<br/>
119
120In this example, only the mandatory resources are kept ON for deep sleep that will be specified later as a power mode constraint, thus the declaration is as follow:
121`#define APP_DEEP_SLEEP_CONSTRAINTS        \`
122`2U, PM_RESC_SRAM16_256KB_RETENTION, PM_RESC_FLEXSPI0_SRAM_RETENTION`
123
124In deep sleep, only the defined SRAM partition and the FLEXSPI0 SRAM are retained, i.e., the memory is retained but not accessible. All the other resources are turned OFF.
125
126<br/>
127
128For sleep low-power state, the following resources are kept ON:
129`#define APP_SLEEP_CONSTRAINTS`
130`7U, PM_RESC_MAIN_CLK_ON, PM_RESC_SYSXTAL_ON, PM_RESC_LPOSC_ON, PM_RESC_SYSPLLLDO_ON,` `PM_RESC_SYSPLLANA_ON, PM_RESC_FLEXSPI0_SRAM_ACTIVE, \ PM_RESC_SRAM16_256KB_ACTIVE`
131
132<br/>
133
134In the application, the user must first create the PM handle:
135`PM_CreateHandle(&g_pmHndle);`
136
137<br/>
138
139The user can declare wakeup sources, first by calling the PM API, and then by declaring the wakeup-source parameter in the application. In this example, the button SW2 will be used as wakeup source.
140The user must call the PM API with the corresponding parameter:
141`PM_InitWakeupSource(&g_UserkeyWakeupSource, (uint32_t)PIN_INT0_IRQn, NULL, true);`
142
143<br/>
144
145And then the user defines the GPIO parameter using the MCUXpresso SDK driver APIs:
146`gpio_pin_config_t gpioPinConfigStruct;`
147
148`/* Set SW pin as GPIO input. */`
149`gpioPinConfigStruct.pinDirection = kGPIO_DigitalInput;`
150`GPIO_PinInit(APP_USER_WAKEUP_KEY_GPIO, APP_USER_WAKEUP_KEY_PORT,APP_USER_WAKEUP_KEY_PIN, &gpioPinConfigStruct);`
151
152`/* Configure the Input Mux block and connect the trigger source to PinInt channel. */`
153`INPUTMUX_Init(INPUTMUX);`
154`INPUTMUX_AttachSignal(INPUTMUX, kPINT_PinInt0, APP_USER_WAKEUP_KEY_INPUTMUX_SEL); /*`
155
156`Using channel 0. */`
157`INPUTMUX_Deinit(INPUTMUX); /* Turnoff clock to inputmux to save power. Clock is only needed to make changes */`
158
159`/* Configure the interrupt for SW pin. */`
160`PINT_Init(PINT);`
161`PINT_PinInterruptConfig(PINT, kPINT_PinInt0, kPINT_PinIntEnableFallEdge,pint_intr_callback);`
162`PINT_EnableCallback(PINT); /* Enable callbacks for PINT */`
163
164<br/>
165
166Then, the user must set the defined constraints, with the following functions:
167`PM_SetConstraints(PM_LP_STATE_DEEP_SLEEP, APP_DEEP_SLEEP_CONSTRAINTS);`
168
169There is two types of constraints that can be set:
170- Constraints on the low power mode,
171- Constraints on the resources.
172
173For example:
174`PM_SetConstraints(PM_LP_STATE_NO_CONSTRAINT, APP_DEEP_SLEEP_CONSTRAINTS);`
175
176The Power Manager will find the deepest power state that satisfies the resources constraints in *APP_DEEP_SLEEP_CONSTRAINTS.*
177
178<br/>
179
180`PM_SetConstraints(PM_LP_STATE_DEEP_SLEEP, APP_DEEP_SLEEP_CONSTRAINTS);`
181
182Here, a constraint is set on the low power mode, and on the resources. The Power Manager will check if the resource constraints matches with the ones pre-defined for the low power mode. If there is an incompatibility, the Power Manager will find a lighter low power mode that satisfies the resource constraints set by the user. In the other case in that example, deep sleep mode will be reached with resources specified in *APP_DEEP_SLEEP_CONSTRAINTS* will be ON.
183
184<br/>
185
186`PM_SetConstraints(PM_LP_STATE_DEEP_SLEEP, 0);`
187
188Here, only a low power mode constraint is set, without resources constraints. Thus the Power Manager will turn everything off in this state, except the pre-defined resources constraints for this low power mode. This case is rarely used, as resources are often always requiring as RAM retention to properly wakeup the device in sleep and deep sleep. For lower low power states where a reset is required, this type of constraint can be used.
189Constraints on the low power mode are priority, i.e. if there is two constraints on the low power, the Power Manager will selects the lighter one.
190
191<br/>
192
193The user can enable the SDK Power Manager framework and enter the low-power mode.
194`PM_EnablePowerManager(true);`
195
196<br/>
197
198To enter in a low power mode, the following Power Manager function must be used:
199`PM_EnterLowPower(durationTicks);`
200
201The *durationTicks* parameter can be useful and leveraged when an exit latency is declared for a low-power state. It will influence the low-power state entered if the specified duration is less than the exit latency of the low-power state.
202
203The exit latency is declared by the developer for a low-power state. For example if the deep-sleep state has an exit latency of 250us, the declaration is as follow in *fsl_pm_device.c*:
204
205`/* Deep Sleep */`
206&emsp;&emsp;`{`
207&emsp;&emsp;&emsp;`.exitHwLatency = 250U, /* 250 us */`
208&emsp;&emsp;&emsp;`.fixConstraintsMask =`
209&emsp;&emsp;&emsp;&emsp;`{`
210&emsp;&emsp;&emsp;&emsp;&emsp;`.rescMask[0U] = 0x00000000UL,`
211&emsp;&emsp;&emsp;&emsp;&emsp;`.rescMask[1U] = 0x00000000UL,`
212&emsp;&emsp;&emsp;&emsp;&emsp;`.rescMask[2U] = 0x0UL,`
213&emsp;&emsp;&emsp;&emsp;`},`
214&emsp;&emsp;&emsp;`.varConstraintsMask =`
215&emsp;&emsp;&emsp;&emsp;`{`
216&emsp;&emsp;&emsp;&emsp;&emsp;`.rescMask[0U] = 0xFFFFFFFFUL,`
217&emsp;&emsp;&emsp;&emsp;&emsp;`.rescMask[1U] = 0xFFFFFFFFUL,`
218&emsp;&emsp;&emsp;&emsp;&emsp;`.rescMask[2U] = 0x3UL,`
219&emsp;&emsp;&emsp;&emsp;`},`
220
221When the Power Manager tries to find the deepest state reachable, it will compare the exit latency of the low power state *exitHwLatency* with the duration tick specified by the user. In that case, if *durationTicks* variable is less or equal to 250 us, then the deep sleep state is unreachable, even if the resources constraints matches. A lighter low power state will be reach satisfying resources constraints and *durationTicks*.
222
223<br/>
224
225The user can set constraints on resources and low power mode, following the same mechanism, for sleep state for example:
226`PM_SetConstraints(PM_LP_STATE_SLEEP, APP_SLEEP_CONSTRAINTS);`
227
228By having two low power mode constraints, i.e sleep and deep-sleep, the Power Manager will go into the lightest low power mode. In this case, as there is not exit latency for the sleep state, sleep state will be reached. The resources constraints to keep will be the sum of the previous ones with the new defined, i.e *APP_DEEP_SLEEP_CONSTRAINTS + APP_SLEEP_CONSTRAINTS*.
229
230<br/>
231
232To unset resource constraint and/or low power mode constraint, the following function must be used:
233`PM_ReleaseConstraints(PM_LP_STATE _SLEEP, APP_DEEP_SLEEP_CONSTRAINTS);`
234
235Here, the sleep state is not registered anymore in the Power Manager, thus deep sleep state will be reached with the corresponding constraints, if the *durationTicks* exceeds the exit latency of the deep sleep state. The *APP_DEEP_SLEEP_CONSTRAINTS* resources constraints are also unregistered, thus the resources constraints to keep are *APP_SLEEP_CONSTRAINTS*.
236
237<br/>
238
239**Note:** If a low power mode constraint or resource constraints has been set multiple times through *PM_SetConstraints*, one should call the *PM_ReleaseConstraints* function as many time as required to fully remove the constraint from the SDK Power Manager. This behavior can be useful in the case where multiple peripherals sets a constraint in a low power mode for example.
240
241<br/>
242
243Finally, when the Power Manager is not required anymore in the application, it must be disabled with:
244` PM_EnablePowerManager(false);`
245
246<br/>
247
248## 5. APIs references <a id="apiref"></a>
249
250<br/>
251
252**void PM_CreateHandle (pm_handle_t *  handle)**
253Initialize the power manager handle, this function should be invoked before using other power manager APIs.
254
255*Note:* By default, the power manager is disabled.
256
257*Parameter:* handle : Pointer to the pm_handle_t structure, upper layer software should pre-allocate the handle global variable.
258
259<br/>
260
261**void PM_EnablePowerManager (bool  enable)**
262Enable/disable power manager functions.
263
264*Parameter:* enable : Used to enable/disable power manager functions.
265
266<br/>
267
268**void PM_EnterLowPower (uint64_t  duration)**
269Power manager core API, this API should be used on RTOS's IDLE task.
270This function contains several steps:
2711. Compute target power state based on the policy module.
2722. Notify upper layer software of the power mode transitions.
2733. Enter into targeted power state.
2744. Exit from low power state, if wakeup event occurred.
2755. Notify upper layer software of the power mode exiting.
276
277The target power state is determined based on two factors: a. The input parameter should be larger than state's exitHwLatency attribution. b. resConstraintsMask logical AND state's lossFeature should equal to 0, because constraint can be understood as some features cannot loss.
278
279*Parameter:* duration : The time in low power mode, this value is calculated from RTOS API.
280
281<br/>
282
283**void PM_RegisterTimerController (pm_handle_t *  handle, pm_low_power_timer_start_func_t  timerStart, pm_low_power_timer_stop_func_t  timerStop, pm_low_power_timer_get_timestamp_func_t  getTimestamp, pm_low_power_timer_get_duration_func_t getTimerDuration)**
284Register timer controller related functions to power manager.
285If low power timer is the wakeup source, please remember to register it into power manager by using PM_EnableWakeupSource () function.
286
287*Parameters:*
288handle : Pointer to the pm_handle_t structure.
289timerStart : Low power timer start function, this parameter can be NULL, and it means low power timer is not set as the wakeup source.
290timerStop  : Low power timer stop function, this parameter can also be set as NULL.
291getTimestamp : Low power timestamp function, this parameter can also be set as NULL.
292getTimerDuration : Get timer duration function. this parameter can also be set as NULL.
293
294<br/>
295
296**uint64_t PM_GetLastLowPowerDuration(void)**
297Get the actual low power state duration.
298
299<br/>
300
301**void PM_RegisterCriticalRegionController (pm_handle_t *  handle, pm_enter_critical  criticalEntry, pm_exit_critical  criticalExit)**
302Register critical region related functions to power manager.
303
304*Note:* There are multiple-methods to implement critical region(E.g. interrupt controller, locker, semaphore).
305
306*Parameters:*
307handle : Pointer to the pm_handle_t structure.
308criticalEntry : Enter critical function to register.
309criticalExit : Exit critical function to register.
310
311<br/>
312
313**status_t PM_RegisterNotify (pm_notify_group_t  groupId, const pm_notify_element_t *  notifyElement)**
314Register notify element into the selected group.
315
316*Parameters:*
317groupId : The group of the notify list, this will affect the execution sequence.
318notifyElement : The pointer to pm_notify_element_t.
319
320*Returns:* status_t The status of register notify object behavior.
321
322<br/>
323
324**void PM_UpdateNotify (void *  notifyElement, pm_notify_callback_func_t  callback, void *  data)**
325Update notify element's callback function and application data.
326
327*Parameters:*
328notifyElement : The pointer to the notify element to update.
329callback : The callback function to be updated.
330data : Pointer to the callback function private data.
331
332<br/>
333
334**status_t PM_UnregisterNotify (void *  notifyElement)**
335Remove notify element from its notify group.
336
337*Parameter:* notifyElement : The pointer to the notify element to remove.
338
339<br/>
340
341**void PM_InitWakeupSource (pm_wakeup_source_t *  ws, uint32_t  wsId, pm_wake_up_source_service_func_t  service, bool  enable)**
342Initialize the wakeup source object.
343
344*Parameters:*
345ws : Pointer to the pm_wakeup_source_t variable.
346wsId : Used to select the wakeup source, the wsId of each wakeup source can be found in fsl_pm_device.h or device description file.
347service : The function to be invoked when wake up source asserted.
348enable : Used to enable/disable the selected wakeup source.
349
350<br/>
351
352**status_t PM_EnableWakeupSource (pm_wakeup_source_t *  ws)**
353Enable wakeup source.
354
355*Parameter:* ws : Pointer to the wakeup source object to be enabled.
356
357*Returns:* status_t The status of enable wakeup source behavior.
358
359<br/>
360
361**status_t PM_DisableWakeupSource (pm_wakeup_source_t *  ws)**
362Disable wakeup source.
363
364*Parameter:* ws : Pointer to the wakeup source object to be disabled.
365
366*Returns:* status_t The status of disable wakeup source behavior.
367
368<br/>
369
370**status_t PM_HandleWakeUpEvent (void)**
371Checks if any enabled wake up source is responsible for last wake up event. In such case, it will call the wake-up source callback if it has been registered. Likely to be called from Wake-Up Unit IRQ Handler.
372
373*Returns:* status_t The status of handling the wake-up event.
374
375<br/>
376
377**status_t PM_TriggerWakeSourceService (pm_wakeup_source_t *  ws)**
378If the specific wakeup event occurs, invoke this API to execute its service function.
379
380*Parameter:* ws : Pointer to the wakeup source object.
381
382*Returns:* status_t The status of trigger wakeup source behavior.
383
384<br/>
385
386**status_t PM_SetConstraints (uint8_t  powerModeConstraint, int32_t  rescNum,   ...)**
387Used to set constraints(including power mode constraint and resource constraints)
388For example, if the device support 3 resource constraints: PM_RESC_1, PM_RESC_2, PM_RESC3. PM_SetConstraints(Sleep_Mode, 3, PM_RESC_1, PM_RESC_2, PM_RESC_3);
389
390*Parameters:*
391powerModeConstraint : The lowest power mode allowed, the power mode constraint macros can be found in fsl_pm_device.h.
392rescNum : The number of resource constraints to be set.
393
394*Returns:* status_t The status of set constraints behavior.
395
396<br/>
397
398**status_t PM_ReleaseConstraints (uint8_t  powerModeConstraint, int32_t  rescNum,   ...)**
399Used to release constraints(including power mode constraint and resource constraints)
400For example, if the device support 3 resource constraints: PM_RESC_1, PM_RESC_2, PM_RESC3. PM_ReleaseConstraints(Sleep_Mode, 1, PM_RESC_1);
401
402*Parameters:*
403powerModeConstraint : The lowest power mode allowed, the power mode constraint macros can be found in fsl_pm_device.h.
404rescNum : The number of resource constraints to be released.
405
406*Returns:* status_t The status of set constraints behavior.
407
408<br/>
409
410**pm_resc_mask_t PM_GetResourceConstraintsMask (void)**
411Get current system resource constraints.
412
413*Returns:* Current system constraints.
414
415<br/>
416
417**uint8_t PM_GetAllowedLowestPowerMode (void)**
418Get current system allowed power mode.
419
420*Returns:* Allowed lowest power mode.
421
422<br/>
423
424## 6. Conclusion <a id="conclusion"></a>
425
426<br/>
427
428The Power Manager is a great option to reduce power consumption in low power states by managing all the resources seemlessly for the user. By abstracting the overall power architecture and providing easy-to-use APIs/macros, this framework speedup the time-to-market and application development.
429