ESP 低功耗参数配置

[English]

引言

本文档介绍了在 ESP-IDF 环境下如何配置以优化 ESP 系列芯片的功耗,在保证功能与性能的同时有效降低系统能耗。

系统低功耗优化配置

本节将首先从纯系统角度介绍,不涉及具体工作场景的低功耗模式。

动态调频(DFS)

CPU 工作的频率越高,功耗消耗也越大。通过 DFS,系统可以根据运行状态自动切换 CPU 工作频率,在负载较高时运行于高频、空闲时降低频率,从而在性能与功耗之间取得平衡。

配置步骤如下:

  1. 使能 CONFIG_PM_DFS_INIT_AUTO

  2. 配置 DFS

备注

在包含 Wi-Fi 应用的自动调频场景中,需注意以下限制:

  • 最小频率不低于 40 MHz,否则 CPU 处理能力将显著下降,且低功耗优化效果有限;

  • 最大频率不低于 80 MHz,否则 Wi-Fi RF 模块将无法正常工作。

备注

  • 在开启了自动调频后,一些外设的通信会因频率变化受到影响,具体说明见 动态调频和外设驱动

  • 若希望在保持低功耗的同时使用 LEDC 和 UART,可参考以下方法:

    • 如果希望在自动睡眠时使用 UART 中断,建议使用 GPIO 唤醒。

    • 如果硬件上搭载了 外部 32 KHz 晶振,建议将外设时钟切换为该晶振。

    • 在通信期间可使用锁机制禁用动态调频,具体操作可参考 低功耗 LEDC 开发指南

自动 Light sleep

自动 Light sleep 模式下,CPU 会在空闲时周期性暂停运行并进入 Light Sleep,Wi-Fi / BLE 的射频及相关基带模块在非通信窗口进入低功耗状态,仅在需要维持连接(如接收 Beacon、广播或进行数据收发)时被唤醒。

配置步骤如下:

  1. 配置唤醒源(详见 睡眠模式

  2. 使能 动态调频(DFS)

  3. 使能 CONFIG_FREERTOS_USE_TICKLESS_IDLE

  4. 设置 light_sleep_enable = true,具体如下:

esp_pm_config_t pm_config = {
.max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ,
.min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ,
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
.light_sleep_enable = true
#endif
};
ESP_ERROR_CHECK(esp_pm_configure(&pm_config));

此外,在启用自动 Light sleep 后,还可通过调整以下配置项,进一步降低休眠阶段的系统功耗。但不同配置在功耗、功能可用性以及系统资源占用之间存在一定取舍,需根据具体应用场景和需求进行选择与组合。

调整间隔时间

可通过调整以下配置项,进一步缩短系统进入 Light sleep 的间隔时间。

通过提高 CONFIG_FREERTOS_HZ,系统能够以更高的时间分辨率检测空闲状态。例如将其配置为 1000 时,每个 Tick 为 1 ms,在 CONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP = 3 的情况下,若系统预测未来约 3 ms 内不会有任务或定时事件需要处理,即可进入 Light sleep,从而进一步降低功耗。

隔离 GPIO

系统在休眠过程中,GPIO 漏电会产生额外电流损耗,增加功耗。

在 ESP-IDF 中,可通过使能 CONFIG_PM_SLP_DISABLE_GPIO 禁止 GPIO 内部上下拉电阻并隔离管脚输入输出,从而消除漏电流,降低休眠功耗。

打开该选项后,系统在进入休眠状态时会禁用所有 GPIO 管脚,以消除 GPIO 漏电对休眠功耗的影响,从而获得更低的休眠电流。但同时,该选项也导致了所有 GPIO 在休眠过程中将无法进行信号输入、输出以及内部上下拉配置。

启用该功能后,所有 GPIO 在休眠期间将无法进行信号输入、输出或内部上下拉配置。因此,对于在系统休眠过程中仍需使用 GPIO(如输入检测、输出控制或保持上下拉状态)的应用,ESP-IDF 提供了一组 API,即使启用了该选项,仍然可以在休眠期间对指定 GPIO 进行单独配置或恢复使用。相关接口如下:

  • 设置休眠状态下的 GPIO 输入输出状态:

    esp_err_t gpio_sleep_set_direction(gpio_num_t  gpio_num, gpio_mode_t  mode);
    
  • 设置休眠状态下的 GPIO 上下拉状态:

    esp_err_t gpio_sleep_set_pull_mode(gpio_num_t  gpio_num, gpio_pull_mode_t  pull);
    
  • 使能自动 GPIO 状态切换:

    esp_err_t gpio_sleep_sel_en(gpio_num_t gpio_num);
    
  • 禁止自动 GPIO 状态切换:

    esp_err_t gpio_sleep_sel_dis(gpio_num_t gpio_num);
    

如果希望在休眠期间保持 GPIO 电平状态,例如在需要持续控制指示灯、保持开关闭合状态的应用场景下,可以在进入休眠前对相关 GPIO 调用:

gpio_hold_en(gpio_num_t gpio_num)

在系统唤醒后,再调用:

gpio_hold_dis(gpio_num_t gpio_num)

Flash 断电

ESP32 系列芯片通过外接 Flash 和 PSRAM 来增大系统存储器资源。Flash 具有掉电后数据不丢失特性,PSRAM 掉电后数据无法保持。

当系统中 没有使用到 PSRAM 时,可以使能 Flash 断电功能来降低芯片休眠电流,但该行为存在一定风险,具体说明及相关配置项请参考 Flash 断电

CPU 断电

备注

该优化项在 ESP32, ESP32-C2 和 ESP32-S2 芯片上无法使用。

使能 CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP 可以在休眠模式下对 CPU 断电,以进一步降低休眠功耗。例如,对于 ESP32-C3,休眠电流可减少约 100 μA;对于 ESP32-S3,休眠电流可减少约 650 μA。

然而,断电会导致 CPU 的执行上下文(包括专用、通用以及状态寄存器等)丢失,若不处理,唤醒后 CPU 将无法正常执行。因此,系统将在断电前备份上下文信息,并在唤醒后从恢复该信息,这一步骤将消耗系统存储器资源,例如对于 ESP32-C3,将消耗 1.6 KB 的 DRAM 空间,对于 ESP32-S3,将消耗 8.58 KB 的 DRAM 空间。

外围设备下电

备注

该优化项仅适用于 ESP32-C6 及其后续系列芯片,包括 ESP32-C6, ESP32-H2, ESP32-C5(ECO3之后版本), ESP32-C61。

使能 CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP 后,数字外设将在 Light sleep 模式下尝试断电,可以将底电流降低约 100 μA。

需要注意的是,当外设电源域在睡眠期间断电时,IO_MUXGPIO 模块都将处于下电状态,芯片引脚状态不再受这些模块控制。因此,如果希望在休眠期间保持 IO 状态,需要在配置 GPIO 状态前后调用 gpio_hold_dis()gpio_hold_en(),以确保 IO 配置被锁存,防止 IO 在睡眠期间浮空。

此外,该配置项还存在较多限制,例如使能后无法使用 GPIO 和 UART 作为唤醒源,更多限制请参考 配置项说明,请根据实际应用谨慎使用。

Wi-Fi/低功耗蓝牙优化

乐鑫芯片为无线 MCU,因此大部分时候,低功耗功能都需配合 Wi-Fi/蓝牙功能一起使用。PHY 作为 Wi-Fi 与蓝牙通信的物理层,负责射频信号的收发。

下文将针对 Wi-Fi、BLE、PHY 相关的低功耗配置展开说明。

PHY 低功耗优化项

无线数字电路掉电

在使能 自动 Light sleep 后,可通过使能 CONFIG_ESP_PHY_MAC_BB_PD,让无线数字电路模块在关闭物理层时也相应掉电,大约能节省 100 μA 左右的底电流。

降低 TX power

使能 CONFIG_ESP_PHY_REDUCE_TX_POWER 后,当检测到系统电压不稳定或电源电压不足,ESP32 内置的电源管理模块自动触发复位时(欠压复位),将减小 PHY TX power,使代码能继续运行。

蓝牙低功耗优化项

BLE Modem sleep

使能 CONFIG_BTDM_CTRL_MODEM_SLEEP 后,在 BLE 保活阶段,即 BLE 保持连接但短时间内没有数据传输的状态时,系统会自动将 RF 模块进入 Modem Sleep 模式;一旦有数据需要发送或接收,射频模块会自动唤醒,从而在空闲期间实现低功耗且保证连接可靠性。

如果希望在保活时进入 Light sleep 而不是 Modem sleep,可参考 自动 Light sleep 的做法。

可以通过配置 BLE 使用的低功耗时钟源来优化功耗,在搭载了 外部 32 KHz 晶振 的情况下,推荐使用 32 kHz 晶振作为休眠时钟,以获得最低的 Light Sleep 底电流。

在 4.4 及之后的 IDF 版本里,蓝牙已支持用主晶振作为休眠时钟,不使用 32 kHz 晶振的代价是 Light sleep 时底电流会上升。参考电流:

  • ESP32-C3: 2.3 mA

  • ESP32-S3: 3.3 mA

Nimble – BLE only

在 BLE only 的场景下,启用 CONFIG_BT_NIMBLE_ENABLED 可以减少内存占用和协议栈处理开销,使 CPU 更易进入低功耗模式,从而降低整体功耗。

但需要注意,启用该配置项后,只能使用 NimBLE 协议栈 进行开发,无法使用 Bluedroid 协议栈

广播/连接模式设置

BLE 的功耗可以通过调整广播、扫描和连接模式下的关键配置参数来优化。

广播模式 下,可以通过调整以下参数优化功耗:

  • 广播间隔:增大广播间隔可以延长设备空闲时间,减少唤醒次数,从而降低平均功耗,但响应延迟将增加。其配置方法如下:

    • 基于 Bluedroid 协议栈:配置 esp_ble_adv_params_t 结构体时,增大 .adv_int_min.adv_int_max,以增大广播间隔;

    • 基于 Nimble 协议栈:配置 ble_gap_adv_params 结构体时,增大 .itvl_min.itvl_max,以增大广播间隔。

  • 广播包大小:广播包越小,每次的发射时间和电流消耗越小。广播数据包内含有的信息可参考 广播数据包结构

    • 基于 Bluedroid 协议栈:定义 esp_ble_adv_data_t 结构体时,只保留必要字段,例如设备名称,去掉可选字段,例如制造商数据和服务数据;

    • 基于 Nimble 协议栈:定义 ble_hs_adv_fields 结构体时,只保留必要字段,去掉可选字段。

  • 发射功率:降低发射功率,减少每次发送广播包时的功耗,但覆盖范围会缩小。

    • 调用 esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, level) 调整发射功率,对于不同芯片,level 的取值可能有所不同,具体请参考对应芯片的 esp_bt.h 文件。

连接模式 下,可以通过调整以下参数优化功耗:

  • 连接间隔:增大连接间隔可以延长设备空闲时间,减少唤醒次数,从而降低平均功耗,但响应延迟将增加。其配置方法如下:

    • 基于 Bluedroid 协议栈:配置 esp_ble_conn_update_params_t 结构体时,增大 .interval,以增大连接间隔;

    • 基于 Nimble 协议栈:配置 ble_gap_upd_params 结构体时,增大 .itvl_min.itvl_max,以增大连接间隔。

  • 从机延迟:增大允许从机跳过的连接事件数量,可以延长休眠时间,进一步降低功耗。

    • 基于 Bluedroid 协议栈:配置 esp_ble_conn_update_params_t 结构体时,增大 .latency,以增大从机延迟;

    • 基于 Nimble 协议栈:配置 ble_gap_upd_params 结构体时,增大 .latency,以增大从机延迟。

  • 连接监督超时:当 BLE 连接在设置的连接监督超时时间内未收到对方响应时,将被判定为断开。合理设置超时时间可以避免因断线重连导致的额外唤醒和能量消耗。

    • 基于 Bluedroid 协议栈:配置 esp_ble_conn_update_params_t 结构体时,增大 .timeout,以增大连接监督超时时间;

    • 基于 Nimble 协议栈:配置 ble_gap_upd_params 结构体时,增大 .supervision_timeout,以增大连接监督超时时间。

  • 发射功率:降低发射功率,减少每次发送广播包时的功耗,但覆盖范围会缩小。

    • 调用 esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, level) 调整发射功率,对于不同芯片,level 的取值可能有所不同,具体请参考对应芯片的 esp_bt.h 文件。

扫描模式 下,可以通过调整以下参数优化功耗:

  • 扫描窗口与扫描间隔:减小扫描窗口或扩大扫描间隔,将缩短射频部分的开启时间,以降低平均功耗;当扫描窗口和扫描间隔相等时,为连续扫描,功耗最高,但发现设备最快。

    • 基于 Bluedroid 协议栈:配置 esp_ble_scan_params_t 结构体时,增大 .scan_interval 或减小 .scan_window,以降低平均功耗;

    • 基于 Nimble 协议栈:配置 ble_gap_disc_params 结构体时,增大 .itvl 或减小 .window,以降低平均功耗。

  • 主动扫描/被动扫描:被动扫描模式仅接收广播包,功耗最低;主动扫描模式会发送 Scan Request 并接收 Scan Response,信息更完整,但功耗更高。在不需要获取完整广播数据时,优先使用被动扫描。

    • 基于 Bluedroid 协议栈:通过 esp_ble_scan_params_t 结构体中的 .scan_type 配置,设置为 BLE_SCAN_TYPE_PASSIVE 代表被动扫描,设置为 BLE_SCAN_TYPE_ACTIVE 代表主动扫描。

    • 基于 Nimble 协议栈:通过 ble_gap_disc_params 结构体中的 .passive 配置,设置为 1 代表被动扫描,设置为 0 代表主动扫描。

  • 扫描持续时间:通过应用层逻辑控制扫描的启停,避免长时间连续扫描,可显著降低平均功耗。

    • 基于 Bluedroid 协议栈:可通过 esp_ble_gap_start_scanning(duration) 设置扫描持续时间,也可将 duration 设置为 0,并在发现目标设备后调用 esp_ble_gap_stop_scanning() 立即停止扫描。

    • 基于 Nimble 协议栈:通过 ble_gap_disc()ble_gap_ext_disc()duration 参数控制。

  • 重复过滤:启用后,控制器会过滤重复的广播报告,减少 Host 侧处理和唤醒次数,间接降低系统功耗。

    • 基于 Bluedroid 协议栈:通过 esp_ble_ext_scan_params_t 结构体中的 .scan_duplicate 配置,具体可参考 扫描重复过滤说明

    • 基于 Nimble 协议栈:通过 ble_gap_disc_params 结构体中的 .filter_duplicates 配置,设置为 1 代表过滤重复广播,设置为 0 代表不过滤(每个广播都上报)。

  • 扫描过滤策略:可设置为仅扫描指定设备,以减少无关广播带来的处理开销,适合已知目标设备地址的场景。

    • 基于 Bluedroid 协议栈:通过 esp_ble_scan_params_t 结构体中的 .scan_filter_policy 配置,具体可参考 过滤策略说明

    • 基于 Nimble 协议栈:通过 ble_gap_disc_param 结构体中的 .filter_policy 配置,设置为 0 代表使用默认策略。

  • 扫描时 TX 功率影响说明:扫描本身主要是 RX 行为,TX 功率对功耗影响较小;仅在主动扫描发送 Scan Request 时才涉及发射功率。一般无需单独为扫描模式调整 TX 功率,除非对链路可靠性有特殊要求。

Wi-Fi 低功耗优化项

Wi-Fi 优化涉及的配置项较多,以下仅列出部分通用配置项,更多说明请参考 Wi-Fi 场景下低功耗模式介绍

Wi-Fi Modem sleep

对于 Wi-Fi,该模式只能应用于 STA 模式,可调用 esp_err_t esp_wifi_set_ps(wifi_ps_type_t type) 开启或选择启用状态:

  • type = WIFI_PS_NONE,关闭 Modem sleep 模式,此时 RF 会一直处于打开状态。

  • type = WIFI_PS_MIN_MODEM,芯片每隔一个 DTIM 会和路由器进行一次交互,交互结束后暂时关闭 RF,然后在下一个 DTIM 再醒来。

  • type = WIFI_PS_MAX_MODEM,芯片每隔一个 listen interval 会和路由器进行一次交互,交互结束后暂时关闭 RF,然后在下一个 listen interval 醒来。

备注

DTIM 和 listen interval 的区别可参考 此处

在 ESP32 系列芯片中,Wi-Fi Modem sleep 模式是默认打开的,其默认值为 WIFI_PS_MIN_MODEM

进一步说明请参考 Modem-sleep 模式配置

更改最小等待时间和最大保活时间

最小等待时间

当 ESP32 作为 STA 和 AP 进行通信时,启用 Modem-sleep 后,STA 在接收完一次数据后不会立即关闭 RF,而是会保持一段最短活动时间,这段时间称为 Minimum active time,默认值为 50 ms。在保证每次数据吞吐量的基础上,可以通过调整 CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME 适当减少这个等待时间,从而降低功耗。

最大保活时间

当 ESP32 处于 power save 模式时,需要周期性地向 AP 发送一个 keep alive 包来告诉 AP 自己仍保持连接。Maximum keep alive time 即是发送这个 keep alive 包的时间周期,默认为 10 s。可以通过调整 CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME 增大该时间间隔以减少发包,从而降低功耗。

推荐配置

  • Minimum active time = 15~20

  • Maximum keep alive time = 60

开启断连电源管理

使能 CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE 后,即使 Wi-Fi STA 断开连接,Wi-Fi 模块仍可保持在 Modem-sleep 模式,从而降低断连期间的功耗。

开启 Beacon lost 优化

备注

该优化项仅适用于 ESP-IDF v4.4 及以上版本。

Wi-Fi 保活的一个基础是能够定时接收到路由器发送的 Beacon 包。在实际使用环境中,因各种原因会导致 Beacon 丢失。

在 release/v4.4 之前的版本中,丢失 Beacon 后 ESP32 会保持 RF 继续开启,直到接收到下一个 Beacon。

v4.4 以后的版本可通过使能 CONFIG_ESP_WIFI_SLP_Beacon_LOST_OPT 以开启 Beacon lost 优化,避免这一行为对功耗造成的影响。

如下图所示,优化原理是在丢失 Beacon 时不会一直开着 RF 接收,而是开一段时间没接收到就进入睡眠模式,然后再起来收包,重复几次后如果还没收到,才会和常规操作一样开着 RF 直到接收到位置。这样可大大提高未接收到 Beacon 时的容错率,从而减少功耗。

图 2-6-1 Beacon lost 优化示意图

Beacon lost 优化示意图-1

图 2-6-2 Beacon lost 优化示意图

Beacon lost 优化示意图-2

开启此选项后会引出额外配置项,主要需要关注:

设置最大 Wi-Fi TX power

使能 CONFIG_ESP_PHY_MAX_WIFI_TX_POWER 后,可限制 Wi-Fi 的最大发射功率,从而降低发送过程中的瞬时电流和平均功耗;在信号条件良好的场景下,可有效减少能耗并提升系统稳定性,但会缩小通信距离并可能影响链路可靠性,应根据实际使用环境进行权衡配置。

在代码中,可通过调用 esp_wifi_set_max_tx_power() 进行设置。

优化 Wi-Fi 执行速度

将部分 Wi-Fi 相关内容放入 IRAM 中,可以提升 Wi-Fi 执行速度。此操作可以缩短 RF 和 CPU 的活跃时间,使系统能够更早进入 Modem sleep 或 Light sleep 模式,从而降低整体平均功耗。

相关配置项如下:

Wi-Fi 物理层收包

备注

该优化项仅适用于 ESP32-C6, ESP32-C5, ESP32-C61 芯片。且目前该功能无法与 外围设备下电 同时使用。

使能 CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP 后,在 Light sleep 期间,PHY 层自动收包,Wi-Fi 接收 Beacon 不再需要 CPU 参与,只有 Wi-Fi MAC + Baseband + RF 工作,以节省功耗。

为了更直观地展示各模块在不同模式下的工作状态,可通过 不同 mode 下接收发射波形图 观察 CPU、MAC、Baseband 和 RF 的活动差异。

补充内容

DTIM 和 listen interval 的区别

当芯片作为 STA 和路由器建立连接的时候,会被告知路由器的 DTIM,即每隔多少时间路由器会发送一个 beacon,STA 需要在这个时间起来接收 beacon,查看是否有需要自己处理的信息。

而 listen interval 则是 STA 告诉路由,我需要隔多少时间起来接受 beacon,即前者是根据路由端来定的,后者是可以自己配置到芯片里的。时间间隔为 DTIM 或者 listen interval 的值 * 100 MS,如果当 DTIM=10,即每次唤醒的时间间隔为 10 * 100 ms = 1 s。

外部 32 KHz 晶振

使用外部 32 KHz 晶振可以获得更低的功耗。主要有以下几个原因:

  • 内部的晶振容易受到干扰,相比之下外接晶振的精度更高,并可以在各种睡眠情况下使用。

  • 对于时间精度要求比较高的应用,如蓝牙和 Wi-Fi 的保活,需要定时起来接受 Beacon,一旦时钟漂移过大,错过了接收的点,会导致打开 RF 等待的窗口期变长,从而大大增加功耗。

外部晶振有两种:

  • External 32kHz crystal: 为外部无源晶振,也是大部分时候推荐的晶振

  • External 32kHz oscillator at 32K_XP pin: 为外部有源晶振,价格更贵,同时会造成底电流上升 50 ~ 100 μA

使能外部时钟源需要如下配置:

图 3-1 使能外部晶振

使能外部晶振

  • 配置项名称: ESP32C3_RTC_CLK_SRC_EXT_CRYS

  • 配置路径: (Top) Component config ESP32XX-Specific RTC clock source

备注

ESP32-C2 内部没有无源晶振的起振电路,只支持外部有源晶振;晶振的布局可以参考各芯片对应的硬件设计指南。

不同 mode 下接收发射波形图

Modem Mode(物理层收 Beacon): 一次收包时间开销为 2.1 ms 左右,收包电流为 64 mA ~ 70 mA 左右。

图 3-3-1 Modem Mode

Active Mode RX: 一次收包时长 5.3 ms 左右,收包电流 80 mA 左右。

图 3-3-2 Active Mode RX

RX 没收到包: 对比没收到包的情况,不会有持续一段时间电流的波形。

图 3-3-3 RX 没收到包

Active Mode TX: 持续时间不定,TX 电流与 Wi-Fi 信道相关。

图 3-3-4 Active Mode TX