Posted at

arduino-esp32 で esp_sleep_enable_timer_wakeup と esp_deep_sleep の違いは何か?

Arduino 環境で ESP32 を使うとき、deepsleepに入るのに


esp_sleep_enable_timer_wakeup(1000*1000*1000); // 1000秒 deep sleep


esp_deep_sleep(1000*1000*1000); // 1000秒 deep sleep

の2つがある。この2つはパラメータも同じだし、何が違うの? という質問を受けた。

arduino-esp32 を作っているのは espressif だから、 espressif のドキュメント見りゃイイヨ! と無責任に言ったけど、ちゃんと調べてみた・・・


ドキュメント確認

https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/sleep_modes.html


Timer

RTC controller has a built in timer which can be used to wake up the chip after a predefined amount of time. Time is specified at > microsecond precision, but the actual resolution depends on the clock source selected for RTC SLOW_CLK. See chapter “Reset and Clock” of the ESP32 Technical Reference Manual for details about RTC clock options.

This wakeup mode doesn’t require RTC peripherals or RTC memories to be powered on during sleep.

esp_sleep_enable_timer_wakeup()function can be used to enable deep sleep wakeup using a timer.

Entering deep sleep

esp_deep_sleep_start()function can be used to enter deep sleep once wakeup sources are configured. It is also possible to go into deep sleep with no wakeup sources configured, in this case the chip will be in deep sleep mode indefinitely, until external reset is applied.


ということで、esp_sleep_enable_timer_wakeup をしたあとに esp_deep_sleep_start することで deep sleepに入るらしい。

それに対し、


void esp_deep_sleep(uint64_t time_in_us)

Enter deep-sleep mode.

The device will automatically wake up after the deep-sleep time Upon waking up, the device calls deep sleep wake stub, and then proceeds to load application.

Call to this function is equivalent to a call to esp_deep_sleep_enable_timer_wakeup followed by a call to esp_deep_sleep_start.

esp_deep_sleep does not shut down WiFi, BT, and higher level protocol connections gracefully. Make sure relevant WiFi and BT stack functions are called to close any connections and deinitialize the peripherals. These include:

esp_bluedroid_disable

esp_bt_controller_disable

esp_wifi_stop

This function does not return.

?Parameters

time_in_us: deep-sleep time, unit: microsecond


ということで、esp_deep_sleep は call to esp_deep_sleep_enable_timer_wakeup followed by a call to esp_deep_sleep_start としているらしい。

とはいうものの、これって arduino-esp32 でも同じかな?


arduino-esp32 コード確認

以下からソースをダウンロードして見てみる。

https://github.com/espressif/arduino-esp32

関連してそうなのは以下の3つ。

tools/sdk/include/esp32/esp_sleep.h:esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us);

tools/sdk/include/esp32/esp_sleep.h:void esp_deep_sleep(uint64_t time_in_us) attribute((noreturn));

tools/sdk/include/esp32/esp_deep_sleep.h:inline static esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us)

このうちの、esp_deep_sleepは以下のようになっていて中身はesp_sleep_enable_timer_wakeup。


inline static esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us)
{
return esp_sleep_enable_timer_wakeup(time_in_us);
}

そして、tools/sdk/include/esp32/esp_sleep.h には以下のようにドキュメントと同じことが書いてある。


/**
* @brief Enter deep-sleep mode
*
* The device will automatically wake up after the deep-sleep time
* Upon waking up, the device calls deep sleep wake stub, and then proceeds
* to load application.
*
* Call to this function is equivalent to a call to esp_deep_sleep_enable_timer_wakeup
* followed by a call to esp_deep_sleep_start.
*
* esp_deep_sleep does not shut down WiFi, BT, and higher level protocol
* connections gracefully.
* Make sure relevant WiFi and BT stack functions are called to close any
* connections and deinitialize the peripherals. These include:
* - esp_bluedroid_disable
* - esp_bt_controller_disable
* - esp_wifi_stop
*
* This function does not return.
*
* @param time_in_us deep-sleep time, unit: microsecond
*/
void esp_deep_sleep(uint64_t time_in_us) __attribute__((noreturn));

しかしながらこのレポジトリには .h ファイルだけで、実際のコードが書いてある .C ファイルは見つからない。

arduino-esp32では、コンパイル済みライブラリとして tools/sdk/lib/libesp32.a

に収容されていた。ではこのライブラリのソースはどこにあるか?


esp-idf コード確認

ここかな?

https://github.com/espressif/esp-idf

これから、components/esp32/sleep_modes.c の中身を見てみる。


esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
{
s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN;
s_config.sleep_duration = time_in_us;
return ESP_OK;
}


void esp_deep_sleep(uint64_t time_in_us)
{
esp_sleep_enable_timer_wakeup(time_in_us);
esp_deep_sleep_start();
}

なるほどね。