2021-11-06 17:24:45 +08:00
/*
2025-01-27 17:48:09 +01:00
* SPDX - FileCopyrightText : 2015 - 2025 Espressif Systems ( Shanghai ) CO LTD
2021-11-06 17:24:45 +08:00
*
* SPDX - License - Identifier : Apache - 2.0
*/
2020-02-02 23:23:16 +08:00
# include <stdlib.h>
2020-10-02 11:17:38 +08:00
# include <string.h>
2020-02-02 23:23:16 +08:00
2024-07-04 23:57:11 +07:00
# include "esp_macros.h"
2020-02-02 23:23:16 +08:00
# include "esp_err.h"
# include "esp_attr.h"
2024-06-06 15:23:02 +07:00
# include "esp_compiler.h"
2020-02-02 23:23:16 +08:00
# include "esp_private/system_internal.h"
2020-04-30 16:48:49 +02:00
# include "esp_private/usb_console.h"
2020-02-02 23:23:16 +08:00
2021-12-14 10:08:15 +05:30
# include "esp_cpu.h"
2019-12-26 16:30:03 +08:00
# include "soc/rtc.h"
2020-02-02 23:23:16 +08:00
# include "hal/timer_hal.h"
2019-12-26 16:30:03 +08:00
# include "hal/wdt_types.h"
# include "hal/wdt_hal.h"
2023-02-17 14:51:00 +08:00
# include "hal/mwdt_ll.h"
2022-07-07 14:54:15 +08:00
# include "esp_private/esp_int_wdt.h"
2020-02-02 23:23:16 +08:00
2020-06-08 19:32:35 +03:00
# include "esp_private/panic_internal.h"
2020-02-04 22:16:37 +08:00
# include "port/panic_funcs.h"
2021-04-19 12:03:43 +03:00
# include "esp_rom_sys.h"
2020-02-02 23:23:16 +08:00
# include "sdkconfig.h"
2023-05-04 17:14:46 +08:00
# if !CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT
2022-07-29 16:07:04 +05:30
# if __has_include("esp_app_desc.h")
# define WITH_ELF_SHA256
# include "esp_app_desc.h"
2022-02-07 17:20:59 +08:00
# endif
2023-05-04 17:14:46 +08:00
# endif // CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT
2022-02-07 17:20:59 +08:00
2021-01-26 13:03:14 +08:00
# if CONFIG_ESP_COREDUMP_ENABLE
2020-10-08 13:18:16 +08:00
# include "esp_core_dump.h"
# endif
# if CONFIG_APPTRACE_ENABLE
# include "esp_app_trace.h"
2020-12-21 20:17:42 +03:00
# if CONFIG_APPTRACE_SV_ENABLE
2020-10-08 13:18:16 +08:00
# include "SEGGER_RTT.h"
# endif
2020-02-02 23:23:16 +08:00
# if CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO == -1
# define APPTRACE_ONPANIC_HOST_FLUSH_TMO ESP_APPTRACE_TMO_INFINITE
# else
# define APPTRACE_ONPANIC_HOST_FLUSH_TMO (1000*CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO)
# endif
2020-10-08 13:18:16 +08:00
# endif // CONFIG_APPTRACE_ENABLE
2020-02-02 23:23:16 +08:00
2020-10-02 11:17:38 +08:00
# if !CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT
# include "hal/uart_hal.h"
# endif
2020-11-06 15:00:07 +11:00
# if CONFIG_ESP_SYSTEM_PANIC_GDBSTUB
2020-10-02 11:17:38 +08:00
# include "esp_gdbstub.h"
2020-11-06 15:00:07 +11:00
# endif
2022-10-22 17:13:00 -07:00
# if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
2021-04-19 12:03:43 +03:00
# include "hal/usb_serial_jtag_ll.h"
# endif
2023-09-02 21:25:06 +02:00
# ifdef __XTENSA__
# include "xtensa/semihosting.h"
# elif __riscv
# include "riscv/semihosting.h"
# endif
2024-01-30 09:40:10 +08:00
# define ESP_SEMIHOSTING_SYS_PANIC_REASON 0x116
2023-09-02 21:25:06 +02:00
2023-02-17 14:51:00 +08:00
# define MWDT_DEFAULT_TICKS_PER_US 500
2025-01-27 17:48:09 +01:00
# define PANIC_ENTRY_COUNT_MAX 2 // We allow at least 2 panic entries to let the panic handler process Double Exceptions
2020-02-04 22:16:37 +08:00
bool g_panic_abort = false ;
2023-08-03 23:47:58 +02:00
char * g_panic_abort_details = NULL ;
2020-02-02 23:23:16 +08:00
2023-02-15 11:54:00 +08:00
static wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT ( ) ;
2019-12-26 16:30:03 +08:00
2025-01-27 17:48:09 +01:00
static uint32_t DRAM_ATTR g_panic_entry_count [ CONFIG_FREERTOS_NUMBER_OF_CORES ] = { 0 } ; // Number of times panic handler has been entered per core since multiple cores can enter the panic handler simultaneously
2020-02-02 23:23:16 +08:00
# if !CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT
2025-01-27 17:48:09 +01:00
/********************** Panic print functions **********************/
2020-04-30 16:48:49 +02:00
# if CONFIG_ESP_CONSOLE_UART
2021-04-19 12:03:43 +03:00
static uart_hal_context_t s_panic_uart = { . dev = CONFIG_ESP_CONSOLE_UART_NUM = = 0 ? & UART0 : & UART1 } ;
2020-02-02 23:23:16 +08:00
2022-10-22 17:13:00 -07:00
static void panic_print_char_uart ( const char c )
2020-02-02 23:23:16 +08:00
{
uint32_t sz = 0 ;
2021-04-19 12:03:43 +03:00
while ( ! uart_hal_get_txfifo_len ( & s_panic_uart ) ) ;
uart_hal_write_txfifo ( & s_panic_uart , ( uint8_t * ) & c , 1 , & sz ) ;
2020-02-02 23:23:16 +08:00
}
2020-04-30 16:48:49 +02:00
# endif // CONFIG_ESP_CONSOLE_UART
# if CONFIG_ESP_CONSOLE_USB_CDC
2022-10-22 17:13:00 -07:00
static void panic_print_char_usb_cdc ( const char c )
2020-04-30 16:48:49 +02:00
{
esp_usb_console_write_buf ( & c , 1 ) ;
/* result ignored */
}
# endif // CONFIG_ESP_CONSOLE_USB_CDC
2022-10-22 17:13:00 -07:00
# if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
2021-04-19 12:03:43 +03:00
//Timeout; if there's no host listening, the txfifo won't ever
//be writable after the first packet.
# define USBSERIAL_TIMEOUT_MAX_US 50000
static int s_usbserial_timeout = 0 ;
2022-10-22 17:13:00 -07:00
static void panic_print_char_usb_serial_jtag ( const char c )
2021-04-19 12:03:43 +03:00
{
while ( ! usb_serial_jtag_ll_txfifo_writable ( ) & & s_usbserial_timeout < ( USBSERIAL_TIMEOUT_MAX_US / 100 ) ) {
esp_rom_delay_us ( 100 ) ;
s_usbserial_timeout + + ;
}
if ( usb_serial_jtag_ll_txfifo_writable ( ) ) {
usb_serial_jtag_ll_write_txfifo ( ( const uint8_t * ) & c , 1 ) ;
s_usbserial_timeout = 0 ;
}
}
2022-10-22 17:13:00 -07:00
# endif //CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
2021-04-19 12:03:43 +03:00
2020-04-30 16:48:49 +02:00
void panic_print_char ( const char c )
{
2022-10-22 17:13:00 -07:00
# if CONFIG_ESP_CONSOLE_UART
panic_print_char_uart ( c ) ;
# endif
# if CONFIG_ESP_CONSOLE_USB_CDC
panic_print_char_usb_cdc ( c ) ;
# endif
# if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG
panic_print_char_usb_serial_jtag ( c ) ;
# endif
2020-04-30 16:48:49 +02:00
}
2020-02-02 23:23:16 +08:00
void panic_print_str ( const char * str )
{
2021-04-19 12:03:43 +03:00
for ( int i = 0 ; str [ i ] ! = 0 ; i + + ) {
2020-02-02 23:23:16 +08:00
panic_print_char ( str [ i ] ) ;
}
}
void panic_print_hex ( int h )
{
int x ;
int c ;
// Does not print '0x', only the digits (8 digits to print)
for ( x = 0 ; x < 8 ; x + + ) {
c = ( h > > 28 ) & 0xf ; // extract the leftmost byte
if ( c < 10 ) {
panic_print_char ( ' 0 ' + c ) ;
} else {
panic_print_char ( ' a ' + c - 10 ) ;
}
h < < = 4 ; // move the 2nd leftmost byte to the left, to be extracted next
}
}
void panic_print_dec ( int d )
{
// can print at most 2 digits!
int n1 , n2 ;
n1 = d % 10 ; // extract ones digit
n2 = d / 10 ; // extract tens digit
if ( n2 = = 0 ) {
panic_print_char ( ' ' ) ;
} else {
panic_print_char ( n2 + ' 0 ' ) ;
}
panic_print_char ( n1 + ' 0 ' ) ;
}
# endif // CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT
2025-01-27 17:48:09 +01:00
static void print_abort_details ( const void * f )
2020-02-02 23:23:16 +08:00
{
2025-01-27 17:48:09 +01:00
panic_print_str ( g_panic_abort_details ) ;
}
/********************** Panic handler watchdog timer functions **********************/
2021-06-24 18:02:28 +10:00
2025-01-27 17:48:09 +01:00
/* This function disables the Timer Group WDTs */
void esp_panic_handler_disable_timg_wdts ( void )
{
wdt_hal_context_t wdt0_context = { . inst = WDT_MWDT0 , . mwdt_dev = & TIMERG0 } ;
2019-12-26 16:30:03 +08:00
wdt_hal_write_protect_disable ( & wdt0_context ) ;
2025-01-27 17:48:09 +01:00
wdt_hal_disable ( & wdt0_context ) ;
2019-12-26 16:30:03 +08:00
wdt_hal_write_protect_enable ( & wdt0_context ) ;
2021-11-06 17:24:45 +08:00
# if SOC_TIMER_GROUPS >= 2
2025-01-27 17:48:09 +01:00
wdt_hal_context_t wdt1_context = { . inst = WDT_MWDT1 , . mwdt_dev = & TIMERG1 } ;
2019-12-26 16:30:03 +08:00
wdt_hal_write_protect_disable ( & wdt1_context ) ;
wdt_hal_disable ( & wdt1_context ) ;
wdt_hal_write_protect_enable ( & wdt1_context ) ;
2025-01-27 17:48:09 +01:00
# endif /* SOC_TIMER_GROUPS >= 2 */
2020-02-02 23:23:16 +08:00
}
2025-01-27 17:48:09 +01:00
/* This function enables the RTC WDT with the given timeout in milliseconds */
void esp_panic_handler_enable_rtc_wdt ( uint32_t timeout_ms )
{
wdt_hal_init ( & rtc_wdt_ctx , WDT_RWDT , 0 , false ) ;
uint32_t stage_timeout_ticks = ( uint32_t ) ( timeout_ms * rtc_clk_slow_freq_get_hz ( ) / 1000ULL ) ;
wdt_hal_write_protect_disable ( & rtc_wdt_ctx ) ;
wdt_hal_config_stage ( & rtc_wdt_ctx , WDT_STAGE0 , stage_timeout_ticks , WDT_STAGE_ACTION_RESET_RTC ) ;
wdt_hal_enable ( & rtc_wdt_ctx ) ;
wdt_hal_write_protect_enable ( & rtc_wdt_ctx ) ;
}
/* Feed the watchdogs if they are enabled and if we are not already in the panic handler */
void esp_panic_handler_feed_wdts ( void )
2020-02-02 23:23:16 +08:00
{
2025-01-27 17:48:09 +01:00
/* If we have already entered the panic handler multiple times,
* we should not feed the WDTs . This is because we need an
* alternate mechanism to reset the system if we happen to be stuck
* in a panic loop .
*/
if ( g_panic_entry_count [ esp_cpu_get_core_id ( ) ] > PANIC_ENTRY_COUNT_MAX ) {
return ;
}
// Feed Timer Group 0 WDT
2021-06-24 18:02:28 +10:00
wdt_hal_context_t wdt0_context = { . inst = WDT_MWDT0 , . mwdt_dev = & TIMERG0 } ;
2025-01-27 17:48:09 +01:00
if ( wdt_hal_is_enabled ( & wdt0_context ) ) {
wdt_hal_write_protect_disable ( & wdt0_context ) ;
wdt_hal_feed ( & wdt0_context ) ;
wdt_hal_write_protect_enable ( & wdt0_context ) ;
}
2021-11-06 17:24:45 +08:00
# if SOC_TIMER_GROUPS >= 2
2025-01-27 17:48:09 +01:00
// Feed Timer Group 1 WDT
2021-06-24 18:02:28 +10:00
wdt_hal_context_t wdt1_context = { . inst = WDT_MWDT1 , . mwdt_dev = & TIMERG1 } ;
2025-01-27 17:48:09 +01:00
if ( wdt_hal_is_enabled ( & wdt1_context ) ) {
wdt_hal_write_protect_disable ( & wdt1_context ) ;
wdt_hal_feed ( & wdt1_context ) ;
wdt_hal_write_protect_enable ( & wdt1_context ) ;
}
# endif /* SOC_TIMER_GROUPS >= 2 */
2021-06-24 18:02:28 +10:00
2025-01-27 17:48:09 +01:00
// Feed RTC WDT
if ( wdt_hal_is_enabled ( & rtc_wdt_ctx ) ) {
wdt_hal_write_protect_disable ( & rtc_wdt_ctx ) ;
wdt_hal_feed ( & rtc_wdt_ctx ) ;
wdt_hal_write_protect_enable ( & rtc_wdt_ctx ) ;
}
}
2019-12-26 16:30:03 +08:00
2025-01-27 17:48:09 +01:00
/* This function disables all the watchdogs */
static inline void disable_all_wdts ( void )
{
//Disable Timer Group WDTs
esp_panic_handler_disable_timg_wdts ( ) ;
//Disable RTC WDT
wdt_hal_write_protect_disable ( & rtc_wdt_ctx ) ;
wdt_hal_disable ( & rtc_wdt_ctx ) ;
wdt_hal_write_protect_enable ( & rtc_wdt_ctx ) ;
2020-02-02 23:23:16 +08:00
}
2025-01-27 17:48:09 +01:00
/********************** Panic handler functions **********************/
/* This function is called from the panic handler entry point to increment the panic entry count */
void esp_panic_handler_increment_entry_count ( void )
2020-02-02 23:23:16 +08:00
{
2025-01-27 17:48:09 +01:00
int core_id = esp_cpu_get_core_id ( ) ;
g_panic_entry_count [ core_id ] + + ;
if ( g_panic_entry_count [ core_id ] > PANIC_ENTRY_COUNT_MAX ) {
/* If we have already panicked multiple times, chances are
* that the panic handler itself is broken . In this case , we
* should just reset the system .
*/
panic_print_str ( " Panic handler entered multiple times. Abort panic handling. Rebooting ... \r \n " ) ;
panic_restart ( ) ;
}
2020-02-02 23:23:16 +08:00
}
// Control arrives from chip-specific panic handler, environment prepared for
// the 'main' logic of panic handling. This means that chip-specific stuff have
// already been done, and panic_info_t has been filled.
void esp_panic_handler ( panic_info_t * info )
{
2021-06-24 18:02:28 +10:00
// The port-level panic handler has already called this, but call it again
2025-01-27 17:48:09 +01:00
// to reset the RTC WDT period
esp_panic_handler_feed_wdts ( ) ;
2021-06-24 18:02:28 +10:00
2020-02-02 23:23:16 +08:00
// If the exception was due to an abort, override some of the panic info
2020-02-04 22:16:37 +08:00
if ( g_panic_abort ) {
2020-02-02 23:23:16 +08:00
info - > description = NULL ;
2023-08-03 23:47:58 +02:00
info - > details = g_panic_abort_details ? print_abort_details : NULL ;
2020-03-04 10:25:49 +08:00
info - > reason = NULL ;
2020-02-02 23:23:16 +08:00
info - > exception = PANIC_EXCEPTION_ABORT ;
}
2021-04-19 12:03:43 +03:00
/*
2025-01-27 17:48:09 +01:00
* For any supported chip , the panic handler prints the contents of panic_info_t in the following format :
*
*
* Guru Meditation Error : Core < core > ( < exception > ) . < description >
* < details >
*
* < state >
*
* < elf_info >
*
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* core - core where exception was triggered
* exception - what kind of exception occurred
* description - a short description regarding the exception that occurred
* details - more details about the exception
* state - processor state like register contents , and backtrace
* elf_info - details about the image currently running
*
* NULL fields in panic_info_t are not printed .
*
*/
2020-03-04 10:25:49 +08:00
if ( info - > reason ) {
panic_print_str ( " Guru Meditation Error: Core " ) ;
panic_print_dec ( info - > core ) ;
panic_print_str ( " panic'ed ( " ) ;
panic_print_str ( info - > reason ) ;
panic_print_str ( " ). " ) ;
}
2020-02-02 23:23:16 +08:00
if ( info - > description ) {
panic_print_str ( info - > description ) ;
}
panic_print_str ( " \r \n " ) ;
PANIC_INFO_DUMP ( info , details ) ;
panic_print_str ( " \r \n " ) ;
// If on-chip-debugger is attached, and system is configured to be aware of this,
// then only print up to details. Users should be able to probe for the other information
// in debug mode.
2023-10-18 00:04:17 +02:00
# if CONFIG_ESP_DEBUG_OCDAWARE
2022-07-19 13:20:07 +08:00
if ( esp_cpu_dbgr_is_attached ( ) ) {
2024-01-30 09:40:10 +08:00
char * panic_reason_str = NULL ;
if ( info - > pseudo_excause ) {
panic_reason_str = ( char * ) info - > reason ;
2024-11-30 15:15:01 +01:00
} else if ( g_panic_abort ) {
2024-01-30 09:40:10 +08:00
panic_reason_str = g_panic_abort_details ;
}
if ( panic_reason_str ) {
/* OpenOCD will print the halt cause when target is stopped at the below breakpoint (info->addr) */
long args [ ] = { ( long ) panic_reason_str , strlen ( panic_reason_str ) } ;
semihosting_call_noerrno ( ESP_SEMIHOSTING_SYS_PANIC_REASON , args ) ;
}
2020-02-02 23:23:16 +08:00
panic_print_str ( " Setting breakpoint at 0x " ) ;
panic_print_hex ( ( uint32_t ) info - > addr ) ;
panic_print_str ( " and returning... \r \n " ) ;
# if CONFIG_APPTRACE_ENABLE
2020-12-21 20:17:42 +03:00
# if CONFIG_APPTRACE_SV_ENABLE
SEGGER_RTT_ESP_FlushNoLock ( CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH , APPTRACE_ONPANIC_HOST_FLUSH_TMO ) ;
2020-02-02 23:23:16 +08:00
# else
esp_apptrace_flush_nolock ( ESP_APPTRACE_DEST_TRAX , CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH ,
APPTRACE_ONPANIC_HOST_FLUSH_TMO ) ;
# endif
# endif
2025-01-27 17:48:09 +01:00
disable_all_wdts ( ) ;
2022-07-21 19:24:42 +08:00
esp_cpu_set_breakpoint ( 0 , info - > addr ) ; // use breakpoint 0
2020-02-02 23:23:16 +08:00
return ;
}
2023-10-18 00:04:17 +02:00
# endif //CONFIG_ESP_DEBUG_OCDAWARE
2020-02-02 23:23:16 +08:00
2025-01-27 17:48:09 +01:00
/* Feed the WDTs here. This is done to fascilitate a "slow" UART
* which might take a longer time to print the state of the processor .
*/
esp_panic_handler_feed_wdts ( ) ;
2020-02-02 23:23:16 +08:00
PANIC_INFO_DUMP ( info , state ) ;
panic_print_str ( " \r \n " ) ;
2022-10-27 18:41:19 +08:00
/* No matter if we come here from abort or an exception, this variable must be reset.
* Else , any exception / error occurring during the current panic handler would considered
* an abort . Do this after PANIC_INFO_DUMP ( info , state ) as it also checks this variable .
* For example , if coredump triggers a stack overflow and this variable is not reset ,
* the second panic would be still be marked as the result of an abort , even the previous
* message reason would be kept . */
g_panic_abort = false ;
2022-07-29 16:07:04 +05:30
# ifdef WITH_ELF_SHA256
2020-02-02 23:23:16 +08:00
panic_print_str ( " \r \n ELF file SHA256: " ) ;
2023-05-04 17:14:46 +08:00
panic_print_str ( esp_app_get_elf_sha256_str ( ) ) ;
2020-02-02 23:23:16 +08:00
panic_print_str ( " \r \n " ) ;
2023-05-04 17:14:46 +08:00
# endif // WITH_ELF_SHA256
2020-02-02 23:23:16 +08:00
panic_print_str ( " \r \n " ) ;
# if CONFIG_APPTRACE_ENABLE
2025-01-27 17:48:09 +01:00
esp_panic_handler_feed_wdts ( ) ;
2020-12-21 20:17:42 +03:00
# if CONFIG_APPTRACE_SV_ENABLE
SEGGER_RTT_ESP_FlushNoLock ( CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH , APPTRACE_ONPANIC_HOST_FLUSH_TMO ) ;
2020-02-02 23:23:16 +08:00
# else
esp_apptrace_flush_nolock ( ESP_APPTRACE_DEST_TRAX , CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH ,
APPTRACE_ONPANIC_HOST_FLUSH_TMO ) ;
# endif
2021-06-24 18:02:28 +10:00
# endif // CONFIG_APPTRACE_ENABLE
2020-02-02 23:23:16 +08:00
2020-09-29 21:02:17 +05:30
# if CONFIG_ESP_COREDUMP_ENABLE
2025-01-27 17:48:09 +01:00
esp_panic_handler_feed_wdts ( ) ;
static bool s_dumping_core = false ;
2020-02-02 23:23:16 +08:00
if ( s_dumping_core ) {
panic_print_str ( " Re-entered core dump! Exception happened during core dump! \r \n " ) ;
} else {
s_dumping_core = true ;
2024-02-27 15:42:09 +01:00
esp_core_dump_write ( info ) ;
2020-02-02 23:23:16 +08:00
s_dumping_core = false ;
}
2020-09-29 21:02:17 +05:30
# endif /* CONFIG_ESP_COREDUMP_ENABLE */
2020-02-02 23:23:16 +08:00
2023-01-20 13:53:29 +08:00
# if CONFIG_ESP_SYSTEM_PANIC_GDBSTUB
panic_print_str ( " Entering gdb stub now. \r \n " ) ;
2025-01-27 17:48:09 +01:00
disable_all_wdts ( ) ;
2023-01-20 13:53:29 +08:00
esp_gdbstub_panic_handler ( ( void * ) info - > frame ) ;
# else
2022-11-15 03:58:16 -08:00
# if CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS
2025-01-27 17:48:09 +01:00
esp_panic_handler_feed_wdts ( ) ;
2022-11-15 03:58:16 -08:00
2022-12-02 17:30:56 +01:00
panic_print_str ( " Rebooting in " ) ;
panic_print_dec ( CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS ) ;
panic_print_str ( " seconds... \r \n " ) ;
2022-11-15 03:58:16 -08:00
2022-12-02 17:30:56 +01:00
esp_rom_delay_us ( CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS * 1000000 ) ;
# endif /* CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS */
2022-11-15 03:58:16 -08:00
2022-12-02 17:30:56 +01:00
# if CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT || CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT
2022-11-15 03:58:16 -08:00
2025-01-27 17:48:09 +01:00
esp_panic_handler_feed_wdts ( ) ;
2020-02-02 23:23:16 +08:00
if ( esp_reset_reason_get_hint ( ) = = ESP_RST_UNKNOWN ) {
2021-04-19 12:03:43 +03:00
switch ( info - > exception ) {
2020-02-02 23:23:16 +08:00
case PANIC_EXCEPTION_IWDT :
esp_reset_reason_set_hint ( ESP_RST_INT_WDT ) ;
break ;
case PANIC_EXCEPTION_TWDT :
esp_reset_reason_set_hint ( ESP_RST_TASK_WDT ) ;
break ;
case PANIC_EXCEPTION_ABORT :
case PANIC_EXCEPTION_FAULT :
default :
esp_reset_reason_set_hint ( ESP_RST_PANIC ) ;
break ; // do not touch the previously set reset reason hint
}
}
2020-06-08 19:32:35 +03:00
2020-02-02 23:23:16 +08:00
panic_print_str ( " Rebooting... \r \n " ) ;
2020-02-04 22:16:37 +08:00
panic_restart ( ) ;
2022-12-02 17:30:56 +01:00
# else /* CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT || CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT */
2020-02-02 23:23:16 +08:00
panic_print_str ( " CPU halted. \r \n " ) ;
2023-05-05 11:19:37 +08:00
esp_system_reset_modules_on_exit ( ) ;
2025-01-27 17:48:09 +01:00
disable_all_wdts ( ) ;
2024-07-04 23:57:11 +07:00
ESP_INFINITE_LOOP ( ) ;
2020-02-02 23:23:16 +08:00
# endif /* CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT || CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT */
# endif /* CONFIG_ESP_SYSTEM_PANIC_GDBSTUB */
}
2021-06-28 17:48:43 +05:30
void IRAM_ATTR __attribute__ ( ( noreturn , no_sanitize_undefined ) ) panic_abort ( const char * details )
2020-02-02 23:23:16 +08:00
{
2020-02-04 22:16:37 +08:00
g_panic_abort = true ;
2023-08-03 23:47:58 +02:00
g_panic_abort_details = ( char * ) details ;
2020-02-02 23:23:16 +08:00
# if CONFIG_APPTRACE_ENABLE
2020-12-21 20:17:42 +03:00
# if CONFIG_APPTRACE_SV_ENABLE
SEGGER_RTT_ESP_FlushNoLock ( CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH , APPTRACE_ONPANIC_HOST_FLUSH_TMO ) ;
2020-02-02 23:23:16 +08:00
# else
esp_apptrace_flush_nolock ( ESP_APPTRACE_DEST_TRAX , CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH ,
APPTRACE_ONPANIC_HOST_FLUSH_TMO ) ;
# endif
# endif
2024-06-19 17:36:14 +05:30
# ifdef __XTENSA__
asm ( " ill " ) ; // should be an invalid operation on xtensa targets
# elif __riscv
asm ( " unimp " ) ; // should be an invalid operation on RISC-V targets
# endif
2024-07-04 23:57:11 +07:00
ESP_INFINITE_LOOP ( ) ;
2020-05-04 06:20:47 +02:00
}
/* Weak versions of reset reason hint functions.
* If these weren ' t provided , reset reason code would be linked into the app
* even if the app never called esp_reset_reason ( ) .
*/
void IRAM_ATTR __attribute__ ( ( weak ) ) esp_reset_reason_set_hint ( esp_reset_reason_t hint )
{
}
esp_reset_reason_t IRAM_ATTR __attribute__ ( ( weak ) ) esp_reset_reason_get_hint ( void )
{
return ESP_RST_UNKNOWN ;
}