From 78362aff04f3b75eccd14f8f6d73bfc8ad34515c Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Tue, 12 Nov 2024 21:21:17 +0800 Subject: [PATCH 1/2] fix(esp_pm): fix missed ccompare update when another core is already in do_switch --- components/esp_pm/pm_impl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index f7ebc0601b..9d3db7e502 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -626,6 +626,7 @@ static void IRAM_ATTR do_switch(pm_mode_t new_mode) } #ifdef CONFIG_FREERTOS_SYSTICK_USES_CCOUNT if (s_need_update_ccompare[core_id]) { + update_ccompare(); s_need_update_ccompare[core_id] = false; } #endif From 2c35c097425fb1bfff0a76604f269687beb67ad2 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Tue, 12 Nov 2024 22:04:08 +0800 Subject: [PATCH 2/2] fix(esp_pm): fix deadlock in pm_mode switching --- components/esp_pm/pm_impl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 9d3db7e502..c4c1d91f4b 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -109,6 +109,9 @@ #endif static portMUX_TYPE s_switch_lock = portMUX_INITIALIZER_UNLOCKED; +static portMUX_TYPE s_cpu_freq_switch_lock[CONFIG_FREERTOS_NUMBER_OF_CORES] = { + [0 ... (CONFIG_FREERTOS_NUMBER_OF_CORES - 1)] = portMUX_INITIALIZER_UNLOCKED +}; /* The following state variables are protected using s_switch_lock: */ /* Current sleep mode; When switching, contains old mode until switch is complete */ static pm_mode_t s_mode = PM_MODE_CPU_MAX; @@ -639,6 +642,7 @@ static void IRAM_ATTR do_switch(pm_mode_t new_mode) s_is_switching = true; bool config_changed = s_config_changed; s_config_changed = false; + portENTER_CRITICAL_ISR(&s_cpu_freq_switch_lock[core_id]); portEXIT_CRITICAL_ISR(&s_switch_lock); rtc_cpu_freq_config_t new_config = s_cpu_freq_by_mode[new_mode]; @@ -678,6 +682,7 @@ static void IRAM_ATTR do_switch(pm_mode_t new_mode) } portENTER_CRITICAL_ISR(&s_switch_lock); + portEXIT_CRITICAL_ISR(&s_cpu_freq_switch_lock[core_id]); s_mode = new_mode; s_is_switching = false; portEXIT_CRITICAL_ISR(&s_switch_lock);