Appearance
电源管理
ESP-IDF的集成电源管理可以根据程序组件的需求, 调节总线的频率, CPU的频率
CONFIG_PM_ENABLE 选项启用电源管理功能。
使用这一个进行调节CPU的频率会使得中断的响应时间增加
启用动态调频和自动 Light-sleep
c
esp_err_t esp_pm_configure(const void *config)
这一个里面需要设置三个函数
max_freq_mhz
:最大 CPU 频率 (MHz),即获取ESP_PM_CPU_FREQ_MAX
锁后所使用的频率。该字段通常设置为 CONFIG_ESP_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_ESP_DEFAULT_CPU_FREQ_MHZ 设置决定,最小 CPU 频率将锁定为 XTAL 频率(晶振的频率)。
ESP32的电源管理中,管理锁用于保护系统在深度睡眠模式下不被意外唤醒。当ESP32进入深度睡眠模式后,所有的外设和时钟都被关闭,只有管理模块处于工作状态。如果在此期间,外部信号或中断触发了某个外设,可能会导致系统被唤醒,从而影响功耗。因此,ESP32引入了管理锁的概念,当管理锁被锁定时,即使有外部触发,系统也不会被唤醒。只有当管理锁被解锁时,才会允许外部信号触发系统唤醒。这样可以有效地防止系统被意外唤醒,延长电池寿命。
自动 Light-sleep 模式基于 FreeRTOS Tickless Idle 功能,因此如果在 menuconfig 中没有启用 CONFIG_FREERTOS_USE_TICKLESS_IDLE 选项,在请求自动 Light-sleep 时,
esp_pm_configure()
将会返回 ESP_ERR_NOT_SUPPORTED 错误。If power management support is enabled, FreeRTOS will be able to put the system into light sleep mode when no tasks need to run for a number of ticks. This number can be set using FREERTOS_IDLE_TIME_BEFORE_SLEEP option. This feature is also known as "automatic light sleep".
可以使用这一个选项设置自动睡眠
CPU 最高频率 | 电源管理锁获取情况 | APB 频率和 CPU 频率 |
---|---|---|
240 | 获取 ESP_PM_CPU_FREQ_MAX 或 ESP_PM_APB_FREQ_MAX | CPU: 240 MHzAPB: 80 MHz |
无 | 使用 esp_pm_configure() 为二者设置最小值 | |
160 | 获取 ESP_PM_CPU_FREQ_MAX | CPU: 160 MHzAPB: 80 MHz |
获取 ESP_PM_APB_FREQ_MAX ,未获得 ESP_PM_CPU_FREQ_MAX | CPU: 80 MHzAPB: 80 MHz | |
无 | 使用 esp_pm_configure() 为二者设置最小值 | |
80 | 获取 ESP_PM_CPU_FREQ_MAX 或 ESP_PM_APB_FREQ_MAX | CPU: 80 MHzAPB: 80 MHz |
无 | 使用 esp_pm_configure() 为二者设置最小值 |
动态调频和外设驱动
使用动态调频的时候, APB的频率可以在一个RTOS的周期里面多次改变, 有的外设不受APB的频率影响, 有的可能会出现问题
Timer Group 外设定时器会继续计数,但定时器计数的速度将随 APB 频率的变更而变更。
时钟频率不受 APB 频率影响的外设时钟源通常有 REF_TICK
, XTAL
, RC_FAST
(i.e., RTC_8M
)。
目前以下外设驱动程序可感知动态调频,并在调频期间使用 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()
期间。 - GPTimer:从调用
gptimer_enable()
至gptimer_disable()
期间。 - Ethernet:从调用
esp_eth_driver_install()
至esp_eth_driver_uninstall()
期间。 - WiFi:从调用
esp_wifi_start()
至esp_wifi_stop()
期间。如果启用了调制解调器睡眠模式,广播关闭时将释放此管理锁。 - TWAI:从调用
twai_driver_install()
至twai_driver_uninstall()
期间 (只有在 TWAI 时钟源选择为TWAI_CLK_SRC_APB
的时候生效)。 - Bluetooth:从调用
esp_bt_controller_enable()
至esp_bt_controller_disable()
期间。如果启用了蓝牙调制解调器,广播关闭时将释放此管理锁。但依然占用ESP_PM_NO_LIGHT_SLEEP
锁,除非将 CONFIG_BTDM_CTRL_LOW_POWER_CLOCK 选项设置为 “外部 32 kHz 晶振”。
API
c
#include "esp_pm.h"
This header file is a part of the API provided by the
esp_pm
component. To declare that your component depends onesp_pm
, add the following to your CMakeLists.txt:REQUIRES esp_pm
PRIV_REQUIRES esp_pm
c
esp_err_t esp_pm_configure(const void *config)
配置函数, 使用这一个函数进行配置
c
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)
初始化句柄, 初始化的时候这一个句柄是没有获取的
- 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_handle -- [out] 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.
c
esp_err_t esp_pm_lock_acquire(esp_pm_lock_handle_t handle)
这一个锁被获取的时候会使用对应的电池管理算法, 这一个锁是一个递归的锁, 可以在中断里面使用
handle -- handle obtained from esp_pm_lock_create function
c
esp_err_t esp_pm_lock_release(esp_pm_lock_handle_t handle)
释放这一个锁
重启
c
void esp_restart(void)
重启
c
esp_err_t esp_register_shutdown_handler(shutdown_handler_t handle)
注册一个回调函数, 会在esp_restart函数执行的时候进行调用