电源管理¶
概述¶
ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求,调整外围总线 (APB) 频率、CPU 频率,并使芯片进入 Light-sleep 模式,尽可能减少运行应用程序的功耗。
应用程序组件可以通过创建和获取电源管理锁来控制功耗。
例如:
- 对于从 APB 获得时钟频率的外设,其驱动可以要求在使用该外设时,将 APB 频率设置为 80 MHz。 
- RTOS 可以要求 CPU 在有任务准备开始运行时以最高配置频率工作。 
- 一些外设可能需要中断才能启用,因此其驱动也会要求禁用 Light-sleep 模式。 
因为请求较高的 APB 频率或 CPU 频率,以及禁用 Light-sleep 模式会增加功耗,请将组件使用的电源管理锁降到最少。
电源管理配置¶
编译时可使用 CONFIG_PM_ENABLE 选项启用电源管理功能。
启用电源管理功能将会增加中断延迟。额外延迟与多个因素有关,例如:CPU 频率、单/双核模式、是否需要进行频率切换等。CPU 频率为 240 MHz 且未启用频率调节时,最小额外延迟为 0.2 us;如果启用频率调节,且在中断入口将频率由 40 MHz 调节至 80 MHz,则最大额外延迟为 40 us。
应用程序可以通过调用 esp_pm_configure() 函数启用动态调频 (DFS) 功能和自动 Light-sleep 模式。此函数的参数为 esp_pm_config_esp32s2_t,定义了频率调节的相关设置。在此参数结构中,需要初始化下面三个字段:
- max_freq_mhz:最大 CPU 频率 (MHz),即获取- ESP_PM_CPU_FREQ_MAX锁后所使用的频率。该字段通常设置为 CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ。
- min_freq_mhz:最小 CPU 频率 (MHz),即仅获取- ESP_PM_APB_FREQ_MAX锁后所使用的频率。该字段可设置为晶振 (XTAL) 频率值,或者 XTAL 频率值除以整数。注意,10 MHz 是生成 1 MHz 的 REF_TICK 默认时钟所需的最小频率。
- light_sleep_enable:没有获取任何管理锁时,决定系统是否需要自动进入 Light-sleep 状态 (- true/- false)。
或者,如果在 menuconfig 中启用了 CONFIG_PM_DFS_INIT_AUTO 选项,最大 CPU 频率将由 CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ 设置决定,最小 CPU 频率将锁定为 XTAL 频率。
注解
- 自动 Light-sleep 模式基于 FreeRTOS Tickless Idle 功能,因此如果在 menuconfig 中没有启用 CONFIG_FREERTOS_USE_TICKLESS_IDLE 选项,在请求自动 Light-sleep 时, - esp_pm_configure()将会返回 ESP_ERR_NOT_SUPPORTED 错误。
- 在 Light-sleep 状态下,外设设有时钟门控,不会产生来自 GPIO 和内部外设的中断。Sleep Modes 文档中所提到的唤醒源可用于从 Light-sleep 状态触发唤醒。例如,EXT0 和 EXT1 唤醒源就可以通过 GPIO 唤醒芯片。 
电源管理锁¶
应用程序可以通过获取或释放管理锁来控制电源管理算法。应用程序获取电源管理锁后,电源管理算法的操作将受到下面的限制。释放电源管理锁后,限制解除。
电源管理锁设有获取/释放计数器,如果已多次获取电源管理锁,则需要将电源管理锁释放相同次数以解除限制。
ESP32-S2 支持下表中所述的三种电源管理锁。
| 电源管理锁 | 描述 | 
|---|---|
| 
 | 请求使用  | 
| 
 | 请求将 APB 频率设置为最大值,ESP32-S2 支持的最大频率为 80 MHz。 | 
| 
 | 禁止自动切换至 Light-sleep 模式。 | 
ESP32-S2 电源管理算法¶
下表列出了启用动态调频时如何切换 CPU 频率和 APB 频率。您可以使用 esp_pm_configure() 或者 CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ 指定 CPU 最大频率。
| CPU最高频率 | 电源管理锁获取情况 | APB 频率和 CPU 频率 | 
| 240 | 获取  | CPU: 240 MHz APB: 80 MHz | 
| 获取  ESP_PM_APB_FREQ_MAX,未获得  ESP_PM_CPU_FREQ_MAX | CPU: 80 MHz APB: 80 MHz | |
| 无 | 使用  | |
| 160 | 获取  | CPU: 160 MHz APB: 80 MHz | 
| 获取  ESP_PM_APB_FREQ_MAX,未获得  ESP_PM_CPU_FREQ_MAX | CPU: 80 MHz APB: 80 MHz | |
| 无 | 使用  | |
| 80 | 获取   ESP_PM_CPU_FREQ_MAX或  ESP_PM_APB_FREQ_MAX | CPU: 80 MHz APB: 80 MHz | 
| 无 | 使用  | 
如果没有获取任何管理锁,调用 esp_pm_configure() 将启动 Light-sleep 模式。 Light-sleep 模式持续时间由以下因素决定:
- 处于阻塞状态的 FreeRTOS 任务数(有限超时) 
- 高分辨率定时器 API 注册的计数器数量 
您也可以设置 Light-sleep 模式在最近事件(任务解除阻塞,或计时器超时)之前持续多久才唤醒芯片。
动态调频和外设驱动¶
启用动态调频后,APB 频率可在一个 RTOS 滴答周期内多次更改。有些外设不受 APB 频率变更的影响,但有些外设可能会出现问题。例如,Timer Group 外设定时器会继续计数,但定时器计数的速度将随 APB 频率的变更而变更。
下面的外设不受 APB 频率变更的影响:
- UART:如果 REF_TICK 用作时钟源,则 UART 不受 APB 频率变更影响。请查看 - uart_config_t中的 use_ref_tick。
- LEDC:如果 REF_TICK 用作时钟源,则 LEDC 不受 APB 频率变更影响。请查看 - ledc_timer_config()函数。
- RMT:如果 REF_TICK 用作时钟源,则 RMT 不受 APB 频率变更影响。请查看 - rmt_config_t结构体中的 flags 成员以及 RMT_CHANNEL_FLAGS_ALWAYS_ON 宏。
目前以下外设驱动程序可感知动态调频,并在调频期间使用 ESP_PM_APB_FREQ_MAX 锁:
- SPI master 
- I2C 
- I2S(如果 APLL 锁在使用中,I2S 则会启用 - ESP_PM_NO_LIGHT_SLEEP锁)
- SDMMC 
启用以下驱动程序时,将占用 ESP_PM_APB_FREQ_MAX 锁:
- SPI slave:从调用 - spi_slave_initialize()至- spi_slave_free()期间。
- Ethernet:从调用 - esp_eth_driver_install()至- esp_eth_driver_uninstall()期间。
- WiFi:从调用 - esp_wifi_start()至- esp_wifi_stop()期间。如果启用了调制解调器睡眠模式,广播关闭时将释放此管理锁。
- TWAI:从调用 - twai_driver_install()至- twai_driver_uninstall()期间。
以下外设驱动程序无法感知动态调频,应用程序需自己获取/释放管理锁:
- PCNT 
- Sigma-delta 
- Timer group 
API 参考¶
Header File¶
Functions¶
- 
esp_err_t esp_pm_configure(const void *config)¶
- Set implementation-specific power management configuration. - Return
- ESP_OK on success 
- ESP_ERR_INVALID_ARG if the configuration values are not correct 
- ESP_ERR_NOT_SUPPORTED if certain combination of values is not supported, or if CONFIG_PM_ENABLE is not enabled in sdkconfig 
 
- Parameters
- config: pointer to implementation-specific configuration structure (e.g. esp_pm_config_esp32)
 
 
- 
esp_err_t esp_pm_get_configuration(void *config)¶
- Get implementation-specific power management configuration. - Return
- ESP_OK on success 
- ESP_ERR_INVALID_ARG if the pointer is null 
 
- Parameters
- config: pointer to implementation-specific configuration structure (e.g. esp_pm_config_esp32)
 
 
- 
esp_err_t esp_pm_lock_create(esp_pm_lock_type_t lock_type, int arg, const char *name, esp_pm_lock_handle_t *out_handle)¶
- Initialize a lock handle for certain power management parameter. - When lock is created, initially it is not taken. Call esp_pm_lock_acquire to take the lock. - This function must not be called from an ISR. - Return
- ESP_OK on success 
- ESP_ERR_NO_MEM if the lock structure can not be allocated 
- ESP_ERR_INVALID_ARG if out_handle is NULL or type argument is not valid 
- ESP_ERR_NOT_SUPPORTED if CONFIG_PM_ENABLE is not enabled in sdkconfig 
 
- Parameters
- lock_type: Power management constraint which the lock should control
- arg: argument, value depends on lock_type, see esp_pm_lock_type_t
- name: arbitrary string identifying the lock (e.g. “wifi” or “spi”). Used by the esp_pm_dump_locks function to list existing locks. May be set to NULL. If not set to NULL, must point to a string which is valid for the lifetime of the lock.
- [out] out_handle: handle returned from this function. Use this handle when calling esp_pm_lock_delete, esp_pm_lock_acquire, esp_pm_lock_release. Must not be NULL.
 
 
- 
esp_err_t esp_pm_lock_acquire(esp_pm_lock_handle_t handle)¶
- Take a power management lock. - Once the lock is taken, power management algorithm will not switch to the mode specified in a call to esp_pm_lock_create, or any of the lower power modes (higher numeric values of ‘mode’). - The lock is recursive, in the sense that if esp_pm_lock_acquire is called a number of times, esp_pm_lock_release has to be called the same number of times in order to release the lock. - This function may be called from an ISR. - This function is not thread-safe w.r.t. calls to other esp_pm_lock_* functions for the same handle. - Return
- ESP_OK on success 
- ESP_ERR_INVALID_ARG if the handle is invalid 
- ESP_ERR_NOT_SUPPORTED if CONFIG_PM_ENABLE is not enabled in sdkconfig 
 
- Parameters
- handle: handle obtained from esp_pm_lock_create function
 
 
- 
esp_err_t esp_pm_lock_release(esp_pm_lock_handle_t handle)¶
- Release the lock taken using esp_pm_lock_acquire. - Call to this functions removes power management restrictions placed when taking the lock. - Locks are recursive, so if esp_pm_lock_acquire is called a number of times, esp_pm_lock_release has to be called the same number of times in order to actually release the lock. - This function may be called from an ISR. - This function is not thread-safe w.r.t. calls to other esp_pm_lock_* functions for the same handle. - Return
- ESP_OK on success 
- ESP_ERR_INVALID_ARG if the handle is invalid 
- ESP_ERR_INVALID_STATE if lock is not acquired 
- ESP_ERR_NOT_SUPPORTED if CONFIG_PM_ENABLE is not enabled in sdkconfig 
 
- Parameters
- handle: handle obtained from esp_pm_lock_create function
 
 
- 
esp_err_t esp_pm_lock_delete(esp_pm_lock_handle_t handle)¶
- Delete a lock created using esp_pm_lock. - The lock must be released before calling this function. - This function must not be called from an ISR. - Return
- ESP_OK on success 
- ESP_ERR_INVALID_ARG if the handle argument is NULL 
- ESP_ERR_INVALID_STATE if the lock is still acquired 
- ESP_ERR_NOT_SUPPORTED if CONFIG_PM_ENABLE is not enabled in sdkconfig 
 
- Parameters
- handle: handle obtained from esp_pm_lock_create function
 
 
- 
esp_err_t esp_pm_dump_locks(FILE *stream)¶
- Dump the list of all locks to stderr - This function dumps debugging information about locks created using esp_pm_lock_create to an output stream. - This function must not be called from an ISR. If esp_pm_lock_acquire/release are called while this function is running, inconsistent results may be reported. - Return
- ESP_OK on success 
- ESP_ERR_NOT_SUPPORTED if CONFIG_PM_ENABLE is not enabled in sdkconfig 
 
- Parameters
- stream: stream to print information to; use stdout or stderr to print to the console; use fmemopen/open_memstream to print to a string buffer.
 
 
Type Definitions¶
- 
typedef struct esp_pm_lock *esp_pm_lock_handle_t¶
- Opaque handle to the power management lock. 
Enumerations¶
- 
enum esp_pm_lock_type_t¶
- Power management constraints. - Values: - 
ESP_PM_CPU_FREQ_MAX¶
- Require CPU frequency to be at the maximum value set via esp_pm_configure. Argument is unused and should be set to 0. 
 - 
ESP_PM_APB_FREQ_MAX¶
- Require APB frequency to be at the maximum value supported by the chip. Argument is unused and should be set to 0. 
 - 
ESP_PM_NO_LIGHT_SLEEP¶
- Prevent the system from going into light sleep. Argument is unused and should be set to 0. 
 
-