Преглед изворни кода

Merge branch 'bugfix/esp32c3_light_sleep_default_params_optimize' into 'master'

light sleep: some default parameters optimization

See merge request espressif/esp-idf!12461
Jiang Jiang Jian пре 4 година
родитељ
комит
ae65cffff0

+ 4 - 0
components/esp_pm/Kconfig

@@ -90,4 +90,8 @@ menu "Power Management"
             Waring: If you want to enable this option on ESP32, you should enable `GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL`
             Waring: If you want to enable this option on ESP32, you should enable `GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL`
             at first, otherwise you will not be able to switch pullup/pulldown mode.
             at first, otherwise you will not be able to switch pullup/pulldown mode.
 
 
+    config PM_SLP_DEFAULT_PARAMS_OPT
+        bool
+        default n
+
 endmenu # "Power Management"
 endmenu # "Power Management"

+ 29 - 0
components/esp_pm/include/esp_private/pm_impl.h

@@ -49,6 +49,13 @@ typedef enum {
  */
  */
 pm_mode_t esp_pm_impl_get_mode(esp_pm_lock_type_t type, int arg);
 pm_mode_t esp_pm_impl_get_mode(esp_pm_lock_type_t type, int arg);
 
 
+/**
+ * @brief Get CPU clock frequency by power mode
+ * @param mode power mode
+ * @return CPU clock frequency
+ */
+int esp_pm_impl_get_cpu_freq(pm_mode_t mode);
+
 /**
 /**
  * If profiling is enabled, this data type will be used to store microsecond
  * If profiling is enabled, this data type will be used to store microsecond
  * timestamps.
  * timestamps.
@@ -172,6 +179,28 @@ esp_err_t esp_pm_register_inform_out_light_sleep_overhead_callback(inform_out_li
   */
   */
 esp_err_t esp_pm_unregister_inform_out_light_sleep_overhead_callback(inform_out_light_sleep_overhead_cb_t cb);
 esp_err_t esp_pm_unregister_inform_out_light_sleep_overhead_callback(inform_out_light_sleep_overhead_cb_t cb);
 
 
+/**
+ * @brief Callback function type for peripherals to know light sleep default parameters
+ */
+typedef void (* update_light_sleep_default_params_config_cb_t)(int, int);
+
+/**
+ * @brief  Register peripherals light sleep default parameters configure callback
+ *
+ * This function allows you to register a callback that configure the peripherals
+ * of default parameters of light sleep
+ * @param cb function to update default parameters
+ */
+void esp_pm_register_light_sleep_default_params_config_callback(update_light_sleep_default_params_config_cb_t cb);
+
+/**
+ * @brief  Unregister peripherals light sleep default parameters configure Callback
+ *
+ * This function allows you to unregister a callback that configure the peripherals
+ * of default parameters of light sleep
+ */
+void esp_pm_unregister_light_sleep_default_params_config_callback(void);
+
 #ifdef CONFIG_PM_PROFILING
 #ifdef CONFIG_PM_PROFILING
 #define WITH_PROFILING
 #define WITH_PROFILING
 #endif
 #endif

+ 48 - 1
components/esp_pm/pm_impl.c

@@ -152,7 +152,7 @@ static esp_pm_lock_handle_t s_rtos_lock_handle[portNUM_PROCESSORS];
 /* Lookup table of CPU frequency configs to be used in each mode.
 /* Lookup table of CPU frequency configs to be used in each mode.
  * Initialized by esp_pm_impl_init and modified by esp_pm_configure.
  * Initialized by esp_pm_impl_init and modified by esp_pm_configure.
  */
  */
-rtc_cpu_freq_config_t s_cpu_freq_by_mode[PM_MODE_COUNT];
+static rtc_cpu_freq_config_t s_cpu_freq_by_mode[PM_MODE_COUNT];
 
 
 /* Whether automatic light sleep is enabled */
 /* Whether automatic light sleep is enabled */
 static bool s_light_sleep_en = false;
 static bool s_light_sleep_en = false;
@@ -198,6 +198,9 @@ static const char* TAG = "pm";
 static void do_switch(pm_mode_t new_mode);
 static void do_switch(pm_mode_t new_mode);
 static void leave_idle(void);
 static void leave_idle(void);
 static void on_freq_update(uint32_t old_ticks_per_us, uint32_t ticks_per_us);
 static void on_freq_update(uint32_t old_ticks_per_us, uint32_t ticks_per_us);
+#if CONFIG_PM_SLP_DEFAULT_PARAMS_OPT
+static void esp_pm_light_sleep_default_params_config(int min_freq_mhz, int max_freq_mhz);
+#endif
 
 
 pm_mode_t esp_pm_impl_get_mode(esp_pm_lock_type_t type, int arg)
 pm_mode_t esp_pm_impl_get_mode(esp_pm_lock_type_t type, int arg)
 {
 {
@@ -311,6 +314,12 @@ esp_err_t esp_pm_configure(const void* vconfig)
     }
     }
 #endif
 #endif
 
 
+#if CONFIG_PM_SLP_DEFAULT_PARAMS_OPT
+    if (config->light_sleep_enable) {
+        esp_pm_light_sleep_default_params_config(min_freq_mhz, max_freq_mhz);
+    }
+#endif
+
     return ESP_OK;
     return ESP_OK;
 }
 }
 
 
@@ -662,6 +671,19 @@ void esp_pm_impl_dump_stats(FILE* out)
 }
 }
 #endif // WITH_PROFILING
 #endif // WITH_PROFILING
 
 
+int esp_pm_impl_get_cpu_freq(pm_mode_t mode)
+{
+    int freq_mhz;
+    if (mode >= PM_MODE_LIGHT_SLEEP && mode < PM_MODE_COUNT) {
+        portENTER_CRITICAL(&s_switch_lock);
+        freq_mhz = s_cpu_freq_by_mode[mode].freq_mhz;
+        portEXIT_CRITICAL(&s_switch_lock);
+    } else {
+        abort();
+    }
+    return freq_mhz;
+}
+
 void esp_pm_impl_init(void)
 void esp_pm_impl_init(void)
 {
 {
 #if defined(CONFIG_ESP_CONSOLE_UART)
 #if defined(CONFIG_ESP_CONSOLE_UART)
@@ -818,3 +840,28 @@ void periph_inform_out_light_sleep_overhead(uint32_t out_light_sleep_time)
         }
         }
     }
     }
 }
 }
+
+static update_light_sleep_default_params_config_cb_t s_light_sleep_default_params_config_cb = NULL;
+
+void esp_pm_register_light_sleep_default_params_config_callback(update_light_sleep_default_params_config_cb_t cb)
+{
+    if (s_light_sleep_default_params_config_cb == NULL) {
+        s_light_sleep_default_params_config_cb = cb;
+    }
+}
+
+void esp_pm_unregister_light_sleep_default_params_config_callback(void)
+{
+    if (s_light_sleep_default_params_config_cb) {
+        s_light_sleep_default_params_config_cb = NULL;
+    }
+}
+
+#if CONFIG_PM_SLP_DEFAULT_PARAMS_OPT
+static void esp_pm_light_sleep_default_params_config(int min_freq_mhz, int max_freq_mhz)
+{
+    if (s_light_sleep_default_params_config_cb) {
+        (*s_light_sleep_default_params_config_cb)(min_freq_mhz, max_freq_mhz);
+    }
+}
+#endif

+ 11 - 1
components/esp_system/sleep_modes.c

@@ -622,8 +622,18 @@ void IRAM_ATTR esp_deep_sleep_start(void)
     // Correct the sleep time
     // Correct the sleep time
     s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US;
     s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US;
 
 
+    uint32_t force_pd_flags = RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO;
+
+#if SOC_PM_SUPPORT_WIFI_PD
+    force_pd_flags |= RTC_SLEEP_PD_WIFI;
+#endif
+
+#if SOC_PM_SUPPORT_BT_PD
+    force_pd_flags |= RTC_SLEEP_PD_BT;
+#endif
+
     // Enter sleep
     // Enter sleep
-    esp_sleep_start(RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | pd_flags);
+    esp_sleep_start(force_pd_flags | pd_flags);
 
 
     // Because RTC is in a slower clock domain than the CPU, it
     // Because RTC is in a slower clock domain than the CPU, it
     // can take several CPU cycles for the sleep mode to start.
     // can take several CPU cycles for the sleep mode to start.

+ 18 - 0
components/esp_wifi/Kconfig

@@ -323,6 +323,8 @@ menu "Wi-Fi"
 
 
     config ESP_WIFI_SLP_IRAM_OPT
     config ESP_WIFI_SLP_IRAM_OPT
         bool "WiFi SLP IRAM speed optimization"
         bool "WiFi SLP IRAM speed optimization"
+        depends on FREERTOS_USE_TICKLESS_IDLE
+        select PM_SLP_DEFAULT_PARAMS_OPT
         help
         help
             Select this option to place called Wi-Fi library TBTT process and receive beacon functions in IRAM.
             Select this option to place called Wi-Fi library TBTT process and receive beacon functions in IRAM.
             Some functions can be put in IRAM either by ESP32_WIFI_IRAM_OPT and ESP32_WIFI_RX_IRAM_OPT, or this one.
             Some functions can be put in IRAM either by ESP32_WIFI_IRAM_OPT and ESP32_WIFI_RX_IRAM_OPT, or this one.
@@ -331,6 +333,22 @@ menu "Wi-Fi"
             If neither of them are enabled, the other 7.4KB IRAM memory would be taken by this option.
             If neither of them are enabled, the other 7.4KB IRAM memory would be taken by this option.
             Wi-Fi power-save mode average current would be reduced if this option is enabled.
             Wi-Fi power-save mode average current would be reduced if this option is enabled.
 
 
+    config ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME
+        int "Minimum active time"
+        range 8 60
+        default 8
+        depends on ESP_WIFI_SLP_IRAM_OPT
+        help
+            The minimum timeout for waiting to receive data, unit: milliseconds.
+
+    config ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME
+        int "Maximum keep alive time"
+        range 10 60
+        default 60
+        depends on ESP_WIFI_SLP_IRAM_OPT
+        help
+            The maximum time that wifi keep alive, unit: seconds.
+
     config ESP_WIFI_FTM_INITIATOR_SUPPORT
     config ESP_WIFI_FTM_INITIATOR_SUPPORT
         bool "FTM Initiator support"
         bool "FTM Initiator support"
         default y
         default y

+ 22 - 4
components/esp_wifi/include/esp_private/wifi.h

@@ -575,10 +575,28 @@ esp_err_t esp_wifi_set_tx_done_cb(wifi_tx_done_cb_t cb);
 esp_err_t esp_wifi_internal_set_spp_amsdu(wifi_interface_t ifidx, bool spp_cap, bool spp_req);
 esp_err_t esp_wifi_internal_set_spp_amsdu(wifi_interface_t ifidx, bool spp_cap, bool spp_req);
 
 
 /**
 /**
-  * @brief    Apply WiFi sleep optimization parameters
-  *
-  */
-void esp_wifi_internal_optimize_wake_ahead_time(void);
+ * @brief   Update WIFI light sleep default parameters
+ *
+ * @param   min_freq_mhz: minimum frequency of DFS
+ * @param   max_freq_mhz: maximum frequency of DFS
+ */
+void esp_wifi_internal_update_light_sleep_default_params(int min_freq_mhz, int max_freq_mhz);
+
+/**
+ * @brief   Set the delay time for wifi to enter the sleep state when light sleep
+ *
+ * @param   return_to_sleep_delay: minimum timeout time  for waiting to receive
+ *                      data, when no data is received during the timeout period,
+ *                      the wifi enters the sleep process.
+ */
+void esp_wifi_set_sleep_delay_time(uint32_t return_to_sleep_delay);
+
+/**
+ * @brief   Set wifi keep alive time
+ *
+ * @param   keep_alive_time: keep alive time
+ */
+void esp_wifi_set_keep_alive_time(uint32_t keep_alive_time);
 
 
 /**
 /**
  * @brief Set FTM Report log level
  * @brief Set FTM Report log level

+ 1 - 1
components/esp_wifi/lib

@@ -1 +1 @@
-Subproject commit d21608a505f8000ba3a7cce696985fb3b4cd8e81
+Subproject commit 6cafbeadef4fa20bd28929c75a96d644b8b0ab15

+ 17 - 1
components/esp_wifi/src/wifi_init.c

@@ -151,6 +151,9 @@ esp_err_t esp_wifi_deinit(void)
     esp_pm_unregister_skip_light_sleep_callback(esp_wifi_internal_is_tsf_active);
     esp_pm_unregister_skip_light_sleep_callback(esp_wifi_internal_is_tsf_active);
     esp_pm_unregister_inform_out_light_sleep_overhead_callback(esp_wifi_internal_update_light_sleep_wake_ahead_time);
     esp_pm_unregister_inform_out_light_sleep_overhead_callback(esp_wifi_internal_update_light_sleep_wake_ahead_time);
 #endif
 #endif
+#if CONFIG_ESP_WIFI_SLP_IRAM_OPT
+    esp_pm_unregister_light_sleep_default_params_config_callback();
+#endif
 #endif
 #endif
 #if CONFIG_MAC_BB_PD
 #if CONFIG_MAC_BB_PD
     esp_unregister_mac_bb_pd_callback(pm_mac_sleep);
     esp_unregister_mac_bb_pd_callback(pm_mac_sleep);
@@ -186,7 +189,6 @@ static void esp_wifi_config_info(void)
 #endif
 #endif
 
 
 #ifdef CONFIG_ESP_WIFI_SLP_IRAM_OPT
 #ifdef CONFIG_ESP_WIFI_SLP_IRAM_OPT
-    esp_wifi_internal_optimize_wake_ahead_time();
     ESP_LOGI(TAG, "WiFi SLP IRAM OP enabled");
     ESP_LOGI(TAG, "WiFi SLP IRAM OP enabled");
 #endif
 #endif
 
 
@@ -222,6 +224,20 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
     }
     }
 #endif
 #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);
+
+    uint32_t sleep_delay_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME * 1000;
+    esp_wifi_set_sleep_delay_time(sleep_delay_us);
+
+    uint32_t keep_alive_time_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME * 1000 * 1000;
+    esp_wifi_set_keep_alive_time(keep_alive_time_us);
+#endif
+
 #if SOC_WIFI_HW_TSF
 #if SOC_WIFI_HW_TSF
     esp_err_t ret = esp_pm_register_skip_light_sleep_callback(esp_wifi_internal_is_tsf_active);
     esp_err_t ret = esp_pm_register_skip_light_sleep_callback(esp_wifi_internal_is_tsf_active);
     if (ret != ESP_OK) {
     if (ret != ESP_OK) {

+ 4 - 0
components/soc/esp32c3/include/soc/soc_caps.h

@@ -146,3 +146,7 @@
 #define SOC_PM_SUPPORT_BT_WAKEUP        (1)
 #define SOC_PM_SUPPORT_BT_WAKEUP        (1)
 
 
 #define SOC_PM_SUPPORT_CPU_PD           (1)
 #define SOC_PM_SUPPORT_CPU_PD           (1)
+
+#define SOC_PM_SUPPORT_WIFI_PD          (1)
+
+#define SOC_PM_SUPPORT_BT_PD            (1)

+ 2 - 0
components/soc/esp32s2/include/soc/soc_caps.h

@@ -317,5 +317,7 @@
 
 
 #define SOC_PM_SUPPORT_WIFI_WAKEUP      (1)
 #define SOC_PM_SUPPORT_WIFI_WAKEUP      (1)
 
 
+#define SOC_PM_SUPPORT_WIFI_PD          (1)
+
 /* ---------------------------- Compatibility ------------------------------- */
 /* ---------------------------- Compatibility ------------------------------- */
 // No contents
 // No contents