forked from espressif/esp-idf
feat: support cache safe assertion check
- Add support for cache safe assertion check to ensure that code expected to be in RAM is in IRAM
This commit is contained in:
@@ -155,6 +155,16 @@ menu "Hardware Settings"
|
|||||||
|
|
||||||
If you are seeing "flash read err, 1000" message printed to the
|
If you are seeing "flash read err, 1000" message printed to the
|
||||||
console after deep sleep reset, try increasing this value.
|
console after deep sleep reset, try increasing this value.
|
||||||
|
|
||||||
|
config ESP_SLEEP_CACHE_SAFE_ASSERTION
|
||||||
|
bool "Check the cache safety of the sleep wakeup code in sleep process"
|
||||||
|
default n
|
||||||
|
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"
|
||||||
|
@@ -399,6 +399,26 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) \
|
||||||
|
|| CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// [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)
|
||||||
{
|
{
|
||||||
@@ -753,6 +773,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
|
||||||
|
|
||||||
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
|
#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND
|
||||||
if (!(pd_flags & RTC_SLEEP_PD_XTAL)) {
|
if (!(pd_flags & RTC_SLEEP_PD_XTAL)) {
|
||||||
rtc_sleep_systimer_enable(true);
|
rtc_sleep_systimer_enable(true);
|
||||||
@@ -897,6 +925,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -961,6 +996,12 @@ esp_err_t esp_light_sleep_start(void)
|
|||||||
|
|
||||||
esp_ipc_isr_stall_other_cpu();
|
esp_ipc_isr_stall_other_cpu();
|
||||||
|
|
||||||
|
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION && CONFIG_PM_SLP_IRAM_OPT
|
||||||
|
/* Cache Suspend 0: if CONFIG_PM_SLP_IRAM_OPT is enabled, suspend cache here so that the access to flash
|
||||||
|
during the sleep process can be explicitly exposed. */
|
||||||
|
suspend_cache();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Decide which power domains can be powered down
|
// Decide which power domains can be powered down
|
||||||
uint32_t pd_flags = get_power_down_flags();
|
uint32_t pd_flags = get_power_down_flags();
|
||||||
|
|
||||||
@@ -1113,6 +1154,12 @@ esp_err_t esp_light_sleep_start(void)
|
|||||||
|
|
||||||
esp_clk_private_unlock();
|
esp_clk_private_unlock();
|
||||||
esp_timer_private_unlock();
|
esp_timer_private_unlock();
|
||||||
|
|
||||||
|
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION && CONFIG_PM_SLP_IRAM_OPT
|
||||||
|
/* Cache Resume 0: sleep process done, resume cache for continue running */
|
||||||
|
resume_cache();
|
||||||
|
#endif
|
||||||
|
|
||||||
esp_ipc_isr_release_other_cpu();
|
esp_ipc_isr_release_other_cpu();
|
||||||
if (!wdt_was_enabled) {
|
if (!wdt_was_enabled) {
|
||||||
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
|
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
|
||||||
|
Reference in New Issue
Block a user