feat(example): implement power management example for ESP chips

This commit is contained in:
wuzhenghui
2026-04-03 19:18:03 +08:00
parent 4eb97bb84d
commit f4eca3c42f
25 changed files with 891 additions and 1 deletions

View File

@@ -130,6 +130,11 @@ These functions are particularly useful for:
To enable profiling features (timing information for individual locks), enable the :ref:`CONFIG_PM_PROFILING` option in menuconfig.
Application Example
-------------------
The :example:`lowpower/power_management` example demonstrates dynamic frequency scaling, automatic Light-sleep, and power management locks.
Dynamic Frequency Scaling and Peripheral Drivers
------------------------------------------------

View File

@@ -130,6 +130,11 @@ ESP-IDF 使用预测性时间补偿机制来实现自动 Light-sleep。系统会
要启用性能分析功能(单个锁的计时信息),请在 menuconfig 中启用 :ref:`CONFIG_PM_PROFILING` 选项。
应用示例
-------------------
:example:`lowpower/power_management` 示例演示了动态调频、自动 Light-sleep 与电源管理锁。
动态调频和外设驱动
------------------------------------------------

View File

@@ -1,5 +1,14 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
examples/lowpower/power_management:
disable:
- if: CONFIG_NAME == "pd_top" and SOC_PM_SUPPORT_TOP_PD != 1
- if: SOC_PM_SUPPORTED != 1
temporary: true
reason: not supported yet # TODO: [ESP32H21] IDF-11522, [ESP32H4] IDF-12286 [ESP32S31] IDF-14645
depends_components:
- esp_pm
examples/lowpower/vbat:
enable:
- if: SOC_VBAT_SUPPORTED == 1

View File

@@ -1,7 +1,7 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
# System Examples
# Low Power Examples
Configuration and management of ESP chips lowpower related features.

View File

@@ -0,0 +1,8 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.22)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
idf_build_set_property(MINIMAL_BUILD ON)
project(power_management_example)

View File

@@ -0,0 +1,66 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
# Power Management Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example demonstrates power management (PM) locks with multiple tasks: one task holds `ESP_PM_CPU_FREQ_MAX` during a short critical section, another holds `ESP_PM_NO_LIGHT_SLEEP` during a short awake window, and a third task periodically dumps PM config and lock/mode stats. Locks are used only where needed so the system can lower CPU frequency or enter light sleep the rest of the time.
## How to Use Example
### Hardware Required
Any supported ESP development board.
### Configure the Project
Run `idf.py menuconfig`. Under **Example Configuration** you can set:
- **Max CPU frequency (MHz)** — CPU frequency when ESP_PM_CPU_FREQ_MAX PM lock is held.
- **Min CPU frequency (MHz)** — CPU frequency when no PM lock is held.
- **Enable automatic light sleep when idle** — When enabled (and tickless idle is enabled), the chip may enter light sleep when no PM lock is held. Default is on if tickless idle is enabled.
Enable PM under **Component config → Power Management → Support for power management**. The example uses `sdkconfig.defaults` to set `CONFIG_PM_ENABLE` and `CONFIG_FREERTOS_USE_TICKLESS_IDLE`. PM is not supported with SMP FreeRTOS; the example sets `CONFIG_FREERTOS_SMP=n`.
### Build and Flash
Build the project, flash it to the board, and run the serial monitor:
```
idf.py -p PORT flash monitor
```
(Replace PORT with your serial port. Exit monitor with `Ctrl-]`.)
## Example Output
At startup the example prints the PM config. The **pm_dump** task then prints PM config and lock/mode stats every 10 seconds; the two demo tasks do not log.
```
=== Power Management Example (multi-task) ===
I (319) pm: Frequency switching config: CPU_MAX: 400, APB_MAX: 100, APB_MIN: 40, Light sleep: ENABLED
PM configured: max=400 min=40 MHz, light_sleep_enable=1
I (330) main_task: Returned from app_main()
--- PM: max_freq=400 min_freq=40 MHz, light_sleep=1 ---
Time since boot up: 10044534 us
Lock stats:
Name Type Arg Active Total_count Time(us) Time(%)
background NO_LIGHT_SLEEP 0 0 20 2998011 30 %
critical_work CPU_FREQ_MAX 0 1 21 1000507 10 %
rtos1 CPU_FREQ_MAX 0 1 4087 141343 2 %
rtos0 CPU_FREQ_MAX 0 0 4076 184970 2 %
Mode stats:
Mode CPU_freq Time(us) Time(%)
SLEEP 40 M 5958343 59%
APB_MIN 40 M 2848902 28%
APB_MAX 100M 0 0 %
CPU_MAX 400M 1205696 11%
Sleep stats:
light_sleep_counts:40 light_sleep_reject_counts:0
```
The same block repeats every 10 seconds.

View File

@@ -0,0 +1,6 @@
set(srcs "power_management_example_main.c")
set(includes ".")
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES esp_pm
INCLUDE_DIRS ${includes})

View File

@@ -0,0 +1,51 @@
choice EXAMPLE_PM_MAX_FREQ_MHZ
prompt "Max CPU frequency (MHz)"
default EXAMPLE_PM_MAX_FREQ_MHZ_240
config EXAMPLE_PM_MAX_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MAX_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MAX_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MAX_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MAX_FREQ_MHZ_160
bool "160"
config EXAMPLE_PM_MAX_FREQ_MHZ_240
bool "240"
endchoice
config EXAMPLE_PM_MAX_FREQ
int
default 10 if EXAMPLE_PM_MAX_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MAX_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MAX_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MAX_FREQ_MHZ_80
default 160 if EXAMPLE_PM_MAX_FREQ_MHZ_160
default 240 if EXAMPLE_PM_MAX_FREQ_MHZ_240
choice EXAMPLE_PM_MIN_FREQ_MHZ
prompt "Min CPU frequency (MHz)"
default EXAMPLE_PM_MIN_FREQ_MHZ_40
config EXAMPLE_PM_MIN_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MIN_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MIN_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MIN_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MIN_FREQ_MHZ_160
bool "160"
config EXAMPLE_PM_MIN_FREQ_MHZ_240
bool "240"
endchoice
config EXAMPLE_PM_MIN_FREQ
int
default 10 if EXAMPLE_PM_MIN_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MIN_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MIN_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MIN_FREQ_MHZ_80
default 160 if EXAMPLE_PM_MIN_FREQ_MHZ_160
default 240 if EXAMPLE_PM_MIN_FREQ_MHZ_240

View File

@@ -0,0 +1,45 @@
choice EXAMPLE_PM_MAX_FREQ_MHZ
prompt "Max CPU frequency (MHz)"
default EXAMPLE_PM_MAX_FREQ_MHZ_120
config EXAMPLE_PM_MAX_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MAX_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MAX_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MAX_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MAX_FREQ_MHZ_120
bool "120"
endchoice
config EXAMPLE_PM_MAX_FREQ
int
default 10 if EXAMPLE_PM_MAX_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MAX_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MAX_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MAX_FREQ_MHZ_80
default 120 if EXAMPLE_PM_MAX_FREQ_MHZ_120
choice EXAMPLE_PM_MIN_FREQ_MHZ
prompt "Min CPU frequency (MHz)"
default EXAMPLE_PM_MIN_FREQ_MHZ_40
config EXAMPLE_PM_MIN_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MIN_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MIN_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MIN_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MIN_FREQ_MHZ_120
bool "120"
endchoice
config EXAMPLE_PM_MIN_FREQ
int
default 10 if EXAMPLE_PM_MIN_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MIN_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MIN_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MIN_FREQ_MHZ_80
default 120 if EXAMPLE_PM_MIN_FREQ_MHZ_120

View File

@@ -0,0 +1,45 @@
choice EXAMPLE_PM_MAX_FREQ_MHZ
prompt "Max CPU frequency (MHz)"
default EXAMPLE_PM_MAX_FREQ_MHZ_160
config EXAMPLE_PM_MAX_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MAX_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MAX_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MAX_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MAX_FREQ_MHZ_160
bool "160"
endchoice
config EXAMPLE_PM_MAX_FREQ
int
default 10 if EXAMPLE_PM_MAX_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MAX_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MAX_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MAX_FREQ_MHZ_80
default 160 if EXAMPLE_PM_MAX_FREQ_MHZ_160
choice EXAMPLE_PM_MIN_FREQ_MHZ
prompt "Min CPU frequency (MHz)"
default EXAMPLE_PM_MIN_FREQ_MHZ_40
config EXAMPLE_PM_MIN_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MIN_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MIN_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MIN_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MIN_FREQ_MHZ_160
bool "160"
endchoice
config EXAMPLE_PM_MIN_FREQ
int
default 10 if EXAMPLE_PM_MIN_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MIN_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MIN_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MIN_FREQ_MHZ_80
default 160 if EXAMPLE_PM_MIN_FREQ_MHZ_160

View File

@@ -0,0 +1,57 @@
choice EXAMPLE_PM_MAX_FREQ_MHZ
prompt "Max CPU frequency (MHz)"
default EXAMPLE_PM_MAX_FREQ_MHZ_240
config EXAMPLE_PM_MAX_FREQ_MHZ_12
bool "12"
config EXAMPLE_PM_MAX_FREQ_MHZ_24
bool "24"
config EXAMPLE_PM_MAX_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MAX_FREQ_MHZ_48
bool "48"
config EXAMPLE_PM_MAX_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MAX_FREQ_MHZ_160
bool "160"
config EXAMPLE_PM_MAX_FREQ_MHZ_240
bool "240"
endchoice
config EXAMPLE_PM_MAX_FREQ
int
default 12 if EXAMPLE_PM_MAX_FREQ_MHZ_12
default 24 if EXAMPLE_PM_MAX_FREQ_MHZ_24
default 40 if EXAMPLE_PM_MAX_FREQ_MHZ_40
default 48 if EXAMPLE_PM_MAX_FREQ_MHZ_48
default 80 if EXAMPLE_PM_MAX_FREQ_MHZ_80
default 160 if EXAMPLE_PM_MAX_FREQ_MHZ_160
default 240 if EXAMPLE_PM_MAX_FREQ_MHZ_240
choice EXAMPLE_PM_MIN_FREQ_MHZ
prompt "Min CPU frequency (MHz)"
default EXAMPLE_PM_MIN_FREQ_MHZ_48
config EXAMPLE_PM_MIN_FREQ_MHZ_12
bool "12"
config EXAMPLE_PM_MIN_FREQ_MHZ_24
bool "24"
config EXAMPLE_PM_MIN_FREQ_MHZ_40
bool "40 (use with 40MHz XTAL)"
config EXAMPLE_PM_MIN_FREQ_MHZ_48
bool "48 (use with 48MHz XTAL)"
config EXAMPLE_PM_MIN_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MIN_FREQ_MHZ_160
bool "160"
config EXAMPLE_PM_MIN_FREQ_MHZ_240
bool "240"
endchoice
config EXAMPLE_PM_MIN_FREQ
int
default 12 if EXAMPLE_PM_MIN_FREQ_MHZ_12
default 24 if EXAMPLE_PM_MIN_FREQ_MHZ_24
default 40 if EXAMPLE_PM_MIN_FREQ_MHZ_40
default 48 if EXAMPLE_PM_MIN_FREQ_MHZ_48
default 80 if EXAMPLE_PM_MIN_FREQ_MHZ_80
default 160 if EXAMPLE_PM_MIN_FREQ_MHZ_160
default 240 if EXAMPLE_PM_MIN_FREQ_MHZ_240

View File

@@ -0,0 +1,51 @@
choice EXAMPLE_PM_MAX_FREQ_MHZ
prompt "Max CPU frequency (MHz)"
default EXAMPLE_PM_MAX_FREQ_MHZ_160
config EXAMPLE_PM_MAX_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MAX_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MAX_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MAX_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MAX_FREQ_MHZ_120
bool "120"
config EXAMPLE_PM_MAX_FREQ_MHZ_160
bool "160"
endchoice
config EXAMPLE_PM_MAX_FREQ
int
default 10 if EXAMPLE_PM_MAX_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MAX_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MAX_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MAX_FREQ_MHZ_80
default 120 if EXAMPLE_PM_MAX_FREQ_MHZ_120
default 160 if EXAMPLE_PM_MAX_FREQ_MHZ_160
choice EXAMPLE_PM_MIN_FREQ_MHZ
prompt "Min CPU frequency (MHz)"
default EXAMPLE_PM_MIN_FREQ_MHZ_40
config EXAMPLE_PM_MIN_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MIN_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MIN_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MIN_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MIN_FREQ_MHZ_120
bool "120"
config EXAMPLE_PM_MIN_FREQ_MHZ_160
bool "160"
endchoice
config EXAMPLE_PM_MIN_FREQ
int
default 10 if EXAMPLE_PM_MIN_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MIN_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MIN_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MIN_FREQ_MHZ_80
default 120 if EXAMPLE_PM_MIN_FREQ_MHZ_120
default 160 if EXAMPLE_PM_MIN_FREQ_MHZ_160

View File

@@ -0,0 +1,45 @@
choice EXAMPLE_PM_MAX_FREQ_MHZ
prompt "Max CPU frequency (MHz)"
default EXAMPLE_PM_MAX_FREQ_MHZ_160
config EXAMPLE_PM_MAX_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MAX_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MAX_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MAX_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MAX_FREQ_MHZ_160
bool "160"
endchoice
config EXAMPLE_PM_MAX_FREQ
int
default 10 if EXAMPLE_PM_MAX_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MAX_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MAX_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MAX_FREQ_MHZ_80
default 160 if EXAMPLE_PM_MAX_FREQ_MHZ_160
choice EXAMPLE_PM_MIN_FREQ_MHZ
prompt "Min CPU frequency (MHz)"
default EXAMPLE_PM_MIN_FREQ_MHZ_40
config EXAMPLE_PM_MIN_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MIN_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MIN_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MIN_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MIN_FREQ_MHZ_160
bool "160"
endchoice
config EXAMPLE_PM_MIN_FREQ
int
default 10 if EXAMPLE_PM_MIN_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MIN_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MIN_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MIN_FREQ_MHZ_80
default 160 if EXAMPLE_PM_MIN_FREQ_MHZ_160

View File

@@ -0,0 +1,51 @@
choice EXAMPLE_PM_MAX_FREQ_MHZ
prompt "Max CPU frequency (MHz)"
default EXAMPLE_PM_MAX_FREQ_MHZ_96
config EXAMPLE_PM_MAX_FREQ_MHZ_8
bool "8"
config EXAMPLE_PM_MAX_FREQ_MHZ_16
bool "16"
config EXAMPLE_PM_MAX_FREQ_MHZ_32
bool "32"
config EXAMPLE_PM_MAX_FREQ_MHZ_48
bool "48"
config EXAMPLE_PM_MAX_FREQ_MHZ_64
bool "64"
config EXAMPLE_PM_MAX_FREQ_MHZ_96
bool "96"
endchoice
config EXAMPLE_PM_MAX_FREQ
int
default 8 if EXAMPLE_PM_MAX_FREQ_MHZ_8
default 16 if EXAMPLE_PM_MAX_FREQ_MHZ_16
default 32 if EXAMPLE_PM_MAX_FREQ_MHZ_32
default 48 if EXAMPLE_PM_MAX_FREQ_MHZ_48
default 64 if EXAMPLE_PM_MAX_FREQ_MHZ_64
default 96 if EXAMPLE_PM_MAX_FREQ_MHZ_96
choice EXAMPLE_PM_MIN_FREQ_MHZ
prompt "Min CPU frequency (MHz)"
default EXAMPLE_PM_MIN_FREQ_MHZ_32
config EXAMPLE_PM_MIN_FREQ_MHZ_8
bool "8"
config EXAMPLE_PM_MIN_FREQ_MHZ_16
bool "16"
config EXAMPLE_PM_MIN_FREQ_MHZ_32
bool "32"
config EXAMPLE_PM_MIN_FREQ_MHZ_48
bool "48"
config EXAMPLE_PM_MIN_FREQ_MHZ_64
bool "64"
config EXAMPLE_PM_MIN_FREQ_MHZ_96
bool "96"
endchoice
config EXAMPLE_PM_MIN_FREQ
int
default 8 if EXAMPLE_PM_MIN_FREQ_MHZ_8
default 16 if EXAMPLE_PM_MIN_FREQ_MHZ_16
default 32 if EXAMPLE_PM_MIN_FREQ_MHZ_32
default 48 if EXAMPLE_PM_MIN_FREQ_MHZ_48
default 64 if EXAMPLE_PM_MIN_FREQ_MHZ_64
default 96 if EXAMPLE_PM_MIN_FREQ_MHZ_96

View File

@@ -0,0 +1,45 @@
choice EXAMPLE_PM_MAX_FREQ_MHZ
prompt "Max CPU frequency (MHz)"
default EXAMPLE_PM_MAX_FREQ_MHZ_96
config EXAMPLE_PM_MAX_FREQ_MHZ_8
bool "8"
config EXAMPLE_PM_MAX_FREQ_MHZ_16
bool "16"
config EXAMPLE_PM_MAX_FREQ_MHZ_32
bool "32"
config EXAMPLE_PM_MAX_FREQ_MHZ_48
bool "48"
config EXAMPLE_PM_MAX_FREQ_MHZ_96
bool "96"
endchoice
config EXAMPLE_PM_MAX_FREQ
int
default 8 if EXAMPLE_PM_MAX_FREQ_MHZ_8
default 16 if EXAMPLE_PM_MAX_FREQ_MHZ_16
default 32 if EXAMPLE_PM_MAX_FREQ_MHZ_32
default 48 if EXAMPLE_PM_MAX_FREQ_MHZ_48
default 96 if EXAMPLE_PM_MAX_FREQ_MHZ_96
choice EXAMPLE_PM_MIN_FREQ_MHZ
prompt "Min CPU frequency (MHz)"
default EXAMPLE_PM_MIN_FREQ_MHZ_32
config EXAMPLE_PM_MIN_FREQ_MHZ_8
bool "8"
config EXAMPLE_PM_MIN_FREQ_MHZ_16
bool "16"
config EXAMPLE_PM_MIN_FREQ_MHZ_32
bool "32"
config EXAMPLE_PM_MIN_FREQ_MHZ_48
bool "48"
config EXAMPLE_PM_MIN_FREQ_MHZ_96
bool "96"
endchoice
config EXAMPLE_PM_MIN_FREQ
int
default 8 if EXAMPLE_PM_MIN_FREQ_MHZ_8
default 16 if EXAMPLE_PM_MIN_FREQ_MHZ_16
default 32 if EXAMPLE_PM_MIN_FREQ_MHZ_32
default 48 if EXAMPLE_PM_MIN_FREQ_MHZ_48
default 96 if EXAMPLE_PM_MIN_FREQ_MHZ_96

View File

@@ -0,0 +1,53 @@
# ESP32-H4: 8, 16, 32, 48, 64, 96
choice EXAMPLE_PM_MAX_FREQ_MHZ
prompt "Max CPU frequency (MHz)"
default EXAMPLE_PM_MAX_FREQ_MHZ_96
config EXAMPLE_PM_MAX_FREQ_MHZ_8
bool "8"
config EXAMPLE_PM_MAX_FREQ_MHZ_16
bool "16"
config EXAMPLE_PM_MAX_FREQ_MHZ_32
bool "32"
config EXAMPLE_PM_MAX_FREQ_MHZ_48
bool "48"
config EXAMPLE_PM_MAX_FREQ_MHZ_64
bool "64"
config EXAMPLE_PM_MAX_FREQ_MHZ_96
bool "96"
endchoice
config EXAMPLE_PM_MAX_FREQ
int
default 8 if EXAMPLE_PM_MAX_FREQ_MHZ_8
default 16 if EXAMPLE_PM_MAX_FREQ_MHZ_16
default 32 if EXAMPLE_PM_MAX_FREQ_MHZ_32
default 48 if EXAMPLE_PM_MAX_FREQ_MHZ_48
default 64 if EXAMPLE_PM_MAX_FREQ_MHZ_64
default 96 if EXAMPLE_PM_MAX_FREQ_MHZ_96
choice EXAMPLE_PM_MIN_FREQ_MHZ
prompt "Min CPU frequency (MHz)"
default EXAMPLE_PM_MIN_FREQ_MHZ_32
config EXAMPLE_PM_MIN_FREQ_MHZ_8
bool "8"
config EXAMPLE_PM_MIN_FREQ_MHZ_16
bool "16"
config EXAMPLE_PM_MIN_FREQ_MHZ_32
bool "32"
config EXAMPLE_PM_MIN_FREQ_MHZ_48
bool "48"
config EXAMPLE_PM_MIN_FREQ_MHZ_64
bool "64"
config EXAMPLE_PM_MIN_FREQ_MHZ_96
bool "96"
endchoice
config EXAMPLE_PM_MIN_FREQ
int
default 8 if EXAMPLE_PM_MIN_FREQ_MHZ_8
default 16 if EXAMPLE_PM_MIN_FREQ_MHZ_16
default 32 if EXAMPLE_PM_MIN_FREQ_MHZ_32
default 48 if EXAMPLE_PM_MIN_FREQ_MHZ_48
default 64 if EXAMPLE_PM_MIN_FREQ_MHZ_64
default 96 if EXAMPLE_PM_MIN_FREQ_MHZ_96

View File

@@ -0,0 +1,82 @@
choice EXAMPLE_PM_MAX_FREQ_MHZ
prompt "Max CPU frequency (MHz)"
default EXAMPLE_PM_MAX_FREQ_MHZ_360 if ESP32P4_SELECTS_REV_LESS_V3
default EXAMPLE_PM_MAX_FREQ_MHZ_400 if !ESP32P4_SELECTS_REV_LESS_V3
config EXAMPLE_PM_MAX_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MAX_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MAX_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MAX_FREQ_MHZ_90
bool "90"
depends on ESP32P4_SELECTS_REV_LESS_V3
config EXAMPLE_PM_MAX_FREQ_MHZ_100
bool "100"
depends on !ESP32P4_SELECTS_REV_LESS_V3
config EXAMPLE_PM_MAX_FREQ_MHZ_180
bool "180"
depends on ESP32P4_SELECTS_REV_LESS_V3
config EXAMPLE_PM_MAX_FREQ_MHZ_200
bool "200"
depends on !ESP32P4_SELECTS_REV_LESS_V3
config EXAMPLE_PM_MAX_FREQ_MHZ_360
bool "360"
depends on ESP32P4_SELECTS_REV_LESS_V3
config EXAMPLE_PM_MAX_FREQ_MHZ_400
bool "400"
depends on !ESP32P4_SELECTS_REV_LESS_V3
endchoice
config EXAMPLE_PM_MAX_FREQ
int
default 10 if EXAMPLE_PM_MAX_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MAX_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MAX_FREQ_MHZ_40
default 90 if EXAMPLE_PM_MAX_FREQ_MHZ_90
default 100 if EXAMPLE_PM_MAX_FREQ_MHZ_100
default 180 if EXAMPLE_PM_MAX_FREQ_MHZ_180
default 200 if EXAMPLE_PM_MAX_FREQ_MHZ_200
default 360 if EXAMPLE_PM_MAX_FREQ_MHZ_360
default 400 if EXAMPLE_PM_MAX_FREQ_MHZ_400
choice EXAMPLE_PM_MIN_FREQ_MHZ
prompt "Min CPU frequency (MHz)"
default EXAMPLE_PM_MIN_FREQ_MHZ_40
config EXAMPLE_PM_MIN_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MIN_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MIN_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MIN_FREQ_MHZ_90
bool "90"
depends on ESP32P4_SELECTS_REV_LESS_V3
config EXAMPLE_PM_MIN_FREQ_MHZ_100
bool "100"
depends on !ESP32P4_SELECTS_REV_LESS_V3
config EXAMPLE_PM_MIN_FREQ_MHZ_180
bool "180"
depends on ESP32P4_SELECTS_REV_LESS_V3
config EXAMPLE_PM_MIN_FREQ_MHZ_200
bool "200"
depends on !ESP32P4_SELECTS_REV_LESS_V3
config EXAMPLE_PM_MIN_FREQ_MHZ_360
bool "360"
depends on ESP32P4_SELECTS_REV_LESS_V3
config EXAMPLE_PM_MIN_FREQ_MHZ_400
bool "400"
depends on !ESP32P4_SELECTS_REV_LESS_V3
endchoice
config EXAMPLE_PM_MIN_FREQ
int
default 10 if EXAMPLE_PM_MIN_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MIN_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MIN_FREQ_MHZ_40
default 90 if EXAMPLE_PM_MIN_FREQ_MHZ_90
default 100 if EXAMPLE_PM_MIN_FREQ_MHZ_100
default 180 if EXAMPLE_PM_MIN_FREQ_MHZ_180
default 200 if EXAMPLE_PM_MIN_FREQ_MHZ_200
default 360 if EXAMPLE_PM_MIN_FREQ_MHZ_360
default 400 if EXAMPLE_PM_MIN_FREQ_MHZ_400

View File

@@ -0,0 +1,51 @@
choice EXAMPLE_PM_MAX_FREQ_MHZ
prompt "Max CPU frequency (MHz)"
default EXAMPLE_PM_MAX_FREQ_MHZ_240
config EXAMPLE_PM_MAX_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MAX_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MAX_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MAX_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MAX_FREQ_MHZ_160
bool "160"
config EXAMPLE_PM_MAX_FREQ_MHZ_240
bool "240"
endchoice
config EXAMPLE_PM_MAX_FREQ
int
default 10 if EXAMPLE_PM_MAX_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MAX_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MAX_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MAX_FREQ_MHZ_80
default 160 if EXAMPLE_PM_MAX_FREQ_MHZ_160
default 240 if EXAMPLE_PM_MAX_FREQ_MHZ_240
choice EXAMPLE_PM_MIN_FREQ_MHZ
prompt "Min CPU frequency (MHz)"
default EXAMPLE_PM_MIN_FREQ_MHZ_40
config EXAMPLE_PM_MIN_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MIN_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MIN_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MIN_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MIN_FREQ_MHZ_160
bool "160"
config EXAMPLE_PM_MIN_FREQ_MHZ_240
bool "240"
endchoice
config EXAMPLE_PM_MIN_FREQ
int
default 10 if EXAMPLE_PM_MIN_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MIN_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MIN_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MIN_FREQ_MHZ_80
default 160 if EXAMPLE_PM_MIN_FREQ_MHZ_160
default 240 if EXAMPLE_PM_MIN_FREQ_MHZ_240

View File

@@ -0,0 +1,51 @@
choice EXAMPLE_PM_MAX_FREQ_MHZ
prompt "Max CPU frequency (MHz)"
default EXAMPLE_PM_MAX_FREQ_MHZ_240
config EXAMPLE_PM_MAX_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MAX_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MAX_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MAX_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MAX_FREQ_MHZ_160
bool "160"
config EXAMPLE_PM_MAX_FREQ_MHZ_240
bool "240"
endchoice
config EXAMPLE_PM_MAX_FREQ
int
default 10 if EXAMPLE_PM_MAX_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MAX_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MAX_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MAX_FREQ_MHZ_80
default 160 if EXAMPLE_PM_MAX_FREQ_MHZ_160
default 240 if EXAMPLE_PM_MAX_FREQ_MHZ_240
choice EXAMPLE_PM_MIN_FREQ_MHZ
prompt "Min CPU frequency (MHz)"
default EXAMPLE_PM_MIN_FREQ_MHZ_40
config EXAMPLE_PM_MIN_FREQ_MHZ_10
bool "10"
config EXAMPLE_PM_MIN_FREQ_MHZ_20
bool "20"
config EXAMPLE_PM_MIN_FREQ_MHZ_40
bool "40"
config EXAMPLE_PM_MIN_FREQ_MHZ_80
bool "80"
config EXAMPLE_PM_MIN_FREQ_MHZ_160
bool "160"
config EXAMPLE_PM_MIN_FREQ_MHZ_240
bool "240"
endchoice
config EXAMPLE_PM_MIN_FREQ
int
default 10 if EXAMPLE_PM_MIN_FREQ_MHZ_10
default 20 if EXAMPLE_PM_MIN_FREQ_MHZ_20
default 40 if EXAMPLE_PM_MIN_FREQ_MHZ_40
default 80 if EXAMPLE_PM_MIN_FREQ_MHZ_80
default 160 if EXAMPLE_PM_MIN_FREQ_MHZ_160
default 240 if EXAMPLE_PM_MIN_FREQ_MHZ_240

View File

@@ -0,0 +1,17 @@
# PM frequency options: one file per target (see test_freqs[] in
# components/esp_pm/test_apps/esp_pm/main/test_pm.c)
menu "Example Configuration"
orsource "Kconfig.$IDF_TARGET.supported_freq"
config EXAMPLE_PM_LIGHT_SLEEP_ENABLE
bool "Enable automatic light sleep when idle"
default y if FREERTOS_USE_TICKLESS_IDLE
default n
help
When enabled (and tickless idle is enabled), the chip may enter light
sleep when no PM lock prevents it. Effective only if Component config
-> FreeRTOS -> Tickless idle support is enabled.
endmenu

View File

@@ -0,0 +1,81 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_pm.h"
#include "sdkconfig.h"
#define DEMO_PERIOD_MS 1000
#define NESTED_HOLD_MS 200
#define NESTED_ACTIVE_MS (3 * NESTED_HOLD_MS)
#define NESTED_IDLE_MS (DEMO_PERIOD_MS - NESTED_ACTIVE_MS)
#define PM_DUMP_INTERVAL_MS 10000
static void task_demo_nested_locks(void *arg)
{
(void)arg;
esp_pm_lock_handle_t lock_no_ls;
esp_pm_lock_handle_t lock_apb;
esp_pm_lock_handle_t lock_cpu;
ESP_ERROR_CHECK(esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "demo_no_ls", &lock_no_ls));
ESP_ERROR_CHECK(esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "demo_apb", &lock_apb));
ESP_ERROR_CHECK(esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "demo_cpu", &lock_cpu));
while (1) {
ESP_ERROR_CHECK(esp_pm_lock_acquire(lock_no_ls));
// CPU working at min_freq_mhz, but not enter Light-sleep mode to
// maintain the ability to respond to interruptions
vTaskDelay(pdMS_TO_TICKS(NESTED_HOLD_MS));
ESP_ERROR_CHECK(esp_pm_lock_acquire(lock_apb));
// CPU working at the frequency of the maximum APB frequency supported
// by the SOC, to keep peripherals working at a high frequency.
vTaskDelay(pdMS_TO_TICKS(NESTED_HOLD_MS));
ESP_ERROR_CHECK(esp_pm_lock_acquire(lock_cpu));
// CPU working at max_freq_mhz, to achieve best performance.
vTaskDelay(pdMS_TO_TICKS(NESTED_HOLD_MS));
ESP_ERROR_CHECK(esp_pm_lock_release(lock_cpu));
ESP_ERROR_CHECK(esp_pm_lock_release(lock_apb));
ESP_ERROR_CHECK(esp_pm_lock_release(lock_no_ls));
// If light_sleep_enable is true, the system will enter Light-sleep mode.
// Otherwise, the CPU stays at min_freq_mhz in IDLE.
vTaskDelay(pdMS_TO_TICKS(NESTED_IDLE_MS));
}
}
/* Print PM config and lock/mode stats every 10s */
static void task_pm_dump(void *arg)
{
(void)arg;
vTaskDelay(pdMS_TO_TICKS(PM_DUMP_INTERVAL_MS));
while (1) {
esp_pm_config_t cfg;
if (esp_pm_get_configuration(&cfg) == ESP_OK) {
printf("\n--- PM: max_freq=%d min_freq=%d MHz, light_sleep=%d ---\n",
cfg.max_freq_mhz, cfg.min_freq_mhz, cfg.light_sleep_enable ? 1 : 0);
}
esp_pm_dump_locks(stdout);
vTaskDelay(pdMS_TO_TICKS(PM_DUMP_INTERVAL_MS));
}
}
void app_main(void)
{
printf("\n=== Power Management Example (nested locks, single task) ===\n");
esp_pm_config_t pm_config = {
.max_freq_mhz = CONFIG_EXAMPLE_PM_MAX_FREQ,
.min_freq_mhz = CONFIG_EXAMPLE_PM_MIN_FREQ,
.light_sleep_enable = CONFIG_EXAMPLE_PM_LIGHT_SLEEP_ENABLE,
};
ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
printf("PM configured: max=%d min=%d MHz, light_sleep_enable=%d\n",
pm_config.max_freq_mhz, pm_config.min_freq_mhz, pm_config.light_sleep_enable ? 1 : 0);
xTaskCreate(task_demo_nested_locks, "demo_pm", 2048, NULL, 3, NULL);
xTaskCreate(task_pm_dump, "pm_dump", 2048, NULL, 0, NULL);
}

View File

@@ -0,0 +1,58 @@
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import re
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
LOCK_PCT_TOL = 5
LOCK_EXPECT_PCT = {
'demo_no_ls': 60,
'demo_apb': 40,
'demo_cpu': 20,
}
def _parse_lock_stats(dut: Dut, timeout: int = 15) -> dict[str, int]:
dut.expect_exact('Lock stats:', timeout=timeout)
dut.expect(re.compile(rb'Name\s+Type\s+Arg\s+Active\s+Total_count\s+Time'), timeout=2)
lock_pct: dict[str, int] = {}
pattern = re.compile(rb'(demo_no_ls|demo_apb|demo_cpu)\s+\S+\s+\d+\s+\d+\s+\d+\s+\d+\s+(\d+)\s*%')
while len(lock_pct) < len(LOCK_EXPECT_PCT):
m = dut.expect(pattern, timeout=timeout)
lock_pct[m.group(1).decode()] = int(m.group(2))
return lock_pct
def _run_pm_example_test(dut: Dut) -> None:
dut.expect_exact('=== Power Management Example (nested locks, single task) ===', timeout=10)
dut.expect(re.compile(rb'--- PM: max_freq=\d+ min_freq=\d+ MHz, light_sleep=\d+ ---'), timeout=15)
lock_pct = _parse_lock_stats(dut, timeout=5)
for name, expected in LOCK_EXPECT_PCT.items():
pct = lock_pct[name]
assert (expected - LOCK_PCT_TOL) <= pct <= (expected + LOCK_PCT_TOL)
@pytest.mark.generic
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
def test_esp_pm_mode_stats(dut: Dut) -> None:
_run_pm_example_test(dut)
@pytest.mark.generic
@pytest.mark.parametrize('config', ['pd_top'], indirect=True)
@idf_parametrize('target', ['esp32c6', 'esp32c61', 'esp32h2', 'esp32p4'], indirect=['target'])
def test_esp_pm_mode_stats_pd_top(dut: Dut) -> None:
_run_pm_example_test(dut)
@pytest.mark.generic
@pytest.mark.esp32c5_eco3
@pytest.mark.parametrize('config', ['pd_top'], indirect=True)
@idf_parametrize('target', ['esp32c5'], indirect=['target'])
def test_esp_pm_mode_stats_pd_top_esp32c5_eco3(dut: Dut) -> None:
_run_pm_example_test(dut)

View File

@@ -0,0 +1 @@
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y

View File

@@ -0,0 +1,7 @@
# Enable power management (required for esp_pm component)
CONFIG_PM_ENABLE=y
CONFIG_PM_PROFILING=y
CONFIG_FREERTOS_HZ=1000
# Enable tickless idle so that automatic light sleep can be used when light_sleep_enable is true
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y