cpu/esp_common: stop WiFi interface before sleep/reboot
The WiFi interface should be stopped before reboot or sleep. But stopping the WiFi interface disconnects an existing connection. Usually, esp_wifi_netdev tries to reconnect on an disconnect event. However, trying reconnect with a stopped WiFi interface may lead to a crash. Therefore, the stop event has to be handled.
This commit is contained in:
parent
09899e4b8d
commit
4f977316fe
@ -34,6 +34,23 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
static inline esp_sleep_wakeup_cause_t pm_get_wakeup_cause(void)
|
||||
{
|
||||
return esp_sleep_get_wakeup_cause();
|
||||
}
|
||||
|
||||
/* function that is required by pm_set if esp_now and esp_wifi are not used */
|
||||
esp_err_t __attribute__((weak)) esp_wifi_start(void)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* function that is required by pm_set if esp_now and esp_wifi are not used */
|
||||
esp_err_t __attribute__((weak)) esp_wifi_stop(void)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static inline void pm_set_lowest_normal(void)
|
||||
{
|
||||
/* reset system watchdog timer */
|
||||
@ -65,6 +82,11 @@ void pm_reboot(void)
|
||||
{
|
||||
DEBUG ("%s\n", __func__);
|
||||
|
||||
if (IS_USED(MODULE_ESP_WIFI_ANY)) {
|
||||
/* stop WiFi if necessary */
|
||||
esp_wifi_stop();
|
||||
}
|
||||
|
||||
/* suspend and flush UARTs */
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF);
|
||||
@ -121,6 +143,10 @@ void pm_set(unsigned mode)
|
||||
UNREACHABLE();
|
||||
}
|
||||
else if (mode == ESP_PM_LIGHT_SLEEP) {
|
||||
if (IS_USED(MODULE_ESP_WIFI_ANY)) {
|
||||
/* stop WiFi if necessary */
|
||||
esp_wifi_stop();
|
||||
}
|
||||
|
||||
esp_light_sleep_start();
|
||||
|
||||
@ -130,6 +156,10 @@ void pm_set(unsigned mode)
|
||||
|
||||
DEBUG ("%s exit from power mode %d @%u with reason %d\n", __func__,
|
||||
mode, system_get_time(), wakeup_reason);
|
||||
|
||||
/* restart WiFi if necessary */
|
||||
if (IS_USED(MODULE_ESP_WIFI_ANY) && (esp_wifi_start() != ESP_OK)) {
|
||||
LOG_ERROR("esp_wifi_start failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -398,6 +398,8 @@ static const char *_esp_wifi_disc_reasons [] = {
|
||||
"HANDSHAKE_TIMEOUT" /* 204 */
|
||||
};
|
||||
|
||||
static unsigned _esp_wifi_started = 0;
|
||||
|
||||
/*
|
||||
* Event handler for esp system events.
|
||||
*/
|
||||
@ -412,6 +414,7 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t *
|
||||
|
||||
switch(event->event_id) {
|
||||
case SYSTEM_EVENT_STA_START:
|
||||
_esp_wifi_started = 1;
|
||||
ESP_WIFI_DEBUG("WiFi started");
|
||||
result = esp_wifi_connect();
|
||||
if (result != ESP_OK) {
|
||||
@ -420,6 +423,11 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t *
|
||||
}
|
||||
break;
|
||||
|
||||
case SYSTEM_EVENT_STA_STOP:
|
||||
_esp_wifi_started = 0;
|
||||
ESP_WIFI_DEBUG("WiFi stopped");
|
||||
break;
|
||||
|
||||
case SYSTEM_EVENT_SCAN_DONE:
|
||||
ESP_WIFI_DEBUG("WiFi scan done");
|
||||
break;
|
||||
@ -457,6 +465,7 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t *
|
||||
_esp_wifi_dev.event_disc++;
|
||||
netdev_trigger_event_isr(&_esp_wifi_dev.netdev);
|
||||
|
||||
if (reason != WIFI_REASON_ASSOC_LEAVE) {
|
||||
/* call disconnect to reset internal state */
|
||||
result = esp_wifi_disconnect();
|
||||
if (result != ESP_OK) {
|
||||
@ -466,11 +475,11 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t *
|
||||
}
|
||||
|
||||
/* try to reconnect */
|
||||
result = esp_wifi_connect();
|
||||
if (result != ESP_OK) {
|
||||
if (_esp_wifi_started && ((result = esp_wifi_connect()) != ESP_OK)) {
|
||||
ESP_WIFI_LOG_ERROR("esp_wifi_connect failed with "
|
||||
"return value %d", result);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user