Merge branch 'bugfix/panic_handler_disable_wdts_early' into 'master'

esp_system: Reconfigure the WDTs at the start of the panic handler

Closes IDFCI-361

See merge request espressif/esp-idf!14138
This commit is contained in:
Angus Gratton 2021-06-29 23:48:40 +00:00
commit 1969e4b8e5
2 changed files with 25 additions and 8 deletions

View File

@ -67,8 +67,6 @@ bool g_panic_abort = false;
static char *s_panic_abort_details = NULL;
static wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
static wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
static wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1};
#if !CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT
@ -164,9 +162,16 @@ void panic_print_dec(int d)
the risk of somehow halting in the panic handler and not resetting. That is why this routine kills
all watchdogs except the timer group 0 watchdog, and it reconfigures that to reset the chip after
one second.
We have to do this before we do anything that might cause issues in the WDT interrupt handlers,
for example stalling the other core on ESP32 may cause the ESP32_ECO3_CACHE_LOCK_FIX
handler to get stuck.
*/
static void reconfigure_all_wdts(void)
void esp_panic_handler_reconfigure_wdts(void)
{
wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1};
//Todo: Refactor to use Interrupt or Task Watchdog API, and a system level WDT context
//Reconfigure TWDT (Timer Group 0)
wdt_hal_init(&wdt0_context, WDT_MWDT0, MWDT0_TICK_PRESCALER, false); //Prescaler: wdt counts in ticks of TG0_WDT_TICK_US
@ -186,6 +191,9 @@ static void reconfigure_all_wdts(void)
*/
static inline void disable_all_wdts(void)
{
wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1};
//Todo: Refactor to use Interrupt or Task Watchdog API, and a system level WDT context
//Task WDT is the Main Watchdog Timer of Timer Group 0
wdt_hal_write_protect_disable(&wdt0_context);
@ -208,6 +216,10 @@ static void print_abort_details(const void *f)
// already been done, and panic_info_t has been filled.
void esp_panic_handler(panic_info_t *info)
{
// The port-level panic handler has already called this, but call it again
// to reset the TG0WDT period
esp_panic_handler_reconfigure_wdts();
// If the exception was due to an abort, override some of the panic info
if (g_panic_abort) {
info->description = NULL;
@ -291,8 +303,7 @@ void esp_panic_handler(panic_info_t *info)
}
//Feed the watchdogs, so they will give us time to print out debug info
reconfigure_all_wdts();
esp_panic_handler_reconfigure_wdts(); // Restart WDT again
PANIC_INFO_DUMP(info, state);
panic_print_str("\r\n");
@ -313,8 +324,8 @@ void esp_panic_handler(panic_info_t *info)
esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH,
APPTRACE_ONPANIC_HOST_FLUSH_TMO);
#endif
reconfigure_all_wdts();
#endif
esp_panic_handler_reconfigure_wdts(); // restore WDT config
#endif // CONFIG_APPTRACE_ENABLE
#if CONFIG_ESP_SYSTEM_PANIC_GDBSTUB
disable_all_wdts();
@ -338,7 +349,8 @@ void esp_panic_handler(panic_info_t *info)
esp_core_dump_to_uart(info);
#endif
s_dumping_core = false;
reconfigure_all_wdts();
esp_panic_handler_reconfigure_wdts();
}
#endif /* CONFIG_ESP_COREDUMP_ENABLE */
wdt_hal_write_protect_disable(&rtc_wdt_ctx);

View File

@ -48,6 +48,8 @@
extern int _invalid_pc_placeholder;
extern void esp_panic_handler_reconfigure_wdts(void);
extern void esp_panic_handler(panic_info_t *);
static wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
@ -154,6 +156,9 @@ static void panic_handler(void *frame, bool pseudo_excause)
}
}
// Need to reconfigure WDTs before we stall any other CPU
esp_panic_handler_reconfigure_wdts();
esp_rom_delay_us(1);
SOC_HAL_STALL_OTHER_CORES();
#endif