1 /* 2 * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include "esp_system.h" 8 #include "esp_private/system_internal.h" 9 #include "freertos/FreeRTOS.h" 10 #include "freertos/task.h" 11 #if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE 12 #if CONFIG_IDF_TARGET_ESP32S2 13 #include "esp32s2/memprot.h" 14 #else 15 #include "esp_memprot.h" 16 #endif 17 #endif 18 19 #define SHUTDOWN_HANDLERS_NO 5 20 21 static shutdown_handler_t shutdown_handlers[SHUTDOWN_HANDLERS_NO]; 22 esp_register_shutdown_handler(shutdown_handler_t handler)23esp_err_t esp_register_shutdown_handler(shutdown_handler_t handler) 24 { 25 for (int i = 0; i < SHUTDOWN_HANDLERS_NO; i++) { 26 if (shutdown_handlers[i] == handler) { 27 return ESP_ERR_INVALID_STATE; 28 } else if (shutdown_handlers[i] == NULL) { 29 shutdown_handlers[i] = handler; 30 return ESP_OK; 31 } 32 } 33 return ESP_ERR_NO_MEM; 34 } 35 esp_unregister_shutdown_handler(shutdown_handler_t handler)36esp_err_t esp_unregister_shutdown_handler(shutdown_handler_t handler) 37 { 38 for (int i = 0; i < SHUTDOWN_HANDLERS_NO; i++) { 39 if (shutdown_handlers[i] == handler) { 40 shutdown_handlers[i] = NULL; 41 return ESP_OK; 42 } 43 } 44 return ESP_ERR_INVALID_STATE; 45 } 46 47 esp_restart(void)48void esp_restart(void) 49 { 50 for (int i = SHUTDOWN_HANDLERS_NO - 1; i >= 0; i--) { 51 if (shutdown_handlers[i]) { 52 shutdown_handlers[i](); 53 } 54 } 55 56 #ifdef CONFIG_FREERTOS_SMP 57 //Note: Scheduler suspension behavior changed in FreeRTOS SMP 58 vTaskPreemptionDisable(NULL); 59 #else 60 // Disable scheduler on this core. 61 vTaskSuspendAll(); 62 #endif // CONFIG_FREERTOS_SMP 63 64 bool digital_reset_needed = false; 65 #if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE 66 #if CONFIG_IDF_TARGET_ESP32S2 67 if (esp_memprot_is_intr_ena_any() || esp_memprot_is_locked_any()) { 68 digital_reset_needed = true; 69 } 70 #else 71 bool is_on = false; 72 if (esp_mprot_is_intr_ena_any(&is_on) != ESP_OK || is_on) { 73 digital_reset_needed = true; 74 } else if (esp_mprot_is_conf_locked_any(&is_on) != ESP_OK || is_on) { 75 digital_reset_needed = true; 76 } 77 #endif 78 #endif 79 if (digital_reset_needed) { 80 esp_restart_noos_dig(); 81 } 82 esp_restart_noos(); 83 } 84