ESP 低功耗参数配置

[English]

引言

Light Sleep 工作模式下,RF 模块会被关闭,除 RTC 相关模块外大多数模块都会被下电或者进行动态频率调节,以此来达到功耗降低的结果。其中有一些 menuconfig 可以按需求配置,本文将对这些配置项做一些介绍。 此时的芯片底电流可以参考 datasheet 上的功耗,如ESP32-C3 为 130 μA,ESP32-S3为 240 μA,ESP32-C6为 35 μA(实测是 45 μA,后续 datasheet 会修正这一项)。

1. 常用功耗优化配置选项

1.1. 动态调频

CPU 工作的频率越高,功耗消耗也越大。通过 DFS(dynamic frequency scaling,动态调频)可以让系统自动切换工作频率,达到功耗和性能间的平衡。开启该功能需要使能如图2-1的这两项,这样系统会在工作的时候切换到最大频率,在系统空闲时切换到最低频率,最大频率默认为主频,如 ESP32-C3 为160 MHz, 最低频率为外部主晶振的频率,一般为 40 MHz。最大和最小的频率可以通过调用esp_pm_configure进行设置。

备注

如果是带有Wi-Fi 应用的自动调频,最小频率不能小于 40 MHz。低于40 MHz CPU处理速度会慢,低功耗收益不高,且 C6 没有适配好,会有 beacon loss 的问题。

图 2-1 动态调频配置项

  • 配置项名称: PM_ENABLE

  • 配置项路径: (Top) -> Component config -> Power Management -> Support for power management

  • 配置项名称: PM_DFS_INIT_AUTO

  • 配置项路径: (Top) -> Component config -> Power Management -> Support for power management -> Enable dynamic frequency scaling (DFS) at startup

1.2 自动 light sleep

在开启动态调频后如果需要进一步降低功耗,如图2-1所示,需要开启自动light sleep。 Modem sleep模式加上自动light sleep 也就是我们常说的 power save 模式。

图 2-2 自动 light sleep配置项

  • 配置项名称: FREERTOS_HZ

  • 配置项路径: (Top) -> Component config -> FreeRTOS -> Tick rate (Hz)

  • 配置项名称: FREERTOS_USE_TICKLESS_IDLE

  • 配置项路径: (Top) -> Component config -> FreeRTOS -> Tickless idle support

这里涉及两个配置项,A 项为 freeRTOS 的Tick 频率,默认为 100,即每个 Tick 需要1000 / 100=10 ms。B项是自动进入 light sleep 状态需要的最小空闲 Tick 数,默认为3,即当系统检测到空闲时间大于3个Tick 时就会自动进入 light sleep。如上图所示,当空闲时间大于 3*10=30 ms 时系统将自动进入 light sleep。通过增加A项,可以让系统更敏感地检测到空闲时间并进入睡眠。如将 tick rate配置为1000,即当3 ms内没有任务工作就进入睡眠,从而达到更低的功耗。

备注

  1. 自动进入 light sleep 必须在使能 2.1 的配置项后才能进行配置。

  2. 在开启了自动调频和自动睡眠后,一些外设的通信会受到影响,具体可以参照编程指南。

客户最容易问的是如何在保持功耗的情况下使用LEDC和 UART,解决方法: - 对于在自动睡眠时想使用UART中断的客户,首先问他们是否还有多余的GPIO 管脚,优先推荐 GPIO 唤醒。 - 询问客户硬件上是否有外接32K晶振,如果有,改变外设时钟源为外部32K晶振。 - 使用锁,可以在进行通信时禁用动态调频,例子可以看附件2。

1.3 隔离 GPIO

系统休眠过程中的 GPIO 漏电会产生电流损耗,增大系统功耗。esp-idf 中 light sleep 休眠时通过 GPIO 管脚悬空(禁止管脚内部上下拉电阻)及隔离(断开管脚输入输出)来消除 GPIO 漏电流,该功能对应的 menuconfig 配置项如下。

备注

该配置项必须在使能 2.2 的自动睡眠后才能启用。

图 2-3 隔离 GPIO 配置项

  • 配置项名称: PM_SLP_DISABLE_GPIO

  • 配置项路径: (Top) -> Component config -> Power Management -> Disable all GPIO when chip at sleep

打开该选项,系统休眠过程中所有 GPIO 管脚将被禁用,消除了 GPIO 漏电对休眠功耗的影响,但也导致了休眠过程中 GPIO 无法进行信号输入和输出,然而在一些应用中,应用层希望在系统休眠过程中能够正常使用 GPIO 功能(输入/输出/内部上下拉),因此 IDF 中提供了一组 API 用于管理休眠过程中的 GPIO 状态,相关 API 参考表 2-1。

表 2-1 休眠过程 GPIO 管理 API

  • 设置休眠状态下的 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_hold_en(gpio_num_t gpio_num)gpio_hold_dis(gpio_num_t gpio_num) 两个 API,在进入睡眠前对需要保持电平的 GPIO 进行 hold,醒来后进行 hold_dis。

1.4 flash 下电

ESP32通过外接 flash 和 PSRAM 来增大系统存储器资源。flash 具有掉电后数据不丢失特性,PSRAM 掉电后数据无法保持,当系统中没有使用到 PSRAM 时,可以使能 flash 下电功能来降低芯片休眠电流,相关 menuconfig 选项如下:

图 2-4 Flash 掉电配置项

  • 配置项名称: ESP_SYSTEM_PD_FLASH    (release/v4.3)

  • 配置项名称: ESP_SLEEP_POWER_DOWN_FLASH    (4.4以后)

  • 配置项路径: (Top) -> Component config -> ESP System Settings -> PD flash at light sleep when there is no SPIRAM     (release/v4.3)

  • 配置项路径: (Top) -> Component config -> Hardware Settings -> Sleep Config -> Power down flash in light sleep when there is no SPIRAM     (4.4以后)

备注

现实情况中 flash 断电所需的时间很难预测,即使可以预知 flash 彻底断电所需的时间,有时也不能通过设置足够长的睡眠时间来确保 flash 断电的安全(比如,突发的异步唤醒源会使得实际的睡眠时间不可控),此时,断电尚未完成又重新上电的硬件行为有可能导致 flash 无法正常工作。因此可以对配置项进行以下调整:

图 2-5 Flash 掉电配置优化

  • 配置项名称: ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND

  • 配置项路径: (Top) -> Component config -> Hardware Settings -> Sleep Config -> Pull-up Flash CS pin in light sleep

这种方式比断电 flash 更好,相比之下增加了十几 μA 的底电流消耗,但同时兼顾了安全性和功耗。如果在 flash 的供电电路上添加了滤波电容,那么应当尽一切可能避免 flash 断电。

1.5 CPU 下电

对于 light sleep 模式下功耗有更高要求的应用,可以使能休眠时 CPU 下电功能来减小休眠电流,对于 ESP32-C3,休眠电流减小 100 μA 左右,对于 ESP32-S3,休眠电流减小 650 μA 左右。目前仅在这两个芯片上可用,ESP32 和 ESP32-S2 无法使用。

休眠时对 CPU 下电会造成 CPU 执行上下文信息(专用、通用以及状态寄存器等)丢失,导致休眠唤醒后 CPU 执行异常,因此需要在 CPU 下电前备份上下文信息到 retention memory,系统唤醒后 CPU 执行前从 retention memory 中恢复上下文信息,备份 CPU 上下文信息需要消耗系统存储器资源,对于 ESP32-C3,将消耗 1.6 KB 的 DRAM 空间,对于 ESP32-S3,将消耗 8.58 KB 的 DRAM 空间。

图 2-6 CPU 掉电配置

  • 配置项名称: PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP

  • 配置项路径: (Top) -> Component config -> Power Management -> Power down CPU in light sleep

1.6 外围设备下电(light sleep)

通过关闭此项,可以将底电流降低约 100 μA。

  • 配置项名称: PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP

  • 配置路径: (Top) -> Component config -> Power Management -> Power down Digital Peripheral in light sleep (EXPERIMENTAL)

当外设电源域在睡眠期间断电时,IO_MUXGPIO 模块都处于下电状态,这意味着芯片引脚的状态不会受这些模块控制。要在休眠期间保持 IO 的状态,需要在配置 GPIO 状态前后调用 gpio_hold_dis()gpio_hold_en()。此操作可确保 IO 配置被锁存,防止 IO 在睡眠期间浮空。

2. Wi-Fi/蓝牙低功耗优化配置

乐鑫芯片是无线 MCU,因此大部分时候的低功耗功能都需要和 Wi-Fi/蓝牙功能一起使用。这里对 Wi-Fi/蓝牙相关的一些低功耗配置和参数进行解释。

2.1 蓝牙低功耗优化项

2.1.1 BLE sleep

目前蓝牙端可以优化配置比较少,可以使能 BLE modem sleep。

图 2-1-1-1 蓝牙低功耗配置_1 图 2-1-1-2 蓝牙低功耗配置_2
  • 配置项名称: BT_CTRL_MODEM_SLEEPBT_LE_SLEEP_ENABLE(V5.2)

  • 配置路径: - (Top) -> Component config -> Bluetooth -> Bluetooth -> Bluetooth controller -> MODEM SLEEP Options - (Top) Component config Bluetooth Controller Options(V5.2)

如果希望在保活时进入 light sleep 而不是 modem sleep,可参考 2.2 的做法。

需要注意的是,在 4.4 及之后的 IDF 版本里,蓝牙已支持用主晶振作为休眠时钟,不使用外部 32 KHz 晶振的代价是 light sleep 时底电流会上升。参考电流: - ESP32-C3: 2.3 mA - ESP32-S3: 3.3 mA

2.1.2 Nimble – BLE only

图 2-1-2 BLE only 配置
  • 配置项名称: BT_NIMBLE_ENABLED

  • 配置路径: (Top) -> Component config -> Bluetooth -> Bluetooth -> Host

在 BLE only 的场景下,可配置此项以减少内存消耗。

2.2 Wi-Fi 低功耗优化项

Wi-Fi 优化涉及的配置项较多,比较通用的有以下几点:

2.2.1 无线数字电路掉电

在使能自动 light sleep 后,可以开启此选项,让无线数字电路模块在关闭物理层时也相应掉电,大约能节省 100 μA 左右的底电流。

图 2-2 无线数字电路掉电配置
  • 配置项名称: ESP_PHY_MAC_BB_PD

  • 配置路径: (Top) -> Component config -> PHY -> Power down MAC and baseband of Wi-Fi and Bluetooth when PHY is disabled

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

当 ESP32 作为 STA 和 AP 进行通信时,接收完一次数据后需要等待一段时间再关闭 RF,这个时间称为 Minimum active time,默认值为 50 ms。在保证每次数据吞吐量的基础上,可以适当减少这个等待时间来降低功耗。

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

图 2-3 最小等待时间和最大保活时间配置
  • 配置项名称: ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME

  • 配置路径: (Top) -> Component config -> Wi-Fi -> Wi-Fi SLP IRAM speed optimization -> Minimum active time

  • 配置项名称: ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME

  • 配置路径: (Top) -> Component config -> Wi-Fi -> Wi-Fi SLP IRAM speed optimization -> Maximum keep alive time

推荐配置: Minimum active time = 15~20,Maximum keep alive time = 60。

2.2.3 开启断连电源管理

使能该配置项后,发生断连时依旧可以保持 Modem sleep 状态。

图 2-4 开启断连电源管理
  • 配置项名称: ESP_WIFI_STA_DISCONNECTED_PM_ENABLE

  • 配置路径: (Top) Component config Wi-Fi Power Management for station at disconnected

2.2.4 开启 Beacon lost 优化(仅 release/v4.4 及以上)

Wi-Fi 保活的一个基础是能够定时接收到路由器发送的 beacon 包。在实际使用环境中,因各种原因会导致 beacon 丢失。在 release/v4.4 之前的版本中,丢失 beacon 后 ESP32 会保持 RF 继续开启,直到接收到下一个 beacon。4.4 以后的版本可通过开启 beacon lost 优化来避免这一行为对功耗造成的影响。

图 2-5 开启 beacon lost 优化
  • 配置项名称: ESP_WIFI_SLP_BEACON_LOST_OPT

  • 配置路径: (Top) Component config Wi-Fi Wifi sleep optimize when beacon lost

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

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

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

  • A 选项: Beacon loss timeout 表示等待多久没收到 beacon 就进入休眠。

  • B 选项: Maximum number of consecutive lost beacons allowed 表示重复多少次没收到才持续开启。

需注意,B 选项不应设得过大,一般设为 3 个即可。

2.2.5 降低 TX power

使能该项后,检测到 brownout reset 后将减小 PHY TX power,使代码能继续运行。

图 2-7 开启 TX power 优化
  • 配置项名称: ESP_PHY_REDUCE_TX_POWER

  • 配置路径: (Top) Component config PHY Reduce PHY TX power when brownout reset

2.2.6 优化 Sleep IRAM Speed

选择此选项可将 Wi-Fi 库的 TBTT 进程和 receive beacon 函数放置在 IRAM 中。如果启用此选项,Wi-Fi powersave 模式平均电流将减少。

图 2-8 开启 Sleep IRAM Speed 优化
  • 配置项名称: ESP_WIFI_SLP_IRAM_OPT

  • 配置路径: (Top) Component config Wi-Fi WiFi SLP IRAM speed optimization

2.2.7 优化 IRAM Speed

以下三项都可以开启。

图 2-9 开启 IRAM Speed 优化
  • 配置项名称: - ESP_WIFI_IRAM_OPT - ESP_WIFI_EXTRA_IRAM_OPT - ESP_WIFI_RX_IRAM_OPT

  • 配置路径: (Top) Component config Wi-Fi WiFi IRAM speed optimization

2.2.8 Wi-Fi 物理层收包

ESP32-C6 的可选功能,在 light sleep 期间,PHY 层自动收包,Wi-Fi 接收 beacon 不再需要 CPU 参与,只有 Wi-Fi MAC + Baseband + RF 工作,以节省功耗。

备注

补充内容:不同 mode 下 T/RX 波形图

图 2-10 Wi-Fi 物理层收包优化
  • 配置项名称: - ESP_WIFI_ENHANCED_LIGHT_SLEEP - ESP_WIFI_EXTRA_IRAM_OPT - ESP_WIFI_RX_IRAM_OPT

  • 配置路径: (Top) Component config Wi-Fi WiFi modem automatically receives the beacon

3. 补充内容

3.1. DTIM 和 listen interval 的区别

当芯片作为 STA 和路由器建立连接的时候,会被告知路由器的 DTIM,即每隔多少时间路由器会发送一个 beacon,STA 需要在这个时间起来接收 beacon,查看是否有需要自己处理的信息。而 listen interval 则是 STA 告诉路由,我需要隔多少时间起来接受 beacon,即前者是根据路由端来定的,后者是可以自己配置到芯片里的。时间间隔为 DTIM 或者 listen interval 的值 * 100 MS,如果当 DTIM=10,即每次唤醒的时间间隔为 10 * 100 ms = 1 s。

3.2. 外接 32KHz 晶振

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

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

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

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

图 3-1 使能外部晶振
  • 配置项名称: - ESP32C3_RTC_CLK_SRC_EXT_CRYS - ESP_WIFI_EXTRA_IRAM_OPT - ESP_WIFI_RX_IRAM_OPT

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

外部晶振有两种:

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

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

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

3.3. 不同 mode 下 T/RX 波形图

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