feat(pm): refactor power management according to IDF

This commit is contained in:
Zhang Jun Hao
2020-03-20 10:00:33 +08:00
parent ffa9749d65
commit ee4224ab66
9 changed files with 117 additions and 8 deletions

View File

@ -221,6 +221,18 @@ config ESP8266_BOOT_COPY_APP
endchoice
endmenu
menu "Power Management"
config PM_ENABLE
bool "Support for power management"
default n
help
If enabled, application is compiled with support for power management.
This option has run-time overhead (increased interrupt latency,
longer time to enter idle state), and it also reduces accuracy of
RTOS ticks and timers used for timekeeping.
Enable this option if application uses power management APIs.
endmenu
menu Wi-Fi
config SCAN_AP_MAX

View File

@ -46,7 +46,7 @@ typedef enum {
} esp_sleep_source_t;
/**
* @brief Set the chip to deep-sleep mode.
* @brief Enter deep-sleep mode.
*
* The device will automatically wake up after the deep-sleep time set
* by the users. Upon waking up, the device boots up from user_init.
@ -56,6 +56,9 @@ typedef enum {
* @attention 2. system_deep_sleep(0): there is no wake up timer; in order to wake
* up, connect a GPIO to pin RST, the chip will wake up by a falling-edge
* on pin RST
* @attention 3. esp_deep_sleep does not shut down WiFi and higher level protocol
* connections gracefully. Make sure esp_wifi_stop are called to close any
* connections and deinitialize the peripherals.
*
* @param time_in_us deep-sleep time, unit: microsecond
*
@ -63,6 +66,15 @@ typedef enum {
*/
void esp_deep_sleep(uint32_t time_in_us);
/**
* @brief Set implementation-specific power management configuration
* @param config pointer to implementation-specific configuration structure (e.g. esp_pm_config_esp32)
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if the configuration values are not correct
* - ESP_ERR_NOT_SUPPORTED if certain combination of values is not supported.
*/
esp_err_t esp_pm_configure(const void* config);
/**
* @brief Call this API before esp_deep_sleep and esp_wifi_init to set the activity after the
@ -207,9 +219,12 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint32_t time_in_us);
/**
* @brief Enter light sleep with the configured wakeup options
*
* @attention esp_deep_sleep does not shut down WiFi and higher level protocol
* connections gracefully. Make sure esp_wifi_stop are called to close any
* connections and deinitialize the peripherals.
* @return
* - ESP_OK on success (returned after wakeup)
* - ESP_ERR_INVALID_STATE if WiFi or BT is not stopped
* - ESP_ERR_INVALID_STATE if WiFi is not stopped
*/
esp_err_t esp_light_sleep_start(void);

View File

@ -977,6 +977,16 @@ esp_err_t esp_wifi_get_event_mask(uint32_t *mask);
*/
esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len, bool en_sys_seq);
/**
* @brief Operation system start check time and enter sleep
*
* @note This function is called by system, user should not call this
*
* @return
* - wifi state
*/
wifi_state_t esp_wifi_get_state(void);
#ifdef __cplusplus
}
#endif

View File

@ -184,12 +184,31 @@ typedef struct {
wifi_auth_mode_t authmode; /**< The weakest authmode to accept in the fast scan mode */
} wifi_fast_scan_threshold_t;
typedef enum {
WIFI_STATE_DEINIT=0,
WIFI_STATE_INIT,
WIFI_STATE_START
}wifi_state_t;
typedef enum {
WIFI_PS_NONE, /**< No power save */
WIFI_PS_MAX_MODEM, /**< Maximum modem power saving. In this mode, station close cpu and RF in DTIM period */
WIFI_PS_MIN_MODEM, /**< Minimum modem power saving. In this mode, station close RF in DTIM period */
WIFI_PS_MIN_MODEM, /**< Minimum modem power saving. In this mode, station wakes up to receive beacon every DTIM period */
WIFI_PS_MAX_MODEM, /**< Maximum modem power saving. In this mode, interval to receive beacons is determined by the listen_interval
parameter in wifi_sta_config_t.
Attention: Using this option may cause ping failures. Not recommended */
} wifi_ps_type_t;
/**
* @brief Power management config for ESP8266
*
* Pass a pointer to this structure as an argument to esp_pm_configure function.
*/
typedef struct {
int max_freq_mhz; /*!< Not used in ESP8266 */
int min_freq_mhz; /*!< Not used in ESP8266 */
bool light_sleep_enable; /*!< Enter light sleep when no locks are taken */
} esp_pm_config_esp8266_t;
#define WIFI_PS_MODEM WIFI_PS_MIN_MODEM /**< @deprecated Use WIFI_PS_MIN_MODEM or WIFI_PS_MAX_MODEM instead */
#define WIFI_PROTOCOL_11B 1

View File

@ -175,6 +175,22 @@ esp_err_t esp_wifi_internal_set_log_mod(uint32_t submodule);
*/
esp_err_t esp_wifi_internal_get_log(wifi_log_level_t *log_level, uint32_t *log_mod);
/**
* @brief Receive broadcast/multicast packet or not when WiFi in power save.
*
* @param enable receive broadcast/multicast packet when set to true.
*/
void esp_wifi_set_pm_recv_multi_data(bool enable);
/**
* @brief Receive broadcast/multicast packet or not when WiFi in power save
*
* @return
* - true: receive broadcast/multicast packet or not when WiFi in power save
* - false: drop broadcast/multicast packet or not when WiFi in power save
*/
bool esp_wifi_get_pm_recv_multi_data(void);
#ifdef __cplusplus
}
#endif

View File

@ -18,6 +18,7 @@
#include "esp_log.h"
#include "esp_system.h"
#include "esp_sleep.h"
#include "esp_wifi.h"
#include "FreeRTOS.h"
#include "freertos/task.h"
#include "driver/soc.h"
@ -374,6 +375,10 @@ esp_err_t esp_light_sleep_start(void)
.flush_uart = 1
};
if (esp_wifi_get_state() >= WIFI_STATE_START) {
return ESP_ERR_INVALID_STATE;
}
return esp_light_sleep_internal(&proc);
}
@ -407,3 +412,18 @@ void esp_sleep_start(void)
esp_light_sleep_internal(&proc);
}
esp_err_t esp_pm_configure(const void* vconfig)
{
#ifndef CONFIG_PM_ENABLE
return ESP_ERR_NOT_SUPPORTED;
#endif
const esp_pm_config_esp8266_t* config = (const esp_pm_config_esp8266_t*) vconfig;
if (config->light_sleep_enable) {
s_sleep_mode = ESP_CPU_LIGHTSLEEP;
} else {
s_sleep_mode = ESP_CPU_WAIT;
}
return ESP_OK;
}

View File

@ -74,6 +74,10 @@ static void user_init_entry(void *param)
extern void app_main(void);
extern void phy_close_rf(void);
extern void esp_sleep_unlock();
/* initialize C++ construture function */
for (func = &__init_array_start; func < &__init_array_end; func++)
func[0]();
@ -89,6 +93,8 @@ static void user_init_entry(void *param)
assert(mac_init() == 0);
assert(base_gpio_init() == 0);
esp_phy_load_cal_and_init(0);
phy_close_rf();
esp_sleep_unlock();
esp_wifi_set_rx_pbuf_mem_type(WIFI_RX_PBUF_DRAM);

View File

@ -2,12 +2,12 @@
This example shows how to use power save mode of wifi.
Power save mode only works in station mode. If the modem sleep mode is enabled, station will switch between active and sleep state periodically after connecting to AP successfully. Station can keep connection with AP in modem sleep mode.
Power save mode only works in station mode. If the modem sleep mode is enabled, station will switch between active and sleep state periodically after connecting to AP successfully. In sleep state, RF, PHY and BB are turned off in order to reduce power consumption. Station can keep connection with AP in modem sleep mode.
* No power save: This is default mode. And the esp8266 will work with full power.
* Minimum modem sleep: In minimum modem sleep mode, station wakes up every DTIM to receive beacon. In sleep state, RF, PHY and BB are turned off in order to reduce power consumption. .
* Minimum modem sleep: In minimum modem sleep mode, station wakes up every DTIM to receive beacon. Broadcast data will not be lost because it is transmitted after DTIM. However, it can not save much more power if DTIM is short for DTIM is determined by AP.
* Maximum modem sleep: In maximum modem sleep mode, station wakes up every DTIM to receive beacon. In sleep state, CPU, RF, PHY and BB are turned off in order to reduce power consumption. .
* Maximum modem sleep: In maximum modem sleep mode, station wakes up every listen interval to receive beacon. Broadcast data may be lost because station may be in sleep state at DTIM time. If listen interval is longer, more power is saved but broadcast data is more easy to lose.
* others: not supported yet.

View File

@ -10,7 +10,7 @@
/*
this example shows how to use power save mode
set a router or a AP using the same SSID&PASSWORD as configuration of this example.
start esp32 and when it connected to AP it will enter power save mode
start esp8266 and when it connected to AP it will enter power save mode
*/
#include <string.h>
@ -21,6 +21,7 @@
#include "esp_netif.h"
#include "esp_event.h"
#include "esp_wifi.h"
#include "esp_sleep.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"
@ -44,4 +45,14 @@ void app_main(void)
ESP_ERROR_CHECK(example_connect());
esp_wifi_set_ps(DEFAULT_PS_MODE);
#if CONFIG_PM_ENABLE
// Configure dynamic frequency scaling:
// maximum and minimum frequencies are set in sdkconfig,
// automatic light sleep is enabled if tickless idle support is enabled.
esp_pm_config_esp8266_t pm_config = {
.light_sleep_enable = true
};
ESP_ERROR_CHECK( esp_pm_configure(&pm_config) );
#endif // CONFIG_PM_ENABLE
}