diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index 90813a16f5..ed23aac6b5 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -477,6 +477,11 @@ typedef void (*esp_deep_sleep_wake_stub_fn_t)(void); */ void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub); +/** + * @brief Set wake stub entry to default `esp_wake_stub_entry` + */ +void esp_set_deep_sleep_wake_stub_default_entry(void); + /** * @brief Get current wake from deep sleep stub * @return Return current wake from deep sleep stub, or NULL if diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index f97991241b..d2f36ee43a 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -263,6 +263,19 @@ static void __attribute__((section(".rtc.entry.text"))) esp_wake_stub_entry(void #endif } + +void RTC_IRAM_ATTR esp_set_deep_sleep_wake_stub_default_entry(void) +{ + extern char _rtc_text_start[]; +#if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM + extern char _rtc_noinit_end[]; + size_t rtc_fast_length = (size_t)_rtc_noinit_end - (size_t)_rtc_text_start; +#else + extern char _rtc_force_fast_end[]; + size_t rtc_fast_length = (size_t)_rtc_force_fast_end - (size_t)_rtc_text_start; +#endif + esp_rom_set_rtc_wake_addr((esp_rom_wake_func_t)esp_wake_stub_entry, rtc_fast_length); +} #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY /* Wake from deep sleep stub @@ -281,7 +294,13 @@ esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void) return stub_ptr; } -void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub) +#if CONFIG_IDF_TARGET_ESP32 +/* APP core of esp32 can't access to RTC FAST MEMORY, do not define it with RTC_IRAM_ATTR */ +void +#else +void RTC_IRAM_ATTR +#endif +esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub) { #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY wake_stub_fn_handler = new_stub; @@ -548,15 +567,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo #endif #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY - extern char _rtc_text_start[]; -#if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM - extern char _rtc_noinit_end[]; - size_t rtc_fast_length = (size_t)_rtc_noinit_end - (size_t)_rtc_text_start; -#else - extern char _rtc_force_fast_end[]; - size_t rtc_fast_length = (size_t)_rtc_force_fast_end - (size_t)_rtc_text_start; -#endif - esp_rom_set_rtc_wake_addr((esp_rom_wake_func_t)esp_wake_stub_entry, rtc_fast_length); + esp_set_deep_sleep_wake_stub_default_entry(); // Enter Deep Sleep #if SOC_PMU_SUPPORTED result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep); diff --git a/components/esp_hw_support/sleep_wake_stub.c b/components/esp_hw_support/sleep_wake_stub.c index 29779160d7..7c49241ba9 100644 --- a/components/esp_hw_support/sleep_wake_stub.c +++ b/components/esp_hw_support/sleep_wake_stub.c @@ -50,19 +50,19 @@ void RTC_IRAM_ATTR esp_wake_stub_sleep(esp_deep_sleep_wake_stub_fn_t new_stub) { -#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY - extern char _rtc_text_start[]; - #if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM - extern char _rtc_noinit_end[]; - size_t rtc_fast_length = (size_t)_rtc_noinit_end - (size_t)_rtc_text_start; - #else - extern char _rtc_force_fast_end[]; - size_t rtc_fast_length = (size_t)_rtc_force_fast_end - (size_t)_rtc_text_start; - #endif // CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM - esp_rom_set_rtc_wake_addr((esp_rom_wake_func_t)new_stub, rtc_fast_length); -#else - // Set the pointer of the wake stub function. + +#if CONFIG_IDF_TARGET_ESP32 + // Since the app core of esp32 does not support access to RTC_FAST_MEMORY, + // `esp_set_deep_sleep_wake_stub` is not declared in RTC_FAST_MEMORY, + // so we cannot call it here REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub); +#else + esp_set_deep_sleep_wake_stub(new_stub); +#endif + +#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY + esp_set_deep_sleep_wake_stub_default_entry(); +#else set_rtc_memory_crc(); #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_MEM diff --git a/components/esp_rom/include/esp32c6/rom/rtc.h b/components/esp_rom/include/esp32c6/rom/rtc.h index 3fba551945..6a046fa25a 100644 --- a/components/esp_rom/include/esp32c6/rom/rtc.h +++ b/components/esp_rom/include/esp32c6/rom/rtc.h @@ -178,6 +178,8 @@ typedef void (* esp_rom_wake_func_t)(void); * @brief Read stored RTC wake function address * * Returns pointer to wake address if a value is set in RTC registers, and stored length & CRC all valid. + * valid means that both stored stub length and stored wake function address are four-byte aligned non-zero values + * and the crc check passes * * @param None * @@ -191,8 +193,11 @@ esp_rom_wake_func_t esp_rom_get_rtc_wake_addr(void); * Set a new RTC wake address function. If a non-NULL function pointer is set then the function * memory is calculated and stored also. * - * @param entry_addr Address of function. If NULL, length is ignored and all registers are cleared to 0. - * @param length of function in RTC fast memory. cannot be larger than RTC Fast memory size. + * @param entry_addr Address of function. should be 4-bytes aligned otherwise it will not start from the stub after wake from deepsleep, + * if NULL length will be ignored and all registers are cleared to 0. + * + * @param length length of function in RTC fast memory. should be less than RTC Fast memory size and aligned to 4-bytes. + * otherwise all registers are cleared to 0. * * @return None */ diff --git a/components/esp_rom/include/esp32h2/rom/rtc.h b/components/esp_rom/include/esp32h2/rom/rtc.h index 4bfa6b7533..1a89e39891 100644 --- a/components/esp_rom/include/esp32h2/rom/rtc.h +++ b/components/esp_rom/include/esp32h2/rom/rtc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -175,6 +175,8 @@ typedef void (* esp_rom_wake_func_t)(void); * @brief Read stored RTC wake function address * * Returns pointer to wake address if a value is set in RTC registers, and stored length & CRC all valid. + * valid means that both stored stub length and stored wake function address are four-byte aligned non-zero values + * and the crc check passes * * @param None * @@ -188,8 +190,11 @@ esp_rom_wake_func_t esp_rom_get_rtc_wake_addr(void); * Set a new RTC wake address function. If a non-NULL function pointer is set then the function * memory is calculated and stored also. * - * @param entry_addr Address of function. If NULL, length is ignored and all registers are cleared to 0. - * @param length of function in RTC fast memory. cannot be larger than RTC Fast memory size. + * @param entry_addr Address of function. should be 4-bytes aligned otherwise it will not start from the stub after wake from deepsleep, + * if NULL length will be ignored and all registers are cleared to 0. + * + * @param length length of function in RTC fast memory. should be less than RTC Fast memory size and aligned to 4-bytes. + * otherwise all registers are cleared to 0. * * @return None */ diff --git a/components/esp_rom/include/esp32h4/rom/rtc.h b/components/esp_rom/include/esp32h4/rom/rtc.h index 8499f1b052..ed529a5e40 100644 --- a/components/esp_rom/include/esp32h4/rom/rtc.h +++ b/components/esp_rom/include/esp32h4/rom/rtc.h @@ -175,6 +175,8 @@ typedef void (* esp_rom_wake_func_t)(void); * @brief Read stored RTC wake function address * * Returns pointer to wake address if a value is set in RTC registers, and stored length & CRC all valid. + * valid means that both stored stub length and stored wake function address are four-byte aligned non-zero values + * and the crc check passes * * @param None * @@ -188,8 +190,11 @@ esp_rom_wake_func_t esp_rom_get_rtc_wake_addr(void); * Set a new RTC wake address function. If a non-NULL function pointer is set then the function * memory is calculated and stored also. * - * @param entry_addr Address of function. If NULL, length is ignored and all registers are cleared to 0. - * @param length of function in RTC fast memory. cannot be larger than RTC Fast memory size. + * @param entry_addr Address of function. should be 4-bytes aligned otherwise it will not start from the stub after wake from deepsleep, + * if NULL length will be ignored and all registers are cleared to 0. + * + * @param length length of function in RTC fast memory. should be less than RTC Fast memory size and aligned to 4-bytes. + * otherwise all registers are cleared to 0. * * @return None */ diff --git a/components/esp_rom/include/esp32s3/rom/rtc.h b/components/esp_rom/include/esp32s3/rom/rtc.h index 168ca7997a..daa6ff0eec 100644 --- a/components/esp_rom/include/esp32s3/rom/rtc.h +++ b/components/esp_rom/include/esp32s3/rom/rtc.h @@ -173,6 +173,8 @@ typedef void (* esp_rom_wake_func_t)(void); * @brief Read stored RTC wake function address * * Returns pointer to wake address if a value is set in RTC registers, and stored length & CRC all valid. + * valid means that both stored stub length and stored wake function address are four-byte aligned non-zero values + * and the crc check passes * * @param None * @@ -186,8 +188,11 @@ esp_rom_wake_func_t esp_rom_get_rtc_wake_addr(void); * Set a new RTC wake address function. If a non-NULL function pointer is set then the function * memory is calculated and stored also. * - * @param entry_addr Address of function. If NULL, length is ignored and all registers are cleared to 0. - * @param length of function in RTC fast memory. cannot be larger than RTC Fast memory size. + * @param entry_addr Address of function. should be 4-bytes aligned otherwise it will not start from the stub after wake from deepsleep, + * if NULL length will be ignored and all registers are cleared to 0. + * + * @param length length of function in RTC fast memory. should be less than RTC Fast memory size and aligned to 4-bytes. + * otherwise all registers are cleared to 0. * * @return None */ diff --git a/examples/system/deep_sleep_wake_stub/main/rtc_wake_stub_example.c b/examples/system/deep_sleep_wake_stub/main/rtc_wake_stub_example.c index 6ae8c4156c..628af418c1 100644 --- a/examples/system/deep_sleep_wake_stub/main/rtc_wake_stub_example.c +++ b/examples/system/deep_sleep_wake_stub/main/rtc_wake_stub_example.c @@ -34,7 +34,7 @@ static const uint32_t s_max_count = 20; static uint32_t wakeup_cause; // wake up stub function stored in RTC memory -void __attribute__((aligned(4))) wake_stub_example(void) +void wake_stub_example(void) { // Get wakeup cause. wakeup_cause = esp_wake_stub_get_wakeup_cause(); diff --git a/examples/system/deep_sleep_wake_stub/main/wake_stub_example_main.c b/examples/system/deep_sleep_wake_stub/main/wake_stub_example_main.c index 47e49bc939..59262477b4 100644 --- a/examples/system/deep_sleep_wake_stub/main/wake_stub_example_main.c +++ b/examples/system/deep_sleep_wake_stub/main/wake_stub_example_main.c @@ -43,7 +43,6 @@ void app_main(void) rtc_gpio_isolate(GPIO_NUM_12); #endif - // Set the wake stub function esp_set_deep_sleep_wake_stub(&wake_stub_example); printf("Entering deep sleep\n");