ESP32: управление энергопотреблением Печать
Добавил(а) microsin   

Алгоритм управления питанием (Power Management), применяемый в ESP-IDF [2], позволяет настроить частоту шины APB, частоту тактирования ядер CPU, и может перевести микросхему в режим легкого сна (light sleep mode), чтобы приложение работала с минимально возможным током потребления, соответствующим требованиям компонентов приложения.

Компоненты приложения могут выражать свои требования путем создания и захвата блокировок управления питанием (power management locks). Например:

• Драйвер периферийного устройства, которое тактируется от APB, может запросить установку частоты APB на 80 МГц, когда используется это периферийное устройство.
• FreeRTOS может запросить работу CPU на повышенной частоте, когда задачи (tasks) готовы к запуску (перешли в состояние Ready).
• Драйверу периферийного устройства может понадобиться разрешить прерывания, что означает запрет режима легкого сна (light sleep).

Поскольку запрос повышения частот APB или CPU, или запрет light sleep приведет к возрастанию тока потребления, старайтесь свести к минимуму использование компонентами блокировок power management lock.

[Конфигурация Power Management]

Управление питанием (Power Management) может быть разрешено во время компиляции с использованием опции CONFIG_PM_ENABLE.

Разрешение функции управления питанием достигается ценой повышения задержек в обработке прерываний (interrupt latency). Дополнительная латентность зависит от нескольких факторов, таких как частота CPU, использование одно или двух ядер (single/dual core mode), требуется или нет переключение на другую частоту. Минимальная дополнительная задержка составляет 0.2 мкс (при частоте CPU 240 МГц, и когда не нужно изменение частоты). Максимальная дополнительная задержка составит 40 мкс (когда разрешено масштабирование частоты, и на входе в прерывание происходит переключение с 40 МГц на 80 МГц).

В приложении может быть разрешено динамическое масштабирование частоты (DFS) и автоматическая активация light sleep путем вызова функции esp_pm_configure(). Её аргументом является структура esp_pm_config_esp32_t, определяющая настройки масштабирования частоты. В этой структуре должны быть инициализированы 3 поля:

max_freq_mhz: максимальная частота CPU в МГц, например частота, которая используется, когда требуется ESP_PM_CPU_FREQ_MAX lock. Это поле обычно устанавливается в значение частоты по умолчанию для CPU.

min_freq_mhz: минимальная частота CPU в МГц, например частота, которая используется, только когда захватывается ESP_PM_APB_FREQ_MAX. Это поле может быть установлено в значение XTAL, либо в значение XTAL, поделенное на целое значение. Обратите внимание, что 10 МГц это минимальная частота, на которой может генерироваться частота по умолчанию REF_TICK 1 МГц.

light_sleep_enable: должна ли система автоматически зайти в режим light sleep, когда не было захватов блокировок (true/false).

Альтернативно, если Вы разрешили опцию CONFIG_PM_DFS_INIT_AUTO в menuconfig, максимальная частота CPU будет определяться настройкой CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, и минимальная частота CPU будет зафиксирована на частоте XTAL.

Замечания: автоматический вход в light sleep основан на функционале FreeRTOS Tickless Idle. Если запрошен automatic light sleep, когда в menuconfig не разрешена опция CONFIG_FREERTOS_USE_TICKLESS_IDLE, то функция esp_pm_configure() вернет ошибку ESP_ERR_NOT_SUPPORTED. В режиме light sleep периферийные устройства не получают тактирование, и прерывания (от ножек GPIO и внутренних периферийных устройств) не генерируются. Для вывода устройства из состояния light sleep может использоваться источник пробуждения (wakeup source), описанный в документации по режимам пониженного энергопотребления [3].

Например, для пробуждения устройства от ножек GPIO могут использоваться источники EXT0 и EXT1 wakeup.

[Блокировки управления питанием]

У приложений есть возможность получать/освобождать блокировки для управления алгоритмом управления питанием (Power Management Locks). Когда приложение получило блокировкуk, алгоритм управления питанием ограничивается способом, описанном ниже. Когда блокировка освобождается, эти ограничения снимаются.

Блокировки управления питаниям имеют счетчики получения/освобождения (acquire/release counters). Если блокировка была получена определенное количество раз, то такое же количество она должна быть освобождена, чтобы были сняты связанные с блокировкой ограничения.

ESP32 поддерживает 3 типа блокировки, описанные в таблице ниже.

Таблица 1. Виды Power Management Locks для ESP32.

Блокировка (Lock) Описание
ESP_PM_CPU_FREQ_MAX Запрашивает максимальное значение частоты CPU, которое было установлено вызовом esp_pm_configure(). Для ESP32 это значение может быть установлено на 80, 160 или 240 МГц.
ESP_PM_APB_FREQ_MAX Запрашивает установку частоты шины APB на максимальное поддерживаемое значение. Для ESP32 это 80 МГц.
ESP_PM_NO_LIGHT_SLEEP Запрещает автоматическое переключение в режим light sleep.

[Алгоритм управления питанием ESP32]

В таблице ниже показано, как будут переключаться частоты CPU и APB, если разрешено динамическое масштабирование частот. Можно указать максимальную частоту CPU либо вызовом esp_pm_configure(), либо опцией CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ.

Таблица 2. Работа переключения тактовых частот ESP32.

Max устанавливаемая частота CPU Получение блокировки Частоты CPU и APB
240 МГц Получена любая из блокировок ESP_PM_CPU_FREQ_MAX или ESP_PM_APB_FREQ_MAX. CPU 240 МГц, APB 80 МГц
Нет блокировки Минимальные значения для обоих частот устанавливаются вызовом esp_pm_configure().
160 МГц Получена блокировка ESP_PM_CPU_FREQ_MAX. CPU 160 МГц, APB 80 МГц
Блокировка ESP_PM_APB_FREQ_MAX получена, ESP_PM_CPU_FREQ_MAX не получена. CPU 80 МГц, APB 80 МГц
Нет блокировки Минимальные значения для обоих частот устанавливаются вызовом esp_pm_configure().
80 МГц Получена любая из блокировок ESP_PM_CPU_FREQ_MAX или ESP_PM_APB_FREQ_MAX. CPU 80 МГц, APB 80 МГц
Нет блокировки Минимальные значения для обоих частот устанавливаются вызовом esp_pm_configure().

Если не была установлена ни одна из блокировок, и разрешен light sleep в вызове esp_pm_configure(), то система перейдет в режим light sleep. Длительность этого режима определяется следующим:

• Задачами FreeRTOS, заблокированными с бесконечным временем ожидания выхода из блокировки.
• Таймерами, зарегистрированными API-вызовами таймеров высокого разрешения [4].

Для пробуждения чипа перед ближайшим событием (разблокировалась задача, или истек таймаут таймера) выбирается длительность light sleep.

Чтобы пропустить нежелательное пробуждение, можно инициализировать esp_timer с опцией skip_unhandled_events, установленной в true. Таймеры с этим флагом не будут пробуждать систему, тем самым будет снижено энергопотребление.

[Динамическое масштабирование частоты и драйверы периферийных устройств]

Когда разрешено динамическое управление частотой тактов (DFS), в пределах одного тика RTOS частота APB может быть изменена несколько раз. Изменение частоты APB не влияет на работу некоторых периферийных устройств, в то время с другими периферийными устройствами могут быть проблемы. Например, периферийные таймеры Timer Group продолжат счет, однако скорость их счета будет меняться в пропорционально частоте APB.

Следующие периферийные устройства будут нормально работать, когда изменяется частота APB:

UART: если в качестве источника тактирования используется REF_TICK или XTAL, см. uart_config_t::source_clk.
LEDC: если в качестве источника тактирования используется REF_TICK, см. функцию ledc_timer_config().
RMT: если в качестве источника тактирования используется REF_TICK или XTAL, см. rmt_config_t::flags и макрос RMT_CHANNEL_FLAGS_AWARE_DFS.
GPTimer: если в качестве источника тактирования используется APB, см. gptimer_config_t::clk_src.
TSENS: в качестве источника тактов используется XTAL или RTC_8M. Таким образом, изменение частоты APB не повлияет на его поведение.

В настоящий момент следующие драйверы периферийных устройств знают о DFS, и будут использовать блокировку ESP_PM_APB_FREQ_MAX на время выполнения транзакции:

SPI master
I2C
I2S (если используются такты APLL, то будет применяться блокировка 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(). Если разрешено засыпание модема (modem sleep), то блокировка будет освобождена для периодов времени, когда блок radio запрещен.

TWAI: между вызовами twai_driver_install() и twai_driver_uninstall().

Bluetooth: между вызовами esp_bt_controller_enable() и esp_bt_controller_disable(). Если разрешено засыпание модема Bluetooth, то блокировка ESP_PM_APB_FREQ_MAX будет освобождена для периодов времени, когда блок radio запрещен. Однако все еще будет удерживаться блокировка ESP_PM_NO_LIGHT_SLEEP, за исключением случаев, когда опция CONFIG_BTDM_CTRL_LOW_POWER_CLOCK установлена в "External 32kHz crystal".

Следующие драйверы периферийных устройств пока не знают про DFS. Поэтому для их использования приложения должны самостоятельно захватывать/освобождать блокировки по мере необходимости:

PCNT
Sigma-delta
Драйвер группы legacy timer
MCPWM

[Справочник по Power Management API]

Заголовочный файл: components/esp_pm/include/esp_pm.h.

Функция Описание
esp_pm_configure Установит конфигурацию управления питанием, зависящую от реализации.
esp_pm_get_configuration Получит информацию по конфигурации управления питанием.
esp_pm_lock_create Инициализирует дескриптор блокировки (lock handle) для определенного параметра управления питанием. Когда блокировка создана, она изначально не захватывается. Для захвата блокировки вызовите esp_pm_lock_acquire. Функция esp_pm_lock_create не должна вызываться из кода ISR.
esp_pm_lock_acquire Получает блокировку для управления питанием (power management lock). Когда блокировка захвачена, алгоритм управления питанием не будет переключаться в режим, указанный в вызове esp_pm_lock_create, или входить в любой из режимов пониженного энергопотребления (режимы с большими числовыми значениями). Блокировка рекурсивная, т. е. когда esp_pm_lock_acquire вызывается N раз, то должен быть осуществлен вызов esp_pm_lock_release также N раз, чтобы блокировка была освобождена. Функция esp_pm_lock_acquire может вызываться из кода ISR, но она не безопасная для использования в контексте потоков при вызове других функций esp_pm_lock_* для того же самого дескриптора.
esp_pm_lock_release Освободит блокировку, полученную вызовом esp_pm_lock_acquire. Вызов функции esp_pm_lock_release снимет все ограничения по управлению питанием, которые были наложены при взятии блокировки. Блокировки рекурсивные, т. е. когда esp_pm_lock_acquire вызывается N раз, то должен быть осуществлен вызов esp_pm_lock_release также N раз, чтобы блокировка была освобождена. Функция esp_pm_lock_release может вызываться из кода ISR, но она не безопасная для использования в контексте потоков при вызове других функций esp_pm_lock_* для того же самого дескриптора.
esp_pm_lock_delete Удалит блокировку, созданную вызовом esp_pm_lock. Перед вызовом этой функции блокировка должна быть освобождена. Эта функция не должна вызываться из кода ISR.
esp_pm_dump_locks Выведет список всех блокировок в stderr. Эта функция предоставляет отладочную информацию о блокировках, созданных с использованием esp_pm_lock_create. Функция esp_pm_dump_locks не должна вызываться из ISR. Если во время работы esp_pm_dump_locks вызывались функции esp_pm_lock_acquire/esp_pm_lock_release, то может быть выведена неполная информация.

Примечание: полное описание макросов, типов данных, API-функций и их параметров см. в документации [1].

[Словарик]

APB Advanced Peripheral Bus, шина периферийных устройств.

DFS Dynamic Frequency Scaling, динамическое переключение частоты тактов.

[Ссылки]

1. ESP32 Power Management site:docs.espressif.com.
2. Установка среды разработки ESP-IDF для ESP32.
3ESP32: режимы пониженного энергопотребления.
4. ESP32 High Resolution Timer site:docs.espressif.com.