Merge branch 'fix/fix_psram_data_corrupt_after_lightsleep' into 'master'

fix(esp_hw_support):fix psram data corrupt after lightsleep

Closes PM-941

See merge request espressif/esp-idf!48322
This commit is contained in:
Wu Zheng Hui
2026-05-22 15:11:41 +08:00
7 changed files with 119 additions and 31 deletions
+15 -14
View File
@@ -991,14 +991,15 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint
spi_flash_enable_deep_power_down_mode(false);
}
#endif
/* Cache Resume 1: Resume cache for continue running*/
sleep_cache_resume();
#if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED && CONFIG_SPIRAM_XIP_FROM_PSRAM
// Code outside of esp_sleep_start_safe may be linked to FLASH, and if CONFIG_SPIRAM_XIP_FROM_PSRAM
// is enabled, code in Flash will be copied to PSRAM for execution. We need to wait here until
// PSRAM exits half-sleep before returning.
#if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED && (CONFIG_SPIRAM_XIP_FROM_PSRAM || !CONFIG_PM_SLP_IRAM_OPT)
// Code outside of esp_sleep_start_safe may be linked to FLASH if CONFIG_PM_SLP_IRAM_OPT is false,
// Code that accesses flash memory may cause cached PSRAM data to be replaced back into PSRAM before
// it has fully resumed. And if CONFIG_SPIRAM_XIP_FROM_PSRAM is enabled, code in Flash will be copied
// to PSRAM for execution. We need to wait here until PSRAM exits half-sleep before returning.
esp_psram_impl_resume_from_halfsleep_mode(s_config.rtc_clk_cal_period);
#endif
/* Cache Resume 1: Resume cache for continue running*/
sleep_cache_resume();
}
return result;
}
@@ -1693,6 +1694,14 @@ esp_err_t esp_light_sleep_start(void)
esp_clk_private_unlock();
esp_timer_private_unlock();
#if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED && !CONFIG_SPIRAM_XIP_FROM_PSRAM && CONFIG_PM_SLP_IRAM_OPT
// If CONFIG_SPIRAM_XIP_FROM_PSRAM is not enabled and CONFIG_PM_SLP_IRAM_OPT is enable,
// the sleep-wake process prior to this point does not access the PSRAM, so we can postpone waiting
// for the PSRAM to resume until here, in order to reuse the time overhead
// of the wake-up process as much as possible.
esp_psram_impl_resume_from_halfsleep_mode(s_config.rtc_clk_cal_period);
#endif
#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION && CONFIG_PM_SLP_IRAM_OPT
/* Cache Resume 0: sleep process done, resume cache for continue running */
if (!(s_config.wakeup_triggers & ignore_check_wakeup_triggers)) {
@@ -1700,14 +1709,6 @@ esp_err_t esp_light_sleep_start(void)
}
#endif
#if CONFIG_PM_SLP_SPIRAM_HALFSLEEP_ENABLED && !CONFIG_SPIRAM_XIP_FROM_PSRAM
// If CONFIG_SPIRAM_XIP_FROM_PSRAM is not enabled, the sleep-wake process
// prior to this point does not access the PSRAM, so we can postpone waiting
// for the PSRAM to resume until here, in order to reuse the time overhead
// of the wake-up process as much as possible.
esp_psram_impl_resume_from_halfsleep_mode(s_config.rtc_clk_cal_period);
#endif
#if !CONFIG_FREERTOS_UNICORE
esp_ipc_isr_stall_resume();
#if CONFIG_PM_ESP_SLEEP_POWER_DOWN_CPU && SOC_PM_CPU_RETENTION_BY_SW