change(esp_hw_support): optimize sleep memory (iram or flash) usage control by PM_SLP_IRAM_OPT

This commit is contained in:
Li Shuai
2025-03-03 21:17:34 +08:00
parent 55712011f1
commit 954270dda3
10 changed files with 68 additions and 50 deletions

View File

@@ -12,22 +12,31 @@ entries:
cpu: esp_cpu_clear_watchpoint (noflash)
cpu: esp_cpu_compare_and_set (noflash)
esp_memory_utils (noflash)
rtc_clk (noflash)
clk_utils (noflash)
if PM_SLP_IRAM_OPT = y:
rtc_clk (noflash)
rtc_time (noflash_text)
if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED = y:
rtc_init:rtc_vddsdio_get_config (noflash)
rtc_init:rtc_vddsdio_set_config (noflash)
if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y || IDF_TARGET_ESP32S3 = y || IDF_TARGET_ESP32C2 = y || IDF_TARGET_ESP32C3 = y:
rtc_sleep (noflash_text)
rtc_time (noflash_text)
rtc_sleep:rtc_sleep_start (noflash)
if PM_SLP_IRAM_OPT = y:
rtc_sleep:rtc_sleep_get_default_config (noflash)
rtc_sleep:rtc_sleep_init (noflash)
rtc_sleep:rtc_sleep_low_init (noflash)
if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y:
rtc_sleep:rtc_sleep_pd (noflash)
if IDF_TARGET_ESP32S3 = y || IDF_TARGET_ESP32C2 = y || IDF_TARGET_ESP32C3 = y:
rtc_sleep:rtc_sleep_pu (noflash)
if SOC_PMU_SUPPORTED = y && SOC_LIGHT_SLEEP_SUPPORTED = y:
pmu_sleep (noflash)
if SPIRAM_FLASH_LOAD_TO_PSRAM = y:
pmu_init (noflash)
pmu_param (noflash)
if SOC_USB_SERIAL_JTAG_SUPPORTED = y:
if PM_SLP_IRAM_OPT = y && SOC_USB_SERIAL_JTAG_SUPPORTED = y:
sleep_console (noflash)
if SOC_USB_OTG_SUPPORTED && SOC_PM_SUPPORT_CNNT_PD = y:
if PM_SLP_IRAM_OPT = y && SOC_USB_OTG_SUPPORTED && SOC_PM_SUPPORT_CNNT_PD = y:
sleep_usb (noflash)
if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y:
rtc_wdt (noflash_text)
@@ -41,7 +50,7 @@ entries:
if SOC_ADC_SHARED_POWER = y:
if ADC_ONESHOT_CTRL_FUNC_IN_IRAM = y:
sar_periph_ctrl (noflash)
else:
elif PM_SLP_IRAM_OPT = y:
sar_periph_ctrl: sar_periph_ctrl_power_enable (noflash)
[mapping:soc_pm]

View File

@@ -65,7 +65,7 @@ typedef struct {
* Configure whether certain peripherals are powered down in deep sleep
* @param cfg power down flags as rtc_sleep_pd_config_t structure
*/
static void rtc_sleep_pd(rtc_sleep_pd_config_t cfg)
void rtc_sleep_pd(rtc_sleep_pd_config_t cfg)
{
REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU, ~cfg.dig_pd);
REG_SET_FIELD(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_LPU, ~cfg.rtc_pd);
@@ -345,7 +345,7 @@ uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt)
return rtc_sleep_finish();
}
static uint32_t rtc_sleep_finish(void)
static IRAM_ATTR uint32_t rtc_sleep_finish(void)
{
/* In deep sleep mode, we never get here */
uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);

View File

@@ -222,7 +222,7 @@ uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
return rtc_sleep_finish(lslp_mem_inf_fpu);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
static IRAM_ATTR uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
{
/* In deep sleep mode, we never get here */
uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);

View File

@@ -352,7 +352,7 @@ uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt)
return rtc_sleep_finish(0);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
static IRAM_ATTR uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
{
/* In deep sleep mode, we never get here */
uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);

View File

@@ -361,7 +361,7 @@ uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt)
return rtc_sleep_finish(0);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
static IRAM_ATTR uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
{
/* In deep sleep mode, we never get here */
uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);

View File

@@ -284,7 +284,7 @@ __attribute__((weak)) uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t rej
return rtc_sleep_finish(lslp_mem_inf_fpu);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
static IRAM_ATTR uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
{
/* In deep sleep mode, we never get here */
uint32_t reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);

View File

@@ -77,7 +77,7 @@ esp_err_t esp_unregister_mac_bb_pd_callback(mac_bb_power_down_cb_t cb)
return ESP_ERR_INVALID_STATE;
}
void IRAM_ATTR mac_bb_power_down_cb_execute(void)
void mac_bb_power_down_cb_execute(void)
{
for (int i = 0; i < MAC_BB_POWER_DOWN_CB_NO; i++) {
if (s_mac_bb_power_down_cb[i]) {
@@ -118,7 +118,7 @@ esp_err_t esp_unregister_mac_bb_pu_callback(mac_bb_power_up_cb_t cb)
return ESP_ERR_INVALID_STATE;
}
void IRAM_ATTR mac_bb_power_up_cb_execute(void)
void mac_bb_power_up_cb_execute(void)
{
for (int i = 0; i < MAC_BB_POWER_UP_CB_NO; i++) {
if (s_mac_bb_power_up_cb[i]) {

View File

@@ -216,6 +216,12 @@
#define CHECK_SOURCE(source, value, mask) ((s_config.wakeup_triggers & mask) && \
(source == value))
#if CONFIG_PM_SLP_IRAM_OPT
# define SLEEP_FN_ATTR IRAM_ATTR
#else
# define SLEEP_FN_ATTR
#endif
#define MAX_DSLP_HOOKS 3
static esp_deep_sleep_cb_t s_dslp_cb[MAX_DSLP_HOOKS] = {0};
@@ -525,7 +531,7 @@ static uint32_t s_stopped_tgwdt_bmap = 0;
#endif
// Must be called from critical sections.
static void IRAM_ATTR suspend_timers(uint32_t sleep_flags) {
static SLEEP_FN_ATTR void suspend_timers(uint32_t sleep_flags) {
if (!(sleep_flags & RTC_SLEEP_PD_XTAL)) {
#if SOC_SLEEP_TGWDT_STOP_WORKAROUND
/* If timegroup implemented task watchdog or interrupt watchdog is running, we have to stop it. */
@@ -547,7 +553,7 @@ static void IRAM_ATTR suspend_timers(uint32_t sleep_flags) {
}
// Must be called from critical sections.
static void IRAM_ATTR resume_timers(uint32_t sleep_flags) {
static SLEEP_FN_ATTR void resume_timers(uint32_t sleep_flags) {
if (!(sleep_flags & RTC_SLEEP_PD_XTAL)) {
#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND
for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) {
@@ -567,7 +573,7 @@ static void IRAM_ATTR resume_timers(uint32_t sleep_flags) {
}
// [refactor-todo] provide target logic for body of uart functions below
static void IRAM_ATTR flush_uarts(void)
static SLEEP_FN_ATTR void flush_uarts(void)
{
for (int i = 0; i < SOC_UART_HP_NUM; ++i) {
if (uart_ll_is_enabled(i)) {
@@ -582,7 +588,7 @@ static uint32_t s_suspended_uarts_bmap = 0;
* Suspend enabled uarts and return suspended uarts bit map.
* Must be called from critical sections.
*/
FORCE_INLINE_ATTR void suspend_uarts(void)
static SLEEP_FN_ATTR void suspend_uarts(void)
{
s_suspended_uarts_bmap = 0;
for (int i = 0; i < SOC_UART_HP_NUM; ++i) {
@@ -603,7 +609,7 @@ FORCE_INLINE_ATTR void suspend_uarts(void)
}
// Must be called from critical sections
FORCE_INLINE_ATTR void resume_uarts(void)
static SLEEP_FN_ATTR void resume_uarts(void)
{
for (int i = 0; i < SOC_UART_HP_NUM; ++i) {
if (s_suspended_uarts_bmap & 0x1) {
@@ -629,7 +635,7 @@ FORCE_INLINE_ATTR void resume_uarts(void)
completion time has exceeded the wakeup time, we should abandon the flush, skip the sleep and
return ESP_ERR_SLEEP_REJECT.
*/
FORCE_INLINE_ATTR bool light_sleep_uart_prepare(uint32_t sleep_flags, int64_t sleep_duration)
static SLEEP_FN_ATTR bool light_sleep_uart_prepare(uint32_t sleep_flags, int64_t sleep_duration)
{
bool should_skip_sleep = false;
#if !SOC_PM_SUPPORT_TOP_PD || !CONFIG_ESP_CONSOLE_UART
@@ -662,7 +668,7 @@ FORCE_INLINE_ATTR bool light_sleep_uart_prepare(uint32_t sleep_flags, int64_t sl
/**
* These save-restore workaround should be moved to lower layer
*/
FORCE_INLINE_ATTR void misc_modules_sleep_prepare(uint32_t sleep_flags, bool deep_sleep)
static SLEEP_FN_ATTR void misc_modules_sleep_prepare(uint32_t sleep_flags, bool deep_sleep)
{
if (deep_sleep){
for (int n = 0; n < MAX_DSLP_HOOKS; n++) {
@@ -716,7 +722,7 @@ FORCE_INLINE_ATTR void misc_modules_sleep_prepare(uint32_t sleep_flags, bool dee
/**
* These save-restore workaround should be moved to lower layer
*/
FORCE_INLINE_ATTR void misc_modules_wake_prepare(uint32_t sleep_flags)
static SLEEP_FN_ATTR void misc_modules_wake_prepare(uint32_t sleep_flags)
{
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
if (sleep_flags & PMU_SLEEP_PD_TOP) {
@@ -760,7 +766,7 @@ FORCE_INLINE_ATTR void misc_modules_wake_prepare(uint32_t sleep_flags)
#endif
}
static IRAM_ATTR void sleep_low_power_clock_calibration(bool is_dslp)
static SLEEP_FN_ATTR void sleep_low_power_clock_calibration(bool is_dslp)
{
// Calibrate rtc slow clock
#ifdef CONFIG_ESP_SYSTEM_RTC_EXT_XTAL
@@ -800,7 +806,7 @@ static IRAM_ATTR void sleep_low_power_clock_calibration(bool is_dslp)
inline static uint32_t call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu, bool dslp);
static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t clk_flags, esp_sleep_mode_t mode, bool allow_sleep_rejection)
static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t clk_flags, esp_sleep_mode_t mode, bool allow_sleep_rejection)
{
// Stop UART output so that output is not lost due to APB frequency change.
// For light sleep, suspend UART output — it will resume after wakeup.
@@ -1254,9 +1260,9 @@ esp_err_t IRAM_ATTR esp_deep_sleep_try_to_start(void)
* Placed into IRAM as flash may need some time to be powered on.
*/
static esp_err_t esp_light_sleep_inner(uint32_t sleep_flags, uint32_t clk_flags,
uint32_t flash_enable_time_us) IRAM_ATTR __attribute__((noinline));
uint32_t flash_enable_time_us) __attribute__((noinline));
static esp_err_t esp_light_sleep_inner(uint32_t sleep_flags, uint32_t clk_flags,
static SLEEP_FN_ATTR esp_err_t esp_light_sleep_inner(uint32_t sleep_flags, uint32_t clk_flags,
uint32_t flash_enable_time_us)
{
#if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED
@@ -1687,7 +1693,7 @@ esp_err_t esp_sleep_enable_vad_wakeup(void)
}
#endif
static esp_err_t timer_wakeup_prepare(int64_t sleep_duration)
static SLEEP_FN_ATTR esp_err_t timer_wakeup_prepare(int64_t sleep_duration)
{
if (sleep_duration < 0) {
sleep_duration = 0;
@@ -2325,7 +2331,7 @@ FORCE_INLINE_ATTR bool top_domain_pd_allowed(void) {
}
#endif
static uint32_t get_power_down_flags(void)
static SLEEP_FN_ATTR uint32_t get_power_down_flags(void)
{
// Where needed, convert AUTO options to ON. Later interpret AUTO as OFF.
@@ -2502,7 +2508,7 @@ static uint32_t get_power_down_flags(void)
return pd_flags;
}
static uint32_t get_sleep_flags(uint32_t sleep_flags, bool deepsleep)
static SLEEP_FN_ATTR uint32_t get_sleep_flags(uint32_t sleep_flags, bool deepsleep)
{
// Override user-configured FOSC power modes.
if (s_sleep_sub_mode_ref_cnt[ESP_SLEEP_RTC_USE_RC_FAST_MODE]) {
@@ -2554,7 +2560,7 @@ static uint32_t get_sleep_flags(uint32_t sleep_flags, bool deepsleep)
return sleep_flags;
}
static uint32_t get_sleep_clock_icg_flags(void)
static SLEEP_FN_ATTR uint32_t get_sleep_clock_icg_flags(void)
{
uint32_t clk_flags = 0;

View File

@@ -7,17 +7,33 @@ entries:
if PM_SLP_IRAM_OPT = y:
pm_impl:esp_pm_impl_get_cpu_freq (noflash)
if FREERTOS_USE_TICKLESS_IDLE = y:
pm_impl:vApplicationSleep (noflash)
[mapping:esp_hw_support_pm]
archive: libesp_hw_support.a
entries:
if PM_SLP_IRAM_OPT = y:
sleep_modes:esp_light_sleep_start (noflash)
sleep_modes:esp_sleep_enable_timer_wakeup (noflash)
sleep_modes:timer_wakeup_prepare (noflash)
sleep_modes:get_power_down_flags (noflash)
sleep_modes:get_sleep_flags (noflash)
sleep_modes:get_sleep_clock_icg_flags (noflash)
if SOC_LIGHT_SLEEP_SUPPORTED = y:
sleep_modes:esp_light_sleep_start (noflash)
sleep_modes:esp_sleep_enable_timer_wakeup (noflash)
sleep_modem:modem_domain_pd_allowed (noflash)
sleep_modem:periph_inform_out_light_sleep_overhead (noflash)
sleep_modem:sleep_modem_reject_triggers (noflash)
if ESP_PHY_MAC_BB_PD = y:
sleep_modem:mac_bb_power_down_cb_execute (noflash)
sleep_modem:mac_bb_power_up_cb_execute (noflash)
if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y:
sleep_gpio:gpio_sleep_mode_config_apply (noflash)
if SOC_PM_SUPPORT_TOP_PD = y:
sleep_clock:clock_domain_pd_allowed (noflash)
sleep_system_peripheral:peripheral_domain_pd_allowed (noflash)
if SOC_PM_CPU_RETENTION_BY_RTCCNTL = y && (PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || SOC_PM_SUPPORT_TAGMEM_PD = y):
sleep_cpu:sleep_enable_cpu_retention (noflash)
if PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || (SOC_CPU_IN_TOP_DOMAIN = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP = y):
sleep_cpu:cpu_domain_pd_allowed (noflash)
if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP = y:
sleep_mmu:mmu_domain_pd_allowed (noflash)
esp_clk:esp_clk_slowclk_cal_set (noflash)
esp_clk:esp_clk_slowclk_cal_get (noflash)
esp_clk:esp_rtc_get_time_us (noflash)
@@ -27,19 +43,6 @@ entries:
esp_clk:calc_checksum (noflash)
if SOC_SYSTIMER_SUPPORTED = y:
systimer (noflash)
if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y:
sleep_gpio:gpio_sleep_mode_config_apply (noflash)
if SOC_PM_CPU_RETENTION_BY_RTCCNTL = y && (PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || SOC_PM_SUPPORT_TAGMEM_PD = y):
sleep_cpu:sleep_enable_cpu_retention (noflash)
if PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y || (SOC_CPU_IN_TOP_DOMAIN = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP = y):
sleep_cpu:cpu_domain_pd_allowed (noflash)
if SOC_PM_SUPPORT_TOP_PD = y:
sleep_clock:clock_domain_pd_allowed (noflash)
sleep_system_peripheral:peripheral_domain_pd_allowed (noflash)
if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD = y && PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP = y:
sleep_mmu:mmu_domain_pd_allowed (noflash)
sleep_modem:modem_domain_pd_allowed (noflash)
sleep_modem:periph_inform_out_light_sleep_overhead (noflash)
sar_periph_ctrl:sar_periph_ctrl_power_disable (noflash)
if SOC_TEMP_SENSOR_SUPPORTED = y:
sar_periph_ctrl_common:temperature_sensor_power_acquire (noflash)

View File

@@ -803,7 +803,7 @@ static inline void IRAM_ATTR other_core_should_skip_light_sleep(int core_id)
#endif
}
void IRAM_ATTR vApplicationSleep( TickType_t xExpectedIdleTime )
void vApplicationSleep( TickType_t xExpectedIdleTime )
{
portENTER_CRITICAL(&s_switch_lock);
int core_id = xPortGetCoreID();