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:
Alexey Gerenkov 2017-03-29 21:09:47 +03:00
parent f9fba35d1d
commit c142b9b9e5
4 changed files with 65 additions and 2 deletions

View file

@ -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));
}

View file

@ -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

View file

@ -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 ; */

View file

@ -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();