From c6db3068339b881875da4ba08bc808c7e5353ef9 Mon Sep 17 00:00:00 2001 From: liuning Date: Fri, 15 Sep 2023 11:34:03 +0800 Subject: [PATCH] sleep_modem: split esp_wifi_internal_mac_sleep_configure, add lock for pm functions --- .../include/esp_private/sleep_modem.h | 10 ++++++++++ components/esp_hw_support/sleep_modem.c | 16 ++++------------ components/esp_pm/pm_impl.c | 9 +++++++++ components/esp_wifi/include/esp_private/wifi.h | 16 ++++++++++++---- components/esp_wifi/src/wifi_init.c | 16 +++++++++++++--- 5 files changed, 48 insertions(+), 19 deletions(-) diff --git a/components/esp_hw_support/include/esp_private/sleep_modem.h b/components/esp_hw_support/include/esp_private/sleep_modem.h index b5a4f23206..fe8e3ea220 100644 --- a/components/esp_hw_support/include/esp_private/sleep_modem.h +++ b/components/esp_hw_support/include/esp_private/sleep_modem.h @@ -178,6 +178,16 @@ esp_err_t sleep_modem_wifi_modem_state_init(void); * This function deinit wifi modem state. */ void sleep_modem_wifi_modem_state_deinit(void); + +/** + * @brief Function to check Wi-Fi modem state to skip light sleep. + * + * This function is to check if light sleep should skip by Wi-Fi modem state . + * @return + * - true skip light sleep + * - false not skip light sleep + */ +bool sleep_modem_wifi_modem_state_skip_light_sleep(void); #endif #ifdef __cplusplus diff --git a/components/esp_hw_support/sleep_modem.c b/components/esp_hw_support/sleep_modem.c index c5eb4acbb5..7e963aa64d 100644 --- a/components/esp_hw_support/sleep_modem.c +++ b/components/esp_hw_support/sleep_modem.c @@ -167,7 +167,7 @@ typedef struct sleep_modem_config { static sleep_modem_config_t s_sleep_modem = { .wifi.phy_link = NULL, .wifi.flags = 0 }; -__attribute__((unused)) esp_err_t sleep_modem_wifi_modem_state_init(void) +esp_err_t sleep_modem_wifi_modem_state_init(void) { esp_err_t err = ESP_OK; phy_i2c_master_command_attribute_t cmd; @@ -302,7 +302,7 @@ uint32_t IRAM_ATTR sleep_modem_reject_triggers(void) return reject_triggers; } -static __attribute__((unused)) bool IRAM_ATTR sleep_modem_wifi_modem_state_skip_light_sleep(void) +bool IRAM_ATTR sleep_modem_wifi_modem_state_skip_light_sleep(void) { bool skip = false; #if SOC_PM_SUPPORT_PMU_MODEM_STATE @@ -317,16 +317,8 @@ static __attribute__((unused)) bool IRAM_ATTR sleep_modem_wifi_modem_state_skip_ esp_err_t sleep_modem_configure(int max_freq_mhz, int min_freq_mhz, bool light_sleep_enable) { #if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP - extern int esp_wifi_internal_mac_sleep_configure(bool, bool); - if (light_sleep_enable) { - if (sleep_modem_wifi_modem_state_enabled() == ESP_OK) { - esp_pm_register_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep); - esp_wifi_internal_mac_sleep_configure(light_sleep_enable, true); /* require WiFi to enable automatically receives the beacon */ - } - } else { - esp_wifi_internal_mac_sleep_configure(light_sleep_enable, false); /* require WiFi to disable automatically receives the beacon */ - esp_pm_unregister_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep); - } + extern int esp_wifi_internal_light_sleep_configure(bool); + esp_wifi_internal_light_sleep_configure(light_sleep_enable); #endif #if CONFIG_PM_SLP_DEFAULT_PARAMS_OPT if (light_sleep_enable) { diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 08547bd882..417b046d30 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -123,6 +123,8 @@ static bool s_skipped_light_sleep[portNUM_PROCESSORS]; */ static bool s_skip_light_sleep[portNUM_PROCESSORS]; #endif // portNUM_PROCESSORS == 2 + +static _lock_t s_skip_light_sleep_lock; #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE /* A flag indicating that Idle hook has run on a given CPU; @@ -547,25 +549,32 @@ static void IRAM_ATTR leave_idle(void) esp_err_t esp_pm_register_skip_light_sleep_callback(skip_light_sleep_cb_t cb) { + _lock_acquire(&s_skip_light_sleep_lock); for (int i = 0; i < PERIPH_SKIP_LIGHT_SLEEP_NO; i++) { if (s_periph_skip_light_sleep_cb[i] == cb) { + _lock_release(&s_skip_light_sleep_lock); return ESP_OK; } else if (s_periph_skip_light_sleep_cb[i] == NULL) { s_periph_skip_light_sleep_cb[i] = cb; + _lock_release(&s_skip_light_sleep_lock); return ESP_OK; } } + _lock_release(&s_skip_light_sleep_lock); return ESP_ERR_NO_MEM; } esp_err_t esp_pm_unregister_skip_light_sleep_callback(skip_light_sleep_cb_t cb) { + _lock_acquire(&s_skip_light_sleep_lock); for (int i = 0; i < PERIPH_SKIP_LIGHT_SLEEP_NO; i++) { if (s_periph_skip_light_sleep_cb[i] == cb) { s_periph_skip_light_sleep_cb[i] = NULL; + _lock_release(&s_skip_light_sleep_lock); return ESP_OK; } } + _lock_release(&s_skip_light_sleep_lock); return ESP_ERR_INVALID_STATE; } diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index acb18626ef..fc7ae119b0 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -629,15 +629,23 @@ void esp_wifi_set_keep_alive_time(uint32_t keep_alive_time); void esp_wifi_beacon_monitor_configure(wifi_beacon_monitor_config_t *config); /** - * @brief Require WiFi to enable or disable Advanced DTIM sleep function + * @brief Set modem state mode to require WiFi to enable or disable Advanced DTIM sleep function * - * @param light_sleep_enable: true for light sleep mode is enabled, false for light sleep mode is disabled. - * @param modem_state_enable: true for require WiFi to enable Advanced DTIM sleep function, + * @param require_modem_state: true for require WiFi to enable Advanced DTIM sleep function, * false for require WiFi to disable Advanced DTIM sleep function. * @return * - ESP_OK: succeed */ -void esp_wifi_internal_mac_sleep_configure(bool light_sleep_enable, bool modem_state_enable); +void esp_wifi_internal_modem_state_configure(bool require_modem_state); + +/** + * @brief Set light sleep mode to require WiFi to enable or disable Advanced DTIM sleep function + * + * @param light_sleep_enable: true for light sleep mode is enabled, false for light sleep mode is disabled. + * @return + * - ESP_OK: succeed + */ +void esp_wifi_internal_light_sleep_configure(bool light_sleep_enable); /** * @brief Start Publishing a service in the NAN cluster diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index e67069a6a5..4473cfc438 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -167,6 +167,10 @@ esp_err_t esp_wifi_deinit(void) #if CONFIG_MAC_BB_PD esp_wifi_internal_set_mac_sleep(false); esp_mac_bb_pd_mem_deinit(); +#endif +#if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP + esp_wifi_internal_modem_state_configure(false); + esp_pm_unregister_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep); #endif esp_phy_modem_deinit(); @@ -231,12 +235,12 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) #endif #if CONFIG_ESP_WIFI_SLP_IRAM_OPT - esp_pm_register_light_sleep_default_params_config_callback(esp_wifi_internal_update_light_sleep_default_params); - int min_freq_mhz = esp_pm_impl_get_cpu_freq(PM_MODE_LIGHT_SLEEP); int max_freq_mhz = esp_pm_impl_get_cpu_freq(PM_MODE_CPU_MAX); esp_wifi_internal_update_light_sleep_default_params(min_freq_mhz, max_freq_mhz); + esp_pm_register_light_sleep_default_params_config_callback(esp_wifi_internal_update_light_sleep_default_params); + uint32_t sleep_delay_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME * 1000; esp_wifi_set_sleep_delay_time(sleep_delay_us); @@ -291,6 +295,12 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) esp_wifi_internal_set_mac_sleep(true); #endif esp_phy_modem_init(); +#if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP + if (sleep_modem_wifi_modem_state_enabled()) { + esp_pm_register_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep); + esp_wifi_internal_modem_state_configure(true); /* require WiFi to enable automatically receives the beacon */ + } +#endif #if CONFIG_IDF_TARGET_ESP32 s_wifi_mac_time_update_cb = esp_wifi_internal_update_mac_time; #endif