mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
esp32: RWDT is used to reboot system in case of panic handler crash
also fixes TG1WDG protection bug in panic handler
This commit is contained in:
parent
f9fba35d1d
commit
c142b9b9e5
@ -55,6 +55,7 @@
|
||||
#include "esp_task_wdt.h"
|
||||
#include "esp_phy_init.h"
|
||||
#include "esp_coexist.h"
|
||||
#include "esp_panic.h"
|
||||
#include "esp_core_dump.h"
|
||||
#include "trax.h"
|
||||
|
||||
@ -92,6 +93,11 @@ static const char* TAG = "cpu_start";
|
||||
|
||||
void IRAM_ATTR call_start_cpu0()
|
||||
{
|
||||
#if CONFIG_FREERTOS_UNICORE
|
||||
RESET_REASON rst_reas[1];
|
||||
#else
|
||||
RESET_REASON rst_reas[2];
|
||||
#endif
|
||||
cpu_configure_region_protection();
|
||||
|
||||
//Move exception vectors to IRAM
|
||||
@ -99,10 +105,25 @@ void IRAM_ATTR call_start_cpu0()
|
||||
"wsr %0, vecbase\n" \
|
||||
::"r"(&_init_start));
|
||||
|
||||
rst_reas[0] = rtc_get_reset_reason(0);
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
rst_reas[1] = rtc_get_reset_reason(1);
|
||||
#endif
|
||||
// from panic handler we can be reset by RWDT or TG0WDT
|
||||
if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
|| rst_reas[1] == RTCWDT_SYS_RESET || rst_reas[1] == TG0WDT_SYS_RESET
|
||||
#endif
|
||||
) {
|
||||
// stop wdt in case of any
|
||||
ESP_EARLY_LOGI(TAG, "Stop panic WDT");
|
||||
esp_panic_wdt_stop();
|
||||
}
|
||||
|
||||
memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
|
||||
|
||||
/* Unless waking from deep sleep (implying RTC memory is intact), clear RTC bss */
|
||||
if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET) {
|
||||
if (rst_reas[0] != DEEPSLEEP_RESET) {
|
||||
memset(&_rtc_bss_start, 0, (&_rtc_bss_end - &_rtc_bss_start) * sizeof(_rtc_bss_start));
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,11 @@ esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags);
|
||||
void esp_clear_watchpoint(int no);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Stops panic WDT
|
||||
*/
|
||||
void esp_panic_wdt_stop(void);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1650,6 +1650,12 @@
|
||||
#define RTC_CNTL_WDT_PAUSE_IN_SLP_M (BIT(7))
|
||||
#define RTC_CNTL_WDT_PAUSE_IN_SLP_V 0x1
|
||||
#define RTC_CNTL_WDT_PAUSE_IN_SLP_S 7
|
||||
/* RTC_CNTL_WDT_STGX : */
|
||||
/*description: stage action selection values */
|
||||
#define RTC_WDT_STG_SEL_OFF 0
|
||||
#define RTC_WDT_STG_SEL_INT 1
|
||||
#define RTC_WDT_STG_SEL_RESET_CPU 2
|
||||
#define RTC_WDT_STG_SEL_RESET_SYSTEM 3
|
||||
|
||||
#define RTC_CNTL_WDTCONFIG1_REG (DR_REG_RTCCNTL_BASE + 0x90)
|
||||
/* RTC_CNTL_WDT_STG0_HOLD : R/W ;bitpos:[31:0] ;default: 32'd128000 ; */
|
||||
|
@ -284,11 +284,37 @@ static void disableAllWdts()
|
||||
TIMERG0.wdt_wprotect = 0;
|
||||
TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
|
||||
TIMERG1.wdt_config0.en = 0;
|
||||
TIMERG0.wdt_wprotect = 0;
|
||||
TIMERG1.wdt_wprotect = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void esp_panic_wdt_start()
|
||||
{
|
||||
if (REG_GET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN)) {
|
||||
return;
|
||||
}
|
||||
WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
|
||||
WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1);
|
||||
REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, 7);
|
||||
REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_CPU_RESET_LENGTH, 7);
|
||||
REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_RESET_SYSTEM);
|
||||
// 64KB of core dump data (stacks of about 30 tasks) will produce ~85KB base64 data.
|
||||
// @ 115200 UART speed it will take more than 6 sec to print them out.
|
||||
WRITE_PERI_REG(RTC_CNTL_WDTCONFIG1_REG, RTC_CNTL_SLOWCLK_FREQ*7);
|
||||
REG_SET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN);
|
||||
WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
|
||||
}
|
||||
|
||||
void esp_panic_wdt_stop()
|
||||
{
|
||||
WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
|
||||
WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1);
|
||||
REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_OFF);
|
||||
REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN);
|
||||
WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
|
||||
}
|
||||
|
||||
static inline bool stackPointerIsSane(uint32_t sp)
|
||||
{
|
||||
return !(sp < 0x3ffae010 || sp > 0x3ffffff0 || ((sp & 0xf) != 0));
|
||||
@ -343,6 +369,9 @@ static void commonErrorHandler(XtExcFrame *frame)
|
||||
"A14 ", "A15 ", "SAR ", "EXCCAUSE", "EXCVADDR", "LBEG ", "LEND ", "LCOUNT "
|
||||
};
|
||||
|
||||
// start panic WDT to restart system if we hang in this handler
|
||||
esp_panic_wdt_start();
|
||||
|
||||
//Feed the watchdogs, so they will give us time to print out debug info
|
||||
reconfigureAllWdts();
|
||||
|
||||
@ -370,6 +399,7 @@ static void commonErrorHandler(XtExcFrame *frame)
|
||||
|
||||
#if CONFIG_ESP32_PANIC_GDBSTUB
|
||||
disableAllWdts();
|
||||
esp_panic_wdt_stop();
|
||||
panicPutStr("Entering gdb stub now.\r\n");
|
||||
esp_gdbstub_panic_handler(frame);
|
||||
#else
|
||||
@ -383,6 +413,7 @@ static void commonErrorHandler(XtExcFrame *frame)
|
||||
#endif
|
||||
reconfigureAllWdts();
|
||||
#endif
|
||||
esp_panic_wdt_stop();
|
||||
#if CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT
|
||||
panicPutStr("Rebooting...\r\n");
|
||||
esp_restart_noos();
|
||||
|
Loading…
x
Reference in New Issue
Block a user