Skip to content

Commit e66a0ad

Browse files
committed
esp_restart: add proper shutdown handlers
This creates a common esp_restart call to be used across the system and also implements the shutdown handler, needed for Wi-Fi, BLE and esp_timer(TBD). Signed-off-by: Sylvio Alves <[email protected]>
1 parent 82a67d4 commit e66a0ad

File tree

9 files changed

+147
-2
lines changed

9 files changed

+147
-2
lines changed

zephyr/common/esp_restart.c

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include "esp_system.h"
9+
#include "esp_private/system_internal.h"
10+
#include <stdint.h>
11+
#include "esp_cpu.h"
12+
#include "soc/soc.h"
13+
#include "soc/soc_caps.h"
14+
#include "esp_private/rtc_clk.h"
15+
#include "esp_private/panic_internal.h"
16+
#include "esp_private/system_internal.h"
17+
#include "esp_private/spi_flash_os.h"
18+
#include "esp_rom_uart.h"
19+
#include "esp_rom_sys.h"
20+
#include "sdkconfig.h"
21+
22+
#if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
23+
#if CONFIG_IDF_TARGET_ESP32S2
24+
#include "esp32s2/memprot.h"
25+
#else
26+
#include "esp_memprot.h"
27+
#endif
28+
#endif
29+
30+
#define SHUTDOWN_HANDLERS_NO 5
31+
32+
static shutdown_handler_t shutdown_handlers[SHUTDOWN_HANDLERS_NO];
33+
34+
esp_err_t esp_register_shutdown_handler(shutdown_handler_t handler)
35+
{
36+
for (int i = 0; i < SHUTDOWN_HANDLERS_NO; i++) {
37+
if (shutdown_handlers[i] == handler) {
38+
return ESP_ERR_INVALID_STATE;
39+
} else if (shutdown_handlers[i] == NULL) {
40+
shutdown_handlers[i] = handler;
41+
return ESP_OK;
42+
}
43+
}
44+
return ESP_ERR_NO_MEM;
45+
}
46+
47+
esp_err_t esp_unregister_shutdown_handler(shutdown_handler_t handler)
48+
{
49+
for (int i = 0; i < SHUTDOWN_HANDLERS_NO; i++) {
50+
if (shutdown_handlers[i] == handler) {
51+
shutdown_handlers[i] = NULL;
52+
return ESP_OK;
53+
}
54+
}
55+
return ESP_ERR_INVALID_STATE;
56+
}
57+
58+
void IRAM_ATTR esp_restart_noos_dig(void)
59+
{
60+
/* In case any of the calls below results in re-enabling of interrupts
61+
* (for example, by entering a critical section), disable all the
62+
* interrupts (e.g. from watchdogs) here.
63+
*/
64+
#ifdef CONFIG_IDF_TARGET_ARCH_RISCV
65+
rv_utils_intr_global_disable();
66+
#else
67+
xt_ints_off(0xFFFFFFFF);
68+
#endif
69+
70+
/* make sure all the panic handler output is sent from UART FIFO */
71+
if (CONFIG_ESP_CONSOLE_UART_NUM >= 0) {
72+
esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM);
73+
}
74+
75+
#if SOC_MEMSPI_CLOCK_IS_INDEPENDENT
76+
spi_flash_set_clock_src(MSPI_CLK_SRC_ROM_DEFAULT);
77+
#endif
78+
79+
/* switch to XTAL (otherwise we will keep running from the PLL) */
80+
rtc_clk_cpu_set_to_default_config();
81+
82+
/* esp_restart_noos_dig() will generates a core reset, which does not reset the
83+
* registers of the RTC domain, so the CPU's stall state remains after the reset,
84+
* we need to release them here
85+
*/
86+
#if !CONFIG_FREERTOS_UNICORE
87+
int core_id = esp_cpu_get_core_id();
88+
for (uint32_t i = 0; i < SOC_CPU_CORES_NUM; i++) {
89+
if (i != core_id) {
90+
esp_cpu_unstall(i);
91+
}
92+
}
93+
#endif
94+
esp_rom_software_reset_system();
95+
while (true) {
96+
;
97+
}
98+
}
99+
100+
void esp_restart(void)
101+
{
102+
for (int i = SHUTDOWN_HANDLERS_NO - 1; i >= 0; i--) {
103+
if (shutdown_handlers[i]) {
104+
shutdown_handlers[i]();
105+
}
106+
}
107+
108+
k_sched_lock();
109+
110+
bool digital_reset_needed = false;
111+
#if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
112+
#if CONFIG_IDF_TARGET_ESP32S2
113+
if (esp_memprot_is_intr_ena_any() || esp_memprot_is_locked_any()) {
114+
digital_reset_needed = true;
115+
}
116+
#else
117+
bool is_on = false;
118+
if (esp_mprot_is_intr_ena_any(&is_on) != ESP_OK || is_on) {
119+
digital_reset_needed = true;
120+
} else if (esp_mprot_is_conf_locked_any(&is_on) != ESP_OK || is_on) {
121+
digital_reset_needed = true;
122+
}
123+
#endif
124+
#endif
125+
if (digital_reset_needed) {
126+
esp_restart_noos_dig();
127+
}
128+
esp_restart_noos();
129+
}

zephyr/esp32/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ if(CONFIG_SOC_SERIES_ESP32)
347347
../port/bootloader/bootloader_flash.c
348348

349349
../common/flash_init.c
350+
../common/esp_restart.c
350351

351352
src/stubs.c
352353
src/soc_random.c

zephyr/esp32/src/bt/esp_bt_adapter.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#include "private/esp_coexist_internal.h"
3232
#include "esp_timer.h"
3333
#include "esp_heap_adapter.h"
34-
34+
#include "esp_system.h"
3535
#include "esp_rom_sys.h"
3636

3737
#include <zephyr/logging/log.h>
@@ -1254,6 +1254,10 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
12541254
}
12551255

12561256
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED;
1257+
ret = esp_register_shutdown_handler(bt_shutdown);
1258+
if (ret != ESP_OK) {
1259+
LOG_WRN("Register shutdown handler failed, ret = 0x%x", ret);
1260+
}
12571261

12581262
/* set default TX power level */
12591263
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, ESP32_RADIO_TXP_DEFAULT);
@@ -1284,7 +1288,7 @@ esp_err_t esp_bt_controller_disable(void)
12841288

12851289
esp_phy_disable(PHY_MODEM_BT);
12861290
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
1287-
bt_shutdown();
1291+
esp_unregister_shutdown_handler(bt_shutdown);
12881292

12891293
return ESP_OK;
12901294
}

zephyr/esp32c2/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ if(CONFIG_SOC_SERIES_ESP32C2)
268268
../port/bootloader/bootloader_flash.c
269269

270270
../common/flash_init.c
271+
../common/esp_restart.c
271272

272273
src/stubs.c
273274
src/soc_random.c

zephyr/esp32c3/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ if(CONFIG_SOC_SERIES_ESP32C3)
347347
../port/bootloader/bootloader_flash.c
348348

349349
../common/flash_init.c
350+
../common/esp_restart.c
350351

351352
src/stubs.c
352353
src/soc_random.c

zephyr/esp32c6/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ if(CONFIG_SOC_SERIES_ESP32C6)
285285
../port/bootloader/bootloader_flash.c
286286

287287
../common/flash_init.c
288+
../common/esp_restart.c
288289

289290
src/stubs.c
290291
src/soc_random.c

zephyr/esp32s2/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ if(CONFIG_SOC_SERIES_ESP32S2)
358358
../port/bootloader/bootloader_flash.c
359359

360360
../common/flash_init.c
361+
../common/esp_restart.c
361362

362363
src/stubs.c
363364
src/soc_random.c

zephyr/esp32s3/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ if(CONFIG_SOC_SERIES_ESP32S3)
377377
../port/bootloader/bootloader_flash.c
378378

379379
../common/flash_init.c
380+
../common/esp_restart.c
380381

381382
src/stubs.c
382383
src/soc_random.c

zephyr/port/wifi/wifi_init.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "esp_phy_init.h"
2626
#include "esp_private/phy.h"
2727
#include "private/esp_modem_wrapper.h"
28+
#include "esp_system.h"
2829

2930
#ifdef CONFIG_ESP_WIFI_NAN_ENABLE
3031
#include "apps_private/wifi_apps_private.h"
@@ -323,6 +324,11 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
323324
esp_nan_app_init();
324325
#endif
325326

327+
result = esp_register_shutdown_handler((shutdown_handler_t)esp_wifi_stop);
328+
if (result != ESP_OK && result != ESP_ERR_INVALID_STATE) {
329+
LOG_ERR("Failed to init wifi (0x%x)", result);
330+
}
331+
326332
s_wifi_inited = true;
327333

328334
return result;

0 commit comments

Comments
 (0)