mirror of
https://github.com/espressif/esp-idf.git
synced 2024-09-21 06:56:11 -04:00
feat: support cache safe assertion check in sleep process
- Add support for cache safe assertion check to ensure that code expected to be in RAM is in IRAM
This commit is contained in:
parent
12dca8d086
commit
54a15b81f9
@ -192,6 +192,17 @@ menu "Hardware Settings"
|
|||||||
|
|
||||||
NOTE: Enabling these callbacks may change sleep duration calculations based on time spent in
|
NOTE: Enabling these callbacks may change sleep duration calculations based on time spent in
|
||||||
callback and hence it is highly recommended to keep them as short as possible.
|
callback and hence it is highly recommended to keep them as short as possible.
|
||||||
|
|
||||||
|
config ESP_SLEEP_CACHE_SAFE_ASSERTION
|
||||||
|
bool "Check the cache safety of the sleep wakeup code in sleep process"
|
||||||
|
default n
|
||||||
|
select ESP_PANIC_HANDLER_IRAM
|
||||||
|
help
|
||||||
|
Enabling it will check the cache safety of the code before the flash power is ready after
|
||||||
|
light sleep wakeup, and check PM_SLP_IRAM_OPT related code cache safety. This option is
|
||||||
|
only for code quality inspection. Enabling it will increase the time overhead of entering
|
||||||
|
and exiting sleep. It is not recommended to enable it in the release version.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "ESP_SLEEP_WORKAROUND"
|
menu "ESP_SLEEP_WORKAROUND"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -404,6 +404,23 @@ void esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb)
|
|||||||
portEXIT_CRITICAL(&spinlock_rtc_deep_sleep);
|
portEXIT_CRITICAL(&spinlock_rtc_deep_sleep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int s_cache_suspend_cnt = 0;
|
||||||
|
|
||||||
|
static void IRAM_ATTR suspend_cache(void) {
|
||||||
|
s_cache_suspend_cnt++;
|
||||||
|
if (s_cache_suspend_cnt == 1) {
|
||||||
|
cache_hal_suspend(CACHE_TYPE_ALL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void IRAM_ATTR resume_cache(void) {
|
||||||
|
s_cache_suspend_cnt--;
|
||||||
|
assert(s_cache_suspend_cnt >= 0 && "cache resume doesn't match suspend ops");
|
||||||
|
if (s_cache_suspend_cnt == 0) {
|
||||||
|
cache_hal_resume(CACHE_TYPE_ALL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// [refactor-todo] provide target logic for body of uart functions below
|
// [refactor-todo] provide target logic for body of uart functions below
|
||||||
static void IRAM_ATTR flush_uarts(void)
|
static void IRAM_ATTR flush_uarts(void)
|
||||||
{
|
{
|
||||||
@ -477,7 +494,12 @@ static bool light_sleep_uart_prepare(uint32_t pd_flags, int64_t sleep_duration)
|
|||||||
#if !SOC_PM_SUPPORT_TOP_PD || !CONFIG_ESP_CONSOLE_UART
|
#if !SOC_PM_SUPPORT_TOP_PD || !CONFIG_ESP_CONSOLE_UART
|
||||||
suspend_uarts();
|
suspend_uarts();
|
||||||
#else
|
#else
|
||||||
if (pd_flags & PMU_SLEEP_PD_TOP) {
|
#ifdef CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION
|
||||||
|
#define FORCE_FLUSH_CONSOLE_UART 1
|
||||||
|
#else
|
||||||
|
#define FORCE_FLUSH_CONSOLE_UART 0
|
||||||
|
#endif
|
||||||
|
if (FORCE_FLUSH_CONSOLE_UART || (pd_flags & PMU_SLEEP_PD_TOP)) {
|
||||||
if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) &&
|
if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) &&
|
||||||
// +1 is for cover the last character flush time
|
// +1 is for cover the last character flush time
|
||||||
(sleep_duration < (int64_t)((UART_LL_FIFO_DEF_LEN - uart_ll_get_txfifo_len(CONSOLE_UART_DEV) + 1) * UART_FLUSH_US_PER_CHAR) + SLEEP_UART_FLUSH_DONE_TO_SLEEP_US)) {
|
(sleep_duration < (int64_t)((UART_LL_FIFO_DEF_LEN - uart_ll_get_txfifo_len(CONSOLE_UART_DEV) + 1) * UART_FLUSH_US_PER_CHAR) + SLEEP_UART_FLUSH_DONE_TO_SLEEP_US)) {
|
||||||
@ -775,8 +797,8 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
|||||||
#endif
|
#endif
|
||||||
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
|
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
|
||||||
} else {
|
} else {
|
||||||
/* Wait cache idle in cache suspend to avoid cache load wrong data after spi io isolation */
|
/* Cache Suspend 1: will wait cache idle in cache suspend to avoid cache load wrong data after spi io isolation */
|
||||||
cache_hal_suspend(CACHE_TYPE_ALL);
|
suspend_cache();
|
||||||
/* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
|
/* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
|
||||||
In order to avoid the leakage of the SPI cs pin, hold it here */
|
In order to avoid the leakage of the SPI cs pin, hold it here */
|
||||||
#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND)
|
#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND)
|
||||||
@ -809,8 +831,8 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
/* Resume cache for continue running */
|
/* Cache Resume 1: Resume cache for continue running*/
|
||||||
cache_hal_resume(CACHE_TYPE_ALL);
|
resume_cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
|
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
|
||||||
@ -820,6 +842,14 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION
|
||||||
|
if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
|
||||||
|
/* Cache Suspend 2: If previous sleep powerdowned the flash, suspend cache here so that the
|
||||||
|
access to flash before flash ready can be explicitly exposed. */
|
||||||
|
suspend_cache();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Restore CPU frequency
|
// Restore CPU frequency
|
||||||
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
|
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
|
||||||
if (pmu_sleep_pll_already_enabled()) {
|
if (pmu_sleep_pll_already_enabled()) {
|
||||||
@ -1009,6 +1039,13 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags,
|
|||||||
esp_rom_delay_us(flash_enable_time_us);
|
esp_rom_delay_us(flash_enable_time_us);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION
|
||||||
|
if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
|
||||||
|
/* Cache Resume 2: flash is ready now, we can resume the cache and access flash safely after */
|
||||||
|
resume_cache();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return reject;
|
return reject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
CONFIG_PM_SLP_IRAM_OPT=y
|
||||||
|
CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y
|
||||||
|
CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION=y
|
Loading…
Reference in New Issue
Block a user