diff --git a/components/esp32/event_default_handlers.c b/components/esp32/event_default_handlers.c index fa32d2cbc..34a0ddcb4 100644 --- a/components/esp32/event_default_handlers.c +++ b/components/esp32/event_default_handlers.c @@ -23,6 +23,7 @@ #include "esp_event_loop.h" #include "esp_task.h" #include "esp_eth.h" +#include "esp_system.h" #include "rom/ets_sys.h" @@ -413,5 +414,6 @@ esp_err_t esp_wifi_init(wifi_init_config_t *config) default_event_handlers[SYSTEM_EVENT_AP_START] = system_event_ap_start_handle_default; default_event_handlers[SYSTEM_EVENT_AP_STOP] = system_event_ap_stop_handle_default; + esp_register_shutdown_handler((shutdown_handler_t)esp_wifi_stop); return esp_wifi_init_internal(config); } diff --git a/components/esp32/include/esp_system.h b/components/esp32/include/esp_system.h index 3921dfb8d..c2064fd49 100644 --- a/components/esp32/include/esp_system.h +++ b/components/esp32/include/esp_system.h @@ -49,6 +49,15 @@ void system_init(void) __attribute__ ((deprecated)); */ void system_restore(void) __attribute__ ((deprecated)); +typedef void (*shutdown_handler_t)(void); +/** + * @brief Register shutdown handler + * + * This function allows you to register a handler that gets invoked before a + * systematic shutdown of the chip. + */ +esp_err_t esp_register_shutdown_handler(shutdown_handler_t handle); + /** * @brief Restart PRO and APP CPUs. * diff --git a/components/esp32/system_api.c b/components/esp32/system_api.c index 1b541f1cb..145b0532a 100644 --- a/components/esp32/system_api.c +++ b/components/esp32/system_api.c @@ -39,6 +39,9 @@ static const char* TAG = "system_api"; static uint8_t base_mac_addr[6] = { 0 }; +#define SHUTDOWN_HANDLERS_NO 2 +static shutdown_handler_t shutdown_handlers[SHUTDOWN_HANDLERS_NO]; + void system_init() { } @@ -227,23 +230,28 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type) return ESP_OK; } -void esp_restart_noos() __attribute__ ((noreturn)); - -/* Dummy function to be used instead of esp_wifi_stop if WiFi stack is not - * linked in (even though CONFIG_WIFI_ENABLED is set). - */ -esp_err_t wifi_stop_noop() +esp_err_t esp_register_shutdown_handler(shutdown_handler_t handler) { - return ESP_OK; + int i; + for (i = 0; i < SHUTDOWN_HANDLERS_NO; i++) { + if (shutdown_handlers[i] == NULL) { + shutdown_handlers[i] = handler; + return ESP_OK; + } + } + return ESP_FAIL; } -esp_err_t esp_wifi_stop(void) __attribute((weak, alias("wifi_stop_noop"))); +void esp_restart_noos() __attribute__ ((noreturn)); void IRAM_ATTR esp_restart(void) { -#ifdef CONFIG_WIFI_ENABLED - esp_wifi_stop(); -#endif + int i; + for (i = 0; i < SHUTDOWN_HANDLERS_NO; i++) { + if (shutdown_handlers[i]) { + shutdown_handlers[i](); + } + } // Disable scheduler on this core. vTaskSuspendAll();