refactor: always jump to wake stub wrapper after wakeup

This commit is contained in:
wuzhenghui
2023-02-24 13:53:38 +08:00
parent 38c4910996
commit 7ee64bd8e8
9 changed files with 68 additions and 33 deletions

View File

@@ -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); 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 * @brief Get current wake from deep sleep stub
* @return Return current wake from deep sleep stub, or NULL if * @return Return current wake from deep sleep stub, or NULL if

View File

@@ -263,6 +263,19 @@ static void __attribute__((section(".rtc.entry.text"))) esp_wake_stub_entry(void
#endif #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 #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
/* Wake from deep sleep stub /* 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; 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 #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
wake_stub_fn_handler = new_stub; 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 #endif
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
extern char _rtc_text_start[]; esp_set_deep_sleep_wake_stub_default_entry();
#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);
// Enter Deep Sleep // Enter Deep Sleep
#if SOC_PMU_SUPPORTED #if SOC_PMU_SUPPORTED
result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep); result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);

View File

@@ -50,19 +50,19 @@
void RTC_IRAM_ATTR esp_wake_stub_sleep(esp_deep_sleep_wake_stub_fn_t new_stub) 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_IDF_TARGET_ESP32
#if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM // Since the app core of esp32 does not support access to RTC_FAST_MEMORY,
extern char _rtc_noinit_end[]; // `esp_set_deep_sleep_wake_stub` is not declared in RTC_FAST_MEMORY,
size_t rtc_fast_length = (size_t)_rtc_noinit_end - (size_t)_rtc_text_start; // so we cannot call it here
#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.
REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub); 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(); set_rtc_memory_crc();
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_MEM #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_MEM

View File

@@ -178,6 +178,8 @@ typedef void (* esp_rom_wake_func_t)(void);
* @brief Read stored RTC wake function address * @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. * 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 * @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 * Set a new RTC wake address function. If a non-NULL function pointer is set then the function
* memory is calculated and stored also. * 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 entry_addr Address of function. should be 4-bytes aligned otherwise it will not start from the stub after wake from deepsleep
* @param length of function in RTC fast memory. cannot be larger than RTC Fast memory size. * 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 * @return None
*/ */

View File

@@ -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 * 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 * @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. * 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 * @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 * Set a new RTC wake address function. If a non-NULL function pointer is set then the function
* memory is calculated and stored also. * 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 entry_addr Address of function. should be 4-bytes aligned otherwise it will not start from the stub after wake from deepsleep
* @param length of function in RTC fast memory. cannot be larger than RTC Fast memory size. * 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 * @return None
*/ */

View File

@@ -175,6 +175,8 @@ typedef void (* esp_rom_wake_func_t)(void);
* @brief Read stored RTC wake function address * @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. * 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 * @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 * Set a new RTC wake address function. If a non-NULL function pointer is set then the function
* memory is calculated and stored also. * 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 entry_addr Address of function. should be 4-bytes aligned otherwise it will not start from the stub after wake from deepsleep
* @param length of function in RTC fast memory. cannot be larger than RTC Fast memory size. * 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 * @return None
*/ */

View File

@@ -173,6 +173,8 @@ typedef void (* esp_rom_wake_func_t)(void);
* @brief Read stored RTC wake function address * @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. * 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 * @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 * Set a new RTC wake address function. If a non-NULL function pointer is set then the function
* memory is calculated and stored also. * 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 entry_addr Address of function. should be 4-bytes aligned otherwise it will not start from the stub after wake from deepsleep
* @param length of function in RTC fast memory. cannot be larger than RTC Fast memory size. * 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 * @return None
*/ */

View File

@@ -34,7 +34,7 @@ static const uint32_t s_max_count = 20;
static uint32_t wakeup_cause; static uint32_t wakeup_cause;
// wake up stub function stored in RTC memory // wake up stub function stored in RTC memory
void __attribute__((aligned(4))) wake_stub_example(void) void wake_stub_example(void)
{ {
// Get wakeup cause. // Get wakeup cause.
wakeup_cause = esp_wake_stub_get_wakeup_cause(); wakeup_cause = esp_wake_stub_get_wakeup_cause();

View File

@@ -43,7 +43,6 @@ void app_main(void)
rtc_gpio_isolate(GPIO_NUM_12); rtc_gpio_isolate(GPIO_NUM_12);
#endif #endif
// Set the wake stub function
esp_set_deep_sleep_wake_stub(&wake_stub_example); esp_set_deep_sleep_wake_stub(&wake_stub_example);
printf("Entering deep sleep\n"); printf("Entering deep sleep\n");