feat(esp8266): add non-mask watch dog to panic critical function

This commit is contained in:
Dong Heng
2020-03-05 17:15:04 +08:00
parent 02c5155def
commit f7b83db266
6 changed files with 106 additions and 23 deletions

View File

@ -1,5 +1,15 @@
menu "ESP8266-specific"
config ESP8266_NMI_WDT
bool "Enable non-mask watch dog"
default y
help
Important: this non-mask watch dog is registered to non-mask timer0,
so it can not work together with PWM.
Enable this non-mask watch dog can help users to debug blocking code
when CPU is at critical state(disable interrupt).
choice ESP8266_DEFAULT_CPU_FREQ_MHZ
prompt "CPU frequency"
default ESP8266_DEFAULT_CPU_FREQ_160

View File

@ -29,15 +29,6 @@
static const char *TAG = "ir tx";
#define WDEVTSF0_TIME_LO 0x3ff21004
#define WDEVTSF0_TIME_HI 0x3ff21008
#define WDEVTSFSW0_LO 0x3ff21018
#define WDEVTSFSW0_HI 0x3ff2101C
#define WDEVTSF0_TIMER_LO 0x3ff2109c
#define WDEVTSF0_TIMER_HI 0x3ff210a0
#define WDEVTSF0TIMER_ENA 0x3ff21098
#define WDEV_TSF0TIMER_ENA BIT(31)
int wDev_MacTimSetFunc(void (*handle)(void));
#define IR_TX_CHECK(a, str, ret_val) \

View File

@ -55,15 +55,6 @@ static const char *TAG = "pwm";
#define AHEAD_TICKS3 2
#define MAX_TICKS 10000000ul
#define WDEVTSF0_TIME_LO 0x3ff21004
#define WDEVTSF0_TIME_HI 0x3ff21008
#define WDEVTSFSW0_LO 0x3ff21018
#define WDEVTSFSW0_HI 0x3ff2101C
#define WDEVTSF0_TIMER_LO 0x3ff2109c
#define WDEVTSF0_TIMER_HI 0x3ff210a0
#define WDEVTSF0TIMER_ENA 0x3ff21098
#define WDEV_TSF0TIMER_ENA BIT(31)
#define PWM_VERSION "PWM v3.2"
typedef struct {

View File

@ -146,6 +146,15 @@
#define WDEV_COUNT_REG (0x3ff20c00)
#define WDEVTSF0_TIME_LO 0x3ff21004
#define WDEVTSF0_TIME_HI 0x3ff21008
#define WDEVTSFSW0_LO 0x3ff21018
#define WDEVTSFSW0_HI 0x3ff2101C
#define WDEVTSF0_TIMER_LO 0x3ff2109c
#define WDEVTSF0_TIMER_HI 0x3ff210a0
#define WDEVTSF0TIMER_ENA 0x3ff21098
#define WDEV_TSF0TIMER_ENA BIT(31)
//Watch dog reg {{
#define PERIPHS_WDT_BASEADDR 0x60000900

View File

@ -17,7 +17,9 @@
#include "esp_log.h"
#include "esp_libc.h"
#include "esp_task_wdt.h"
#include "esp_attr.h"
#include "portmacro.h"
#include "esp8266/rom_functions.h"
#include "esp8266/eagle_soc.h"
#include "driver/soc.h"
@ -36,6 +38,73 @@ static void esp_task_wdt_isr(void *param)
}
#endif
#ifdef CONFIG_ESP8266_NMI_WDT
#if CONFIG_ESP_TASK_WDT_TIMEOUT_S == 13
#define NMI_WD_TOTAL_PERIOD (6553600)
#elif CONFIG_ESP_TASK_WDT_TIMEOUT_S == 14
#define NMI_WD_TOTAL_PERIOD (13107200)
#elif CONFIG_ESP_TASK_WDT_TIMEOUT_S == 15
#define NMI_WD_TOTAL_PERIOD (26214400)
#endif
#define NMI_WD_CHECK_PERIOD (1 * 1000 * 1000)
static int s_nmi_wd_state;
static void nmi_panic_wd(void)
{
extern uint32_t _chip_nmi_cnt;
extern uint8_t _chip_nmi_stk[];
extern void panicHandler(void *frame, int wdt);
uint32_t *p;
if (_chip_nmi_cnt == 1) {
p = (uint32_t *)&_chip_nmi_stk[512];
} else {
p = (uint32_t *)&_chip_nmi_stk[512 + 124 + 256];
}
panicHandler(p - 1, 1);
}
static void IRAM_ATTR nmi_set_wd_time(uint32_t us)
{
REG_WRITE(WDEVTSF0TIMER_ENA, REG_READ(WDEVTSF0TIMER_ENA) & (~WDEV_TSF0TIMER_ENA));
REG_WRITE(WDEVTSFSW0_LO, 0);
REG_WRITE(WDEVTSFSW0_HI, 0);
REG_WRITE(WDEVTSFSW0_LO, 0);
REG_WRITE(WDEVTSF0_TIMER_LO, 0);
REG_WRITE(WDEVTSF0_TIMER_HI, 0);
REG_WRITE(WDEVTSF0_TIMER_LO, us);
REG_WRITE(WDEVTSF0TIMER_ENA, WDEV_TSF0TIMER_ENA);
}
static void IRAM_ATTR nmi_check_wd(void)
{
switch (s_nmi_wd_state) {
case 0:
s_nmi_wd_state = 1;
nmi_set_wd_time(NMI_WD_CHECK_PERIOD);
break;
case 1:
s_nmi_wd_state = 2;
nmi_set_wd_time(NMI_WD_TOTAL_PERIOD - NMI_WD_CHECK_PERIOD);
break;
case 2:
Cache_Read_Enable_New();
nmi_panic_wd();
break;
default:
break;
}
}
#endif
/**
* @brief Just for pass compiling and mark wdt calling line
*/
@ -72,6 +141,15 @@ esp_err_t esp_task_wdt_init(void)
WDT_FEED();
#ifdef CONFIG_ESP8266_NMI_WDT
{
extern void wDev_MacTimSetFunc(void *func);
wDev_MacTimSetFunc(nmi_check_wd);;
nmi_set_wd_time(NMI_WD_CHECK_PERIOD);
}
#endif
return 0;
}
@ -82,6 +160,10 @@ esp_err_t esp_task_wdt_init(void)
void esp_task_wdt_reset(void)
{
WDT_FEED();
#ifdef CONFIG_ESP8266_NMI_WDT
s_nmi_wd_state = 0;
#endif
}
/**

View File

@ -80,14 +80,14 @@ Add to compile passing.
#define _INTERRUPT_LEVEL 3
STRUCT_BEGIN
STRUCT_FIELD (long,4,HESF_,SAR)
STRUCT_FIELD (long,4,HESF_,EPC1)
STRUCT_FIELD (long,4,HESF_,EXCCAUSE)
STRUCT_FIELD (long,4,HESF_,EXCVADDR)
STRUCT_FIELD (long,4,HESF_,EXCSAVE1)
STRUCT_FIELD (long,4,HESF_,EPC3)
STRUCT_FIELD (long,4,HESF_,EPS3)
STRUCT_AFIELD(long,4,HESF_,AREG, 16) /* address registers ar0..ar15 */
STRUCT_FIELD (long,4,HESF_,SAR)
STRUCT_FIELD (long,4,HESF_,EXCCAUSE)
STRUCT_FIELD (long,4,HESF_,EPC1)
STRUCT_FIELD (long,4,HESF_,EXCVADDR)
STRUCT_FIELD (long,4,HESF_,EXCSAVE1)
#define HESF_AR(n) HESF_AREG+((n)*4)
STRUCT_END(HighPriFrame)
#define HESF_TOTALSIZE HighPriFrameSize+32 /* 32 bytes for interrupted code's save areas under SP */