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.h"
|
||||||
#include "soc/rtc_cntl_reg.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)
|
static inline void pm_set_lowest_normal(void)
|
||||||
{
|
{
|
||||||
/* reset system watchdog timer */
|
/* reset system watchdog timer */
|
||||||
@ -65,6 +82,11 @@ void pm_reboot(void)
|
|||||||
{
|
{
|
||||||
DEBUG ("%s\n", __func__);
|
DEBUG ("%s\n", __func__);
|
||||||
|
|
||||||
|
if (IS_USED(MODULE_ESP_WIFI_ANY)) {
|
||||||
|
/* stop WiFi if necessary */
|
||||||
|
esp_wifi_stop();
|
||||||
|
}
|
||||||
|
|
||||||
/* suspend and flush UARTs */
|
/* suspend and flush UARTs */
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF);
|
REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF);
|
||||||
@ -121,6 +143,10 @@ void pm_set(unsigned mode)
|
|||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
else if (mode == ESP_PM_LIGHT_SLEEP) {
|
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();
|
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__,
|
DEBUG ("%s exit from power mode %d @%u with reason %d\n", __func__,
|
||||||
mode, system_get_time(), wakeup_reason);
|
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 */
|
"HANDSHAKE_TIMEOUT" /* 204 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static unsigned _esp_wifi_started = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Event handler for esp system events.
|
* 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) {
|
switch(event->event_id) {
|
||||||
case SYSTEM_EVENT_STA_START:
|
case SYSTEM_EVENT_STA_START:
|
||||||
|
_esp_wifi_started = 1;
|
||||||
ESP_WIFI_DEBUG("WiFi started");
|
ESP_WIFI_DEBUG("WiFi started");
|
||||||
result = esp_wifi_connect();
|
result = esp_wifi_connect();
|
||||||
if (result != ESP_OK) {
|
if (result != ESP_OK) {
|
||||||
@ -420,6 +423,11 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t *
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SYSTEM_EVENT_STA_STOP:
|
||||||
|
_esp_wifi_started = 0;
|
||||||
|
ESP_WIFI_DEBUG("WiFi stopped");
|
||||||
|
break;
|
||||||
|
|
||||||
case SYSTEM_EVENT_SCAN_DONE:
|
case SYSTEM_EVENT_SCAN_DONE:
|
||||||
ESP_WIFI_DEBUG("WiFi scan done");
|
ESP_WIFI_DEBUG("WiFi scan done");
|
||||||
break;
|
break;
|
||||||
@ -457,19 +465,20 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t *
|
|||||||
_esp_wifi_dev.event_disc++;
|
_esp_wifi_dev.event_disc++;
|
||||||
netdev_trigger_event_isr(&_esp_wifi_dev.netdev);
|
netdev_trigger_event_isr(&_esp_wifi_dev.netdev);
|
||||||
|
|
||||||
/* call disconnect to reset internal state */
|
if (reason != WIFI_REASON_ASSOC_LEAVE) {
|
||||||
result = esp_wifi_disconnect();
|
/* call disconnect to reset internal state */
|
||||||
if (result != ESP_OK) {
|
result = esp_wifi_disconnect();
|
||||||
ESP_WIFI_LOG_ERROR("esp_wifi_disconnect failed with "
|
if (result != ESP_OK) {
|
||||||
"return value %d", result);
|
ESP_WIFI_LOG_ERROR("esp_wifi_disconnect failed with "
|
||||||
return result;
|
"return value %d", result);
|
||||||
}
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* try to reconnect */
|
/* try to reconnect */
|
||||||
result = esp_wifi_connect();
|
if (_esp_wifi_started && ((result = esp_wifi_connect()) != ESP_OK)) {
|
||||||
if (result != ESP_OK) {
|
ESP_WIFI_LOG_ERROR("esp_wifi_connect failed with "
|
||||||
ESP_WIFI_LOG_ERROR("esp_wifi_connect failed with "
|
"return value %d", result);
|
||||||
"return value %d", result);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user