1Deep Sleep Wake Stubs 2===================== 3 4{IDF_TARGET_NAME} supports running a "deep sleep wake stub" when coming out of deep sleep. This function runs immediately as soon as the chip wakes up - before any normal initialisation, bootloader, or ESP-IDF code has run. After the wake stub runs, the SoC can go back to sleep or continue to start ESP-IDF normally. 5 6Deep sleep wake stub code is loaded into "RTC Fast Memory" and any data which it uses must also be loaded into RTC memory. RTC memory regions hold their contents during deep sleep. 7 8Rules for Wake Stubs 9-------------------- 10 11Wake stub code must be carefully written: 12 13* As the SoC has freshly woken from sleep, most of the peripherals are in reset states. The SPI flash is unmapped. 14 15* The wake stub code can only call functions implemented in ROM or loaded into RTC Fast Memory (see below.) 16 17* The wake stub code can only access data loaded in RTC memory. All other RAM will be unintiailised and have random contents. The wake stub can use other RAM for temporary storage, but the contents will be overwritten when the SoC goes back to sleep or starts ESP-IDF. 18 19* RTC memory must include any read-only data (.rodata) used by the stub. 20 21* Data in RTC memory is initialised whenever the SoC restarts, except when waking from deep sleep. When waking from deep sleep, the values which were present before going to sleep are kept. 22 23* Wake stub code is a part of the main esp-idf app. During normal running of esp-idf, functions can call the wake stub functions or access RTC memory. It is as if these were regular parts of the app. 24 25Implementing A Stub 26------------------- 27 28The wake stub in esp-idf is called ``esp_wake_deep_sleep()``. This function runs whenever the SoC wakes from deep sleep. There is a default version of this function provided in esp-idf, but the default function is weak-linked so if your app contains a function named ``esp_wake_deep_sleep()`` then this will override the default. 29 30If supplying a custom wake stub, the first thing it does should be to call ``esp_default_wake_deep_sleep()``. 31 32It is not necessary to implement ``esp_wake_deep_sleep()`` in your app in order to use deep sleep. It is only necessary if you want to have special behaviour immediately on wake. 33 34If you want to swap between different deep sleep stubs at runtime, it is also possible to do this by calling the ``esp_set_deep_sleep_wake_stub()`` function. This is not necessary if you only use the default ``esp_wake_deep_sleep()`` function. 35 36All of these functions are declared in the ``esp_sleep.h`` header under components/{IDF_TARGET_PATH_NAME}. 37 38Loading Code Into RTC Memory 39---------------------------- 40 41Wake stub code must be resident in RTC Fast Memory. This can be done in one of two ways. 42 43The first way is to use the ``RTC_IRAM_ATTR`` attribute to place a function into RTC memory:: 44 45 void RTC_IRAM_ATTR esp_wake_deep_sleep(void) { 46 esp_default_wake_deep_sleep(); 47 // Add additional functionality here 48 } 49 50The second way is to place the function into any source file whose name starts with ``rtc_wake_stub``. Files names ``rtc_wake_stub*`` have their contents automatically put into RTC memory by the linker. 51 52The first way is simpler for very short and simple code, or for source files where you want to mix "normal" and "RTC" code. The second way is simpler when you want to write longer pieces of code for RTC memory. 53 54 55Loading Data Into RTC Memory 56---------------------------- 57 58Data used by stub code must be resident in RTC memory. 59 60.. only:: SOC_RTC_SLOW_MEM_SUPPORTED 61 62 The data can be placed in RTC Fast memory or in RTC Slow memory which is also used by the ULP. 63 64Specifying this data can be done in one of two ways: 65 66The first way is to use the ``RTC_DATA_ATTR`` and ``RTC_RODATA_ATTR`` to specify any data (writeable or read-only, respectively) which should be loaded into RTC memory:: 67 68 RTC_DATA_ATTR int wake_count; 69 70 void RTC_IRAM_ATTR esp_wake_deep_sleep(void) { 71 esp_default_wake_deep_sleep(); 72 static RTC_RODATA_ATTR const char fmt_str[] = "Wake count %d\n"; 73 esp_rom_printf(fmt_str, wake_count++); 74 } 75 76.. only:: SOC_RTC_SLOW_MEM_SUPPORTED 77 78 The RTC memory area where this data will be placed can be configured via menuconfig option named ``CONFIG_{IDF_TARGET_CFG_PREFIX}_RTCDATA_IN_FAST_MEM``. This option allows to keep slow memory area for ULP programs and once it is enabled the data marked with ``RTC_DATA_ATTR`` and ``RTC_RODATA_ATTR`` are placed in the RTC fast memory segment otherwise it goes to RTC slow memory (default option). This option depends on the ``CONFIG_FREERTOS_UNICORE`` because RTC fast memory can be accessed only by PRO_CPU. 79 80 The attributes ``RTC_FAST_ATTR`` and ``RTC_SLOW_ATTR`` can be used to specify data that will be force placed into RTC_FAST and RTC_SLOW memory respectively. Any access to data marked with ``RTC_FAST_ATTR`` is allowed by PRO_CPU only and it is responsibility of user to make sure about it. 81 82.. only:: not SOC_RTC_SLOW_MEM_SUPPORTED 83 84 The attributes ``RTC_FAST_ATTR`` and ``RTC_SLOW_ATTR`` can be used to specify data that will be force placed into RTC_FAST and RTC_SLOW memory respectively, but for {IDF_TARGET_NAME} there is only RTC fast memory, so both attributes will map to this region. 85 86 87Unfortunately, any string constants used in this way must be declared as arrays and marked with RTC_RODATA_ATTR, as shown in the example above. 88 89The second way is to place the data into any source file whose name starts with ``rtc_wake_stub``. 90 91For example, the equivalent example in ``rtc_wake_stub_counter.c``:: 92 93 int wake_count; 94 95 void RTC_IRAM_ATTR esp_wake_deep_sleep(void) { 96 esp_default_wake_deep_sleep(); 97 esp_rom_printf("Wake count %d\n", wake_count++); 98 } 99 100The second way is a better option if you need to use strings, or write other more complex code. 101 102To reduce wake-up time use the `CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP` Kconfig option, see more information in :doc:`Fast boot from Deep Sleep <bootloader>`. 103 104CRC Check For Wake Stubs 105------------------------ 106 107.. only:: SOC_PM_SUPPORT_DEEPSLEEP_VERIFY_STUB_ONLY 108 109 During deep sleep, only the wake stubs area of RTC Fast memory is validated with CRC. When {IDF_TARGET_NAME} wakes up from deep sleep, the wake stubs area is validated again. If the validation passes, the wake stubs code will be executed. Otherwise, the normal initialization, bootloader, and esp-idf codes will be executed. 110 111.. only:: not SOC_PM_SUPPORT_DEEPSLEEP_VERIFY_STUB_ONLY 112 113 During deep sleep, all RTC Fast memory areas will be validated with CRC. When {IDF_TARGET_NAME} wakes up from deep sleep, the RTC fast memory will be validated with CRC again. If the validation passes, the wake stubs code will be executed. Otherwise, the normal initialization, bootloader and esp-idf codes will be executed. 114 115.. note:: 116 117 When the `CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP` option is enabled, all the RTC fast memory except the wake stubs area is added to the heap. 118