Merge branch 'feature/panic_wdt' into 'master'

esp32: RWDT is used to reboot system in case of panic handler crash

This branch uses RWDT to reboot system in case of panic handler crash.

See merge request !625
This commit is contained in:
Ivan Grokhotkov 2017-04-07 12:14:30 +08:00
commit fd0539b4ba
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();