警告

This document is not updated for ESP32C5 yet, so some of the content may not be correct.

This warning was automatically inserted due to the source file being in the add_warnings_pages list.

低功耗模式使用指南

[English]

对于物联网应用场景,终端的待机性能表现十分重要,本文档旨在介绍 ESP32-C5 低功耗的基本原理,同时介绍 ESP32-C5 支持的低功耗模式,需注意本文档主要针对 station mode。文档还会具体给出每种模式的配置步骤、推荐配置和功耗表现,以帮助用户根据实际需求快速配置适合的低功耗模式。

系统低功耗模式介绍

低功耗模式不仅涉及到系统相关问题,还涉及到芯片具体的工作场景,如处在 Wi-Fi 工作场景就会与处在蓝牙工作场景时产生不同。为此本节将首先介绍纯系统角度,即不涉及具体场景的低功耗模式,主要有 DFS、Light-sleep、Deep-sleep。纯系统下的低功耗模式主要思想就是在休眠时关闭或门控一些功能模块来降低功耗。

DFS

DFS (Dynamic frequency scaling) 即动态频率切换,是 ESP-IDF 中集成的电源管理机制的基础功能。DFS 可以根据应用程序持有电源锁的情况,调整外围总线 (APB) 频率和 CPU 频率。持有高性能锁就使用高频,空闲状态不持有电源锁时则使用低频来降低功耗,以此来尽可能减少运行应用程序的功耗。

DFS 的调频机制即根据持有电源锁的最大频率需求来调整频率,同时,freertos tick rates 的数值也会对 DFS 调频产生影响。系统任务调度的灵敏度越大,则意味着系统能更及时的根据需求调整频率。有关调频机制的详细信息,请参见 电源管理

下图为 DFS 调频机制运行的理想电流情况。

../_images/Low-power-DFS-current.png

理想 DFS 机制调频电流图

DFS 适用于 CPU 必须处于工作状态但是对低功耗有需求的场景,因此 DFS 经常与其他低功耗模式共同开启,下文会详细介绍。

Light-sleep

Light-sleep 模式是 ESP32-C5 预设的一种低功耗模式,其核心思想就是在休眠时关闭或门控一些功能模块来降低功耗。从纯系统方面来说,Light-sleep 模式有两种进入方式,一种是通过 API 调用进入休眠,一种是自动进入的 auto 模式。两种模式都需要配置唤醒源进行唤醒,同时在进入休眠后会门控或关闭一些模块。这里主要介绍 Auto Light-sleep 模式。

Auto Light-sleep 模式是 ESP-IDF 电源管理机制和 Light-sleep 模式的结合。开启电源管理机制是其前置条件,auto 体现在系统进入空闲状态 (IDLE) 超过设定时间后,自动进入 Light-sleep。空闲状态下,应用程序释放所有电源锁,此时,DFS 将降频以减小功耗。

Auto Light-sleep 依赖于电源管理机制,系统经过提前判断,发现空闲时间超过设定时间时,则直接进入休眠。该过程为自动进行。休眠时会自动关闭 RF、8 MHz 振荡器、40 MHz 高速晶振、PLL、门控数字内核时钟,暂停 CPU 工作。

Auto Light-sleep 模式需配置唤醒源。该模式拥有多种唤醒源,支持相互组合,此时任何一个唤醒源都可以触发唤醒。唤醒后,会从进入休眠的位置继续执行程序。若不配置唤醒源,进入 Light-sleep 休眠后,芯片将一直处在睡眠状态,直到外部复位。具体唤醒源有 RTC 定时器、触摸传感器、外部唤醒 (ext0)、外部唤醒 (ext1)、ULP 协处理器、SDIO、GPIO、UART、Wi-Fi、BT 唤醒等。

Auto Light-sleep 模式工作流程相对复杂,但是进入休眠状态是自动进行,同时需注意在进入前配置好唤醒源,防止芯片一直处在休眠状态。

../_images/Low-power-auto-light-sleep-process.png

Auto Light-sleep 模式工作流程图

根据 Auto Light-sleep 的工作流程可得其理想电流图,关键节点均在图上标出。

../_images/Low-power-auto-light-sleep-current.png

Auto Light-sleep 模式模式理想电流图

备注

为更加清晰地展现出 Auto Light-sleep 的主要变化,图中省略了 DFS 降频过程。

Auto Light-sleep 模式适用于不需要实时响应外界需求的场景。

Deep-sleep

Deep-sleep 模式是为了追求更好的功耗表现所设计,休眠时仅保留 RTC 控制器、RTC 外设(可配置)、ULP 协处理器、RTC 高速内存、RTC 低速内存,其余模块全部关闭。与 Light-sleep 类似,Deep-sleep 同样通过 API 进入,且需要配置唤醒源进行唤醒。

Deep-sleep 通过调用 API 进入,休眠时会关闭除 RTC 控制器、RTC 外设、ULP 协处理器、RTC 高速内存、RTC 低速内存外的所有模块。

Deep-sleep 模式需配置唤醒源,其拥有多种唤醒源,这些唤醒源也可以组合在一起,此时任何一个唤醒源都可以触发唤醒。若不配置唤醒源进入 Deep-sleep 模式,芯片将一直处在睡眠状态,直到外部复位。具体唤醒源有 RTC 定时器、触摸传感器、外部唤醒 (ext0)、外部唤醒 (ext1)、ULP 协处理器、GPIO 唤醒等。

Deep-sleep 模式工作流程如下图所示:

../_images/Low-power-deep-sleep-process.png

Deep-sleep 模式工作流程图

Deep-sleep 模式主要应用场景决定了系统很长时间才会苏醒一次,完成工作后又会继续进入 Deep-sleep,所以其理想电流图如下。

../_images/Low-power-deep-sleep-current.png

Deep-sleep 模式理想电流图

Deep-sleep 可以用于低功耗的传感器应用,或是大部分时间都不需要进行数据传输的情况,也就是通常所说的待机模式。设备可以每隔一段时间从 Deep-sleep 状态醒来测量数据并上传,之后重新进入 Deep-sleep;也可以将多个数据存储于 RTC memory,然后一次性发送出去。

如何配置纯系统下低功耗模式

介绍完纯系统下的低功耗模式后,本节将介绍公共配置选项、每种模式独有的配置选项,以及相应低功耗模式 API 的使用说明,同时给出相应模式推荐的配置。

公共配置选项

DFS 配置

DFS 有如下可配置选项:

  • max_freq_mhz

    该参数表示最大 CPU 频率 (MHz),即 CPU 最高性能工作时候的频率,一般设置为芯片参数的最大值。

  • min_freq_mhz

    该参数表示最小 CPU 频率 (MHz),即系统处在空闲状态时 CPU 的工作频率。该字段可设置为晶振 (XTAL) 频率值,或者 XTAL 频率值除以整数。

  • light_sleep_enable

    使能该选项,系统将在空闲状态下自动进入 Light-sleep 状态,即 Auto Light-sleep 使能,上文已经具体介绍。

具体配置方法如下:

    1. 使能 CONFIG_PM_ENABLE

    1. 配置 max_freq_mhz 和 min_freq_mhz,方式如下:

    esp_pm_config_t pm_config = {
            .max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ,
            .min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ,
            .light_sleep_enable = false
    };
    ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
    

推荐配置:

配置名称

设置情况

CONFIG_PM_ENABLE

ON

RTOS Tick rate (Hz)

1000

max_freq_mhz

160

min_freq_mhz

40

light_sleep_enable

false

备注

上表中不涉及的配置均是默认。

Light-sleep 配置

本节介绍 Auto Light-sleep 的推荐配置和配置步骤。

Auto Light-sleep 有如下可配置选项:

  • Minimum step to enter sleep mode

    该参数表示系统自动进入休眠的阈值。该参数单位为 RTOS Tick,故其表示的时间与 RTOS Tick rate 相关,例该参数值为 3,RTOS Tick rate 配置为 1000 Hz 时,即当系统空闲时间大于等于 3 ms 时进入 休眠。

  • Put light sleep related codes in internal RAM

    如果使能该选项,一些 light-sleep 功能将被移至 IRAM,减少代码运行时间,降低系统功耗,IRAM 使用量将增加 1.8 kB。

  • Put RTOS IDLE related codes in internal RAM

    如果使能该选项,一些 RTOS IDLE 功能将被移至 IRAM,减少代码运行时间,降低系统功耗,IRAM 使用量将增加 260 B。

  • RTC slow clock source

    该参数表表示 RTC 慢速时钟源。系统休眠时计时器模块的时钟被门控,此时使用 RTC Timer 进行计时,唤醒后使用 RTC Timer 的计数值对系统时间进行补偿。

时钟源

精度

频偏

Internal 150 kHz OSC

约 6.7 us/cycle

External 32 kHz XTAL

约 30.5 us/cycle

  • Disable all GPIO when chip at sleep

    如果使能该选项,系统将在休眠过程中禁用所有 GPIO 管脚,消除 GPIO 漏电,降低功耗,但是休眠过程中 GPIO 无法进行信号输入和输出。

唤醒源:

  • RTC Timer Wakeup

  • GPIO Wakeup

  • UART Wakeup

  • Touchpad Wakeup

  • External Wakeup (ext0)

  • External Wakeup (ext1)

  • ULP Coprocessor Wakeup

备注

以上仅列出可配置唤醒源,详细介绍请参考 睡眠模式

配置方法:

    1. 配置唤醒源

    1. 使能 CONFIG_PM_ENABLE

    1. 使能 CONFIG_FREERTOS_USE_TICKLESS_IDLE

    1. 配置 DFS 参数

    1. 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));
    
    1. 配置介绍的其余相关参数

推荐配置:

Deep-sleep 配置

对 Deep-sleep 模式来说,除了唤醒源相关配置,其余配置意义已经不大。

Deep-sleep 有如下可配置选项:

  • RTC Timer wakeup

  • EXT0/1 wakeup

  • Touchpad wakeup

  • ULP wakeup

备注

以上仅列出可配置唤醒源,详细介绍请参考 睡眠模式

配置步骤:

  • 配置唤醒源

  • 调用 API,具体如下:

    /* Enter deep sleep */
    esp_deep_sleep_start();
    

用户可以通过下列配置选项,让一些特定模块在休眠时保持开启状态:

  • Power up External 40 MHz XTAL

    在一些特殊应用中,部分模块对休眠时的时钟精度及稳定度有很高要求(例如 BT)。这种情况下,可以考虑在休眠过程中打开 External 40 MHz XTAL。 打开和关闭代码如下:

    ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON));
    ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF));
    
  • Power up Internal 8 MHz OSC

    在一些特殊应用中,部分模块(例如 LEDC)将 Internal 8 MHz OSC 作为时钟源,并且希望在 Light-sleep 休眠过程中也可以正常使用。这种情况下,可以考虑在休眠过程中打开 Internal 8 MHz OSC。 打开和关闭代码如下:

    ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC8M, ESP_PD_OPTION_ON));
    ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC8M, ESP_PD_OPTION_OFF));