Программирование ARM ESP32-C3: режимы пониженного энергопотребления Sun, October 06 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

ESP32-C3: режимы пониженного энергопотребления Печать
Добавил(а) microsin   

ESP32-C3 может находиться в двух режимах пониженного энергопотребления: Light-sleep и Deep-sleep.

Light-sleep. В этом режиме сна цифровые периферийные устройства, большая часть RAM и CPU, не получают тактирование, и их напряжение питания снижено. При выходе из Light-sleep блоки периферийных устройств, RAM и CPU возобновляют свою работу в том состоянии, в каком они находились в момент входа Light-sleep (никакие данные не теряются).

Deep-sleep. В этом режиме выключено почти все: CPU, большая часть RAM и все цифровые периферийные устройства, которые тактируются от APB_CLK. Только некоторые части чипа остаются под питанием:

Контроллер RTC [2]
Быстрая память RTC (RTC fast memory)

Примечание: существует более продвинутый, двухядерный чип ESP32 с другой архитектурой, у которого есть и другие дополнительные устройства, которые также получают питание в режиме Deep-sleep: периферийные устройства RTC, сопроцессор ULP, медленная память RTC (RTC slow memory), см. [3].

Существует несколько источников пробуждения (wakeup) для выхода из режимов Deep-sleep и Light-sleep. Эти источники также можно комбинировать, чтобы чип просыпался, когда поступил сигнал пробуждения от любого сконфигурированного источника пробуждения. Источники пробуждения можно разрешить вызовом API-функций esp_sleep_enable_X_wakeup, и запретить esp_sleep_disable_wakeup_source. В следующей секции более подробно описываются эти API-вызовы. Источники пробуждения могут быть сконфигурированы в любой момент перед входом в режим Light-sleep или Deep-sleep.

Дополнительно приложение может принудительно активировать определенные режимы выключения для периферийных устройств RTC и областей памяти RTC, используя API-функцию esp_sleep_pd_config.

После того, как источники пробуждения сконфигурированы, приложение может войти в один из двух режимов сна, используя API-функцию esp_light_sleep_start или esp_deep_sleep_start. В этот момент аппаратура будет сконфигурирована в соответствии с запрошенными источниками пробуждения, и контроллер RTC будет делать либо power down, либо power off для ядра CPU и цифровых периферийных устройств.

Если соединения Wi-Fi должны сохраняться, разрешите режим Wi-Fi Modem-sleep и функцию automatic Light-sleep (см. API-функции управления энергопотреблением [4]). Это позволит системе автоматически выйти из сна, когда сконфигурирован драйвер Wi-Fi, поддерживая тем самым соединение с точкой доступа.

[Wi-Fi/Bluetooth и режимы сна]

В режимах пониженного энергопотребления Deep-sleep и Light-sleep беспроводные устройства выключены (power down). Перед входом в режим Deep-sleep или Light-sleep, приложение должно запретить Wi-Fi и Bluetooth, используя для этого соответствующие вызовы API-функций (т. е. esp_bluedroid_disable, esp_bt_controller_disable, esp_wifi_stop). Соединения Wi-Fi и Bluetooth не будут поддерживаться в режимах Deep-sleep или Light-sleep, даже если эти функции не были вызваны.

[Источники пробуждения]

Timer. Контроллер RTC содержит встроенный таймер, который может использоваться для пробуждения чипа после предварительно определенного интервала времени. Время указывается с точностью до микросекунды, однако реальная разрешающая способность указания времени зависит от выбранного источника тактирования для RTC SLOW_CLK.

В этом режиме выхода из сна периферийные устройства RTC или блоки памяти RTC во время сна включать не нужно.

Для разрешения пробуждения с помощью таймера может использоваться функция esp_sleep_enable_timer_wakeup.

GPIO Wakeup. Любой внешний вывод порта GPIO может использоваться для вывода ESP32-C3 из режима Light-sleep. С этим источником пробуждения каждая ножка может быть индивидуально сконфигурирована (с помощью функции gpio_wakeup_enable) для вывода чипа из сна по высокому или низкому уровню. Для разрешения этого источника пробуждения может использоваться функция esp_sleep_enable_gpio_wakeup.

Дополнительно те ножки GPIO, которые получают питание от домена VDD3P3_RTC (это порты GPIO0 .. GPIO5, см. [5]), могут быть использованы для вывода чипа ESP32-C3 из Deep-sleep. Ножка для подачи сигнала пробуждения и уровень активации пробуждения может быть сконфигурирован вызовом esp_deep_sleep_enable_gpio_wakeup. Эта функция разрешит выход из Deep-sleep для выбранного вывода.

UART Wakeup (только для Light-sleep). Когда ESP32 получает данные на входе UART от внешних устройств, часто необходимо разбудить чип, чтобы он мог обработать доступные данные. Периферийное устройство UART содержит функцию, которая позволяет вывести чип из режима Light-sleep, когда на ножке RX появилось определенное количество положительных перепадов. Это количество перепадов может быть установлено функцией uart_set_wakeup_threshold. Обратите внимание, что символ, который активирует пробуждение (и любые символы до него) не будет принят блоком UART после пробуждения (т. е. символ пробуждения и любые символы до него будут потеряны). Это значит, что внешнему устройству перед отправкой полезных данных обычно требуется отправить в ESP32 дополнительный символ, чтобы активировалось пробуждение.

Для разрешения этого источника пробуждения может использоваться функция esp_sleep_enable_uart_wakeup.

Примечание: двухядерная версия чипа ESP32 также может быть выведена из deep-sleep периферийным устройством тачпада, сопроцессором ULP, в также внешним сигналом на выводах ext0 и ext1, подробнее см. [3].

[Выключение периферийных устройств и блоков памяти RTC]

По умолчанию все функции esp_deep_sleep_start и esp_light_sleep_start выключат все домены питания RTC, которые не требуются для разрешенных источников пробуждения. Для переназначения этого поведения предоставлена функция esp_sleep_pd_config.

У чипа ESP32-C3 есть только быстрая память RTRC (RTC fast memory), так что если некоторые переменные в программе помечены атрибутами RTC_DATA_ATTR, RTC_SLOW_ATTR или RTC_FAST_ATTR, то все они попадут в RTC fast memory. По умолчанию эта память сохраняет питание, и значения данных в ней могут быть сохранены. Если необходимо, это можно переназначить функцией esp_sleep_pd_config.

[Выключение питания памяти Flash]

По умолчанию во избежание потенциальных проблем функция esp_light_sleep_start не будет выключать питание flash. Если углубляться в подробности, то выключение питания flash занимает некоторое время, и во время этого периода времени система может быть разбужена, что фактически включит питание flash прежде чем flash может быть полностью выключена. В результате есть некий шанс, что flash может не заработать правильно.

Так что теоретически будет нормальным, если вы разбудите систему только после того, как flash будет полностью выключена. Однако фактически период времени выключения flash может быть сложно предсказать (например, этот период может оказаться намного больше, когда вы добавили конденсаторы фильтра в цепь питания flash), и может быть неконтролируемым (например, асинхронные внешние сигналы пробуждения делают неуправляемым реальную длительность времени сна).

Предупреждение: если добавлен конденсатор фильтра на схему питания памяти flash, то по возможности избегайте выключения питания flash.

Таким образом, рекомендуется не выключать питание flash, когда используется ESP-IDF. Для приложений, которые особенно критичны в плане минимизации энергопотребления, рекомендуется использовать Kconfig-опцию CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND, чтобы снизить потребление мощности во время light sleep, вместо того, чтобы выключать питание flash.

Однако стоит проверить следующие механизмы для тех, кто полностью понимает риск, и все еще намерен выключать питание flash для дополнительного снижения энергопотребления:

● Установка опции CONFIG_ESP_SLEEP_POWER_DOWN_FLASH выключит питание flash только когда таймер RTC является единственным источником пробуждения, и время сна больше, чем период выключенного питания flash.
● Вызов esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_OFF) выключит питание flash, когда таймер RTC не разрешен в качестве источника пробуждения, или время сна дольше, чем период выключенного питания flash.

Замечания:

● ESP-IDF не предоставляет какие-либо механизмы, которые могут выключить питание flash во всех условиях, когда используется режим light sleep.
● Функция esp_deep_sleep_start принудительно выключит питание flash независимо от конфигурации пользователя.

Вход в Light-sleep. После того, как источники пробуждения были сконфигурированы, для входа в режим Light-sleep может использоваться функция esp_light_sleep_start. Также есть возможность входа в Light-sleep, когда не было сконфигурировано ни одного источника пробуждения. В этом случае чип будет бесконечно находиться в режиме Light-sleep, пока не придет сигнал внешнего сброса.

Вход в Deep-sleep. После того, как источники пробуждения были сконфигурированы, для входа в режим Deep-sleep может использоваться функция esp_deep_sleep_start. Также есть возможность в входа Deep-sleep, когда не было сконфигурировано ни одного источника пробуждения. В этом случае чип будет бесконечно находиться в режиме Deep-sleep, пока не придет сигнал внешнего сброса.

[Конфигурирование IO]

Некоторые ножки ввода/вывода ESP32 (IO) снабжены внутренними резисторами подтяжки pullup или pulldown, которые по умолчанию разрешены. Если внешняя схема управляет такой ножкой в режиме Deep-sleep, то может увеличиться ток потребления, который будет протекать через эти резисторы.

Чтобы изолировать (переключить в третье состояние) ножку IO, и тем самым исключить лишний ток потребления, вызовите функцию rtc_gpio_isolate.

В режиме Deep-sleep:

● Цифровые порты GPIO (GPIO6 .. GPIO21) находятся в состоянии высокого сопротивления.

● Ножки RTC GPIO (GPIO0 .. GPIO5) могут быть в следующих состояниях, в зависимости от того, разрешена ли на них функция удержания уровня, или нет:

- Если функция удержания не разрешена, то RTC GPIO останутся в состоянии высокого сопротивления.
- Если функция удержания разрешена, то RTC GPIO сохранят состояние вывода, которое было защелкнуто в момент удержания.

[Обработка вывода UART]

Перед входом в режим сна функция esp_deep_sleep_start сбросит (flush) содержимое всех стеков UART FIFO.

Когда происходит вход в Light-sleep с помощью esp_light_sleep_start, стеки UART FIFO не будут сбрасываться. Вместо этого вывод UART будет приостановлен, и оставшиеся в FIFO символы будут отправлены после выхода из режима Light-sleep.

[Проверка, от чего произошло пробуждение]

Чтобы проверить, какой из источников пробуждения вывел устройство из режима сна, может использоваться функция esp_sleep_get_wakeup_cause.

/**
 * @brief Возможные причины пробуждения
 */
typedef enum
{
   ESP_SLEEP_WAKEUP_UNDEFINED,    //!< В случае deep sleep сброс не был вызван выходом из deep sleep.
   ESP_SLEEP_WAKEUP_ALL,          //!< Не случай пробуждения, используется для запрета всех источников
                                  //   пробуждения вызовом функции esp_sleep_disable_wakeup_source.
   ESP_SLEEP_WAKEUP_EXT0,         //!< Пробуждение было вызвано внешним сигналом, используется RTC_IO.
   ESP_SLEEP_WAKEUP_EXT1,         //!< Пробуждение было вызвано внешним сигналом, используется RTC_CNTL.
   ESP_SLEEP_WAKEUP_TIMER,        //!< Пробуждение от таймера.
   ESP_SLEEP_WAKEUP_TOUCHPAD,     //!< Пробуждение от тачпада.
   ESP_SLEEP_WAKEUP_ULP,          //!< Пробуждение от программы ULP(*).
   ESP_SLEEP_WAKEUP_GPIO,         //!< Пробуждение от GPIO (работает только для light sleep).
   ESP_SLEEP_WAKEUP_UART,         //!< Пробуждение от UART (работает только для light sleep).
   ESP_SLEEP_WAKEUP_WIFI,         //!< Пробуждение от WIFI (работает только для light sleep).
   ESP_SLEEP_WAKEUP_COCPU,             //!< Пробуждение от прерывания COCPU.
   ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG,   //!< Пробуждение от COCPU crash.
   ESP_SLEEP_WAKEUP_BT,           //!< Пробуждение от BT (работает только для light sleep).
} esp_sleep_source_t;
 
/* Этот тип определен для сохранения совместимости */
typedef esp_sleep_source_t esp_sleep_wakeup_cause_t;

Примечание (*): блоком ULP оборудованы не все модели процессоров ESP32, подробнее см. [6].

[Запрет источника пробуждения]

Сконфигурированные ранее источники пробуждения могут быть запрещены позже с помощью API-функции esp_sleep_disable_wakeup_source. Эта функция деактивирует триггер пробуждения для указанного источника. Дополнительно можно запретить все триггеры, если передать в аргументе ESP_SLEEP_WAKEUP_ALL.

[Примеры приложений]

protocols/sntp: реализация базового функционала Deep-sleep, где модуль ESP периодически выводится из сна для получения времени с сервера NTP.
wifi/power_save: реализация примера засыпания модема.
system/deep_sleep: использование таймера для пробуждения из Deep-sleep.

[Справочник по API-функциям Sleep Modes]

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

Функция Описание
esp_sleep_disable_wakeup_source Запрещает источник пробуждения. Эта функция используется для деактивации триггера пробуждения для источника, переданного в аргументе функции. Подробную информацию см. в docs/sleep-modes.rst. Замечание: эта функция не модифицирует конфигурацию пробуждения RTC. Эти модификации выполняют функции esp_deep_sleep_start и esp_light_sleep_start.
esp_sleep_enable_timer_wakeup Разрешает пробуждение от таймера.
esp_sleep_is_valid_wakeup_gpio Вернет true, если указанный номер GPIO допустим в качестве источника пробуждения. Примечание: для кристаллов SoC, обладающим функционалом RTC IO, это может быть любая допустимая ножка входа RTC IO.
esp_deep_sleep_enable_gpio_wakeup Разрешает пробуждение с использованием указанных выводов GPIO. Эта функция разрешает ножке IO выводит чип из режима deep sleep. Замечания: эта функция не модифицирует конфигурацию вывода. Выводы конфигурируются внутри esp_deep_sleep_start, непосредственно перед входом в режим сна. Вам не нужно заботиться о верхней или нижней подтяжке уровня (pull-up или pull-down) перед использованием этой функции, потому что это будет настроено внутри esp_deep_sleep_start на основе выбранного режима пробуждения. Кстати, когда вы используете низкий логический уровень для пробуждения чипа, то строго рекомендуется добавить внешние подтягивающие вверх резисторы (pull-up).
esp_sleep_enable_gpio_wakeup Разрешает пробуждение из Light-Sleep с помощью GPIO. Каждая ножка GPIO поддерживает активацию пробуждения, которое может срабатывать либо от низкого, либо от высокого уровня. В отличие от источников пробуждения EXT0 и EXT1, этот метод может использовать для всех типов ножек IO: RTC IO и digital IO. Пробуждение возможно только из Light-Sleep. Для разрешения пробуждения сначала вызывается gpio_wakeup_enable, где указывается номер ножки GPIO и уровень пробуждения для каждой ножки GPIO. Затем вызывается функция esp_sleep_enable_gpio_wakeup для разрешения работы пробуждения. Примечание: на продвинутом чипе ESP32 источник пробуждения GPIO нельзя использовать вместе с пробуждением от тачпада или от ULP.
esp_sleep_enable_uart_wakeup Разрешает побуждение из Light-Sleep с помощью UART. Для конфигурирования порога пробуждения UART используется функция uart_set_wakeup_threshold. Выход из Light-Sleep требует некоторого времени, так что не каждый символ, отправленный в UART, может быть принят приложением. Примечание: ESP32 не поддерживает пробуждение от UART2.
esp_sleep_enable_bt_wakeup Разрешает пробуждение от Bluetooth.
esp_sleep_disable_bt_wakeup Запрещает пробуждение от Bluetooth.
esp_sleep_enable_wifi_wakeup Разрешает пробуждение от WiFi MAC.
esp_sleep_disable_wifi_wakeup Запрещает пробуждение от WiFi MAC.
esp_sleep_get_ext1_wakeup_status Получит битовую маску ножек GPIO, которые вызвали пробуждение (ext1). Если пробуждение произошло от другого источника, то эта функция вернет 0.
esp_sleep_get_gpio_wakeup_status Получит битовую маску ножек GPIO, которые привели к пробуждению. Если пробуждение произошло от другого источника, то эта функция вернет 0.
esp_sleep_pd_config Установит режим выключения (power down mode) для домена питания RTC в режиме сна. Если с помощью этого API-вызова ничего не было установлено, то по умолчанию у всех доменов питания используется режим ESP_PD_OPTION_AUTO.
esp_deep_sleep_start Вход в Deep-Sleep с опциями пробуждения, которые были предварительно сконфигурированы. Из этой функции не будет произведен возврат, потому что пробуждение произойдет по вектору сброса (начиная с запуска ROM-загрузчика).
esp_light_sleep_start Вход в Light-Sleep с опциями пробуждения, которые были предварительно сконфигурированы.
esp_deep_sleep Вход в режим Deep-Sleep. Устройство автоматически выйдет из режима глубокого сна после истечения интервала времени, указанного в параметре. После пробуждения устройство вызовет заглушку глубокого сна (deep sleep wake stub), и затем перейдет к загрузке приложения. Вызов esp_deep_sleep эквивалентен вызову esp_deep_sleep_enable_timer_wakeup, за которым следует вызов esp_deep_sleep_start. Функция esp_deep_sleep не выключит корректно WiFi, BT и соединения высокоуровневого протокола. Убедитесь, что предварительно были вызваны соответствующие функции стека WiFi и BT, чтобы были закрыты любые соединения и отменена инициализация периферийных устройств (это включает esp_bluedroid_disable, esp_bt_controller_disable, esp_wifi_stop). Из функции esp_deep_sleep не будет выполнен возврат.
esp_sleep_get_wakeup_cause Выдаст информацию по источнику, от которого произошло пробуждение.
esp_wake_deep_sleep Заглушка по умолчанию для запуска при выходе из режима Deep-Sleep. Позволяет запустить некоторый код немедленно после выхода из сна, до момента запуска программного загрузчика (загрузчик второго уровня) или приложения ESP-IDF. Эта функция линкуется в режиме weak, т. е. она может быть переопределена разработчиком. Подробную информацию см. в docs/deep-sleep-stub.rst.
esp_set_deep_sleep_wake_stub Установит новую заглушку во время выполнения кода (runtime), чтобы она запустилась при выходе устройства из Deep-Sleep. Если разработчиком переопределена функция esp_wake_deep_sleep, то не нужно вызывать функцию esp_set_deep_sleep_wake_stub. Однако все-таки её вызвать можно, чтобы установить другую заглушку. Любая функция, которая используется как заглушка выхода из глубокого сна (deep sleep stub), должна быть помечена атрибутом RTC_IRAM_ATTR, и должна соблюдать те же правила, что и esp_wake_deep_sleep.
esp_get_deep_sleep_wake_stub Получает текущее пробуждение от deep sleep stub.
esp_default_wake_deep_sleep Заглушка по умолчанию для esp_wake_deep_sleep, предоставленная средой разработки ESP-IDF. Подробную информацию см. в docs/deep-sleep-stub.rst.
esp_deep_sleep_disable_rom_logging Запретит вывод в лог из кода ROM после Deep-Sleep, использует младший бит (LSB) из RTC_STORE4.
esp_sleep_cpu_pd_low_init Инициализация низкого уровня CPU Power down, разрешает или запрещает выключение CPU во время light sleep.
esp_sleep_config_gpio_isolate Конфигурирует третье состояние всех ножек GPIO для режима сна.
esp_sleep_enable_gpio_switch Разрешает или запрещает состояние переключения ножек GPIO между сном и пробуждением.

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

[Ссылки]

1. ESP32-C3 Sleep Modes site:docs.espressif.com.
2. ESP32-C3 System Time site:docs.espressif.com.
3. ESP32: режимы пониженного энергопотребления.
4. ESP32-C3 Power Management site:docs.espressif.com.
5. ESP32-C3: GPIO и RTC GPIO.
6ESP32: программирование сопроцессора ULP.

 

Добавить комментарий


Защитный код
Обновить

Top of Page