feat(esp8266): Refactor task watch dog

1. Remove old watch dog function
2. Put WIFI NVS index table from RAM to flash
This commit is contained in:
Dong Heng
2018-09-10 21:13:15 +08:00
parent 60a0297f32
commit 7e8650dd65
19 changed files with 242 additions and 110 deletions

View File

@ -71,6 +71,45 @@ config MAIN_TASK_STACK_SIZE
which calls app_main(). If app_main() returns then this task is deleted which calls app_main(). If app_main() returns then this task is deleted
and its stack memory is freed. and its stack memory is freed.
config TASK_WDT
bool "Initialize Task Watchdog Timer on startup"
default y
help
The Task Watchdog Timer can be used to make sure individual tasks are still
running. Enabling this option will cause the Task Watchdog Timer to be
initialized automatically at startup. The Task Watchdog timer can be
initialized after startup as well.
config TASK_WDT_PANIC
bool "Invoke panic handler on Task Watchdog timeout"
depends on TASK_WDT
default n
help
If this option is enabled, the Task Watchdog Timer will be configured to
trigger the panic handler when it times out. And it may cost some time.
choice TASK_WDT_TIMEOUT_S
prompt "Task Watchdog timeout period (seconds)"
depends on TASK_WDT
default TASK_WDT_TIMEOUT_13N
help
Timeout period configuration for the Task Watchdog Timer in seconds.
This is also configurable at run time.
config TASK_WDT_TIMEOUT_13N
bool "6.5536s"
config TASK_WDT_TIMEOUT_14N
bool "13.1072s"
config TASK_WDT_TIMEOUT_15N
bool "26.2144s"
endchoice
config TASK_WDT_TIMEOUT_S
int
default 13 if TASK_WDT_TIMEOUT_13N
default 14 if TASK_WDT_TIMEOUT_14N
default 15 if TASK_WDT_TIMEOUT_15N
endmenu endmenu
menu WIFI menu WIFI

View File

@ -117,10 +117,31 @@
//Interrupt remap control registers define{{ //Interrupt remap control registers define{{
#define EDGE_INT_ENABLE_REG (PERIPHS_DPORT_BASEADDR + 0x04) #define EDGE_INT_ENABLE_REG (PERIPHS_DPORT_BASEADDR + 0x04)
#define WDT_EDGE_INT_ENABLE() SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT0)
#define TM1_EDGE_INT_ENABLE() SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1) #define TM1_EDGE_INT_ENABLE() SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1)
#define TM1_EDGE_INT_DISABLE() CLEAR_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1) #define TM1_EDGE_INT_DISABLE() CLEAR_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1)
//}} //}}
//Watch dog reg {{
#define PERIPHS_WDT_BASEADDR 0x60000900
#define WDT_CTL_ADDRESS 0
#define WDT_OP_ADDRESS 0x4
#define WDT_OP_ND_ADDRESS 0x8
#define WDT_RST_ADDRESS 0x14
#define WDT_CTL_RSTLEN_MASK 0x38
#define WDT_CTL_RSPMOD_MASK 0x6
#define WDT_CTL_EN_MASK 0x1
#define WDT_CTL_RSTLEN_LSB 0x3
#define WDT_CTL_RSPMOD_LSB 0x1
#define WDT_CTL_EN_LSB 0
#define WDT_FEED_VALUE 0x73
//}}
//RTC reg {{ //RTC reg {{
#define REG_RTC_BASE PERIPHS_RTC_BASEADDR #define REG_RTC_BASE PERIPHS_RTC_BASEADDR

View File

@ -0,0 +1,37 @@
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "esp_err.h"
/**
* @brief Initialize the Task Watchdog Timer (TWDT)
*
* @return
* - ESP_OK: Initialization was successful
* - ESP_ERR_NO_MEM: Initialization failed due to lack of memory
*
* @note esp_task_wdt_init() must only be called after the scheduler
* started
*/
esp_err_t esp_task_wdt_init(void);
/**
* @brief Reset(Feed) the Task Watchdog Timer (TWDT) on behalf of the currently
* running task
*/
void esp_task_wdt_reset(void);

View File

@ -149,6 +149,8 @@ extern wifi_osi_funcs_t s_wifi_osi_funcs;
#define wifi_rand() \ #define wifi_rand() \
s_wifi_osi_funcs.rand() s_wifi_osi_funcs.rand()
void *osi_task_top_sp(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,9 +1,9 @@
gwen: gwen:
core: b9f2d3e core: 103fbb8
net80211: 48cd36b net80211: 103fbb8
pp: 82269d9 pp: 103fbb8
smartconfig:eca7811 smartconfig:103fbb8
wpa: b9f2d3e wpa: 103fbb8
espnow: 95a55d0 espnow: 103fbb8
wps: 48cd36b wps: 103fbb8
phy: 1055_8 phy: 1055_8

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -341,6 +341,13 @@ static int32_t rand_wrapper(void)
return (int32_t)esp_random(); return (int32_t)esp_random();
} }
void *osi_task_top_sp(void)
{
extern uint32_t **pxCurrentTCB;
return pxCurrentTCB[0];
}
const wifi_osi_funcs_t s_wifi_osi_funcs = { const wifi_osi_funcs_t s_wifi_osi_funcs = {
.version = ESP_WIFI_OS_ADAPTER_VERSION, .version = ESP_WIFI_OS_ADAPTER_VERSION,

View File

@ -27,6 +27,7 @@
#include "esp_phy_init.h" #include "esp_phy_init.h"
#include "esp_wifi_osi.h" #include "esp_wifi_osi.h"
#include "esp_heap_caps_init.h" #include "esp_heap_caps_init.h"
#include "esp_task_wdt.h"
#include "internal/esp_wifi_internal.h" #include "internal/esp_wifi_internal.h"
#define FLASH_MAP_ADDR 0x40200000 #define FLASH_MAP_ADDR 0x40200000
@ -58,11 +59,14 @@ static void user_init_entry(void *param)
assert(mac_init() == 0); assert(mac_init() == 0);
assert(base_gpio_init() == 0); assert(base_gpio_init() == 0);
esp_phy_load_cal_and_init(0); esp_phy_load_cal_and_init(0);
assert(watchdog_init() == 0);
assert(wifi_timer_init() == 0); assert(wifi_timer_init() == 0);
esp_wifi_set_rx_pbuf_mem_type(WIFI_RX_PBUF_DRAM); esp_wifi_set_rx_pbuf_mem_type(WIFI_RX_PBUF_DRAM);
#ifdef CONFIG_TASK_WDT
esp_task_wdt_init();
#endif
app_main(); app_main();
wifi_task_delete(NULL); wifi_task_delete(NULL);

View File

@ -0,0 +1,102 @@
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include "esp_log.h"
#include "esp_libc.h"
#include "esp_wifi_osi.h"
#include "esp_task_wdt.h"
#include "portmacro.h"
#include "esp8266/eagle_soc.h"
#define WDT_REG_READ(_reg) REG_READ(PERIPHS_WDT_BASEADDR + _reg)
#define WDT_REG_WRITE(_reg, _val) REG_WRITE(PERIPHS_WDT_BASEADDR + _reg, _val)
#define CLEAR_WDT_REG_MASK(_reg, _mask) WDT_REG_WRITE(_reg, WDT_REG_READ(_reg) & (~_mask))
#define WDT_FEED() WDT_REG_WRITE(WDT_RST_ADDRESS, WDT_FEED_VALUE)
static const char *TAG = "wdt";
#ifdef CONFIG_TASK_WDT_PANIC
/**
* @brief Task watch dog interrupt function and it should do panic
*/
static void esp_task_wdt_isr(void *param)
{
extern void panicHandler(void *frame, int wdt);
panicHandler(osi_task_top_sp(), 1);
}
#endif
/**
* @brief Just for pass compiling and mark wdt calling line
*/
esp_err_t esp_task_wdt_init(void)
{
CLEAR_WDT_REG_MASK(WDT_CTL_ADDRESS, BIT0);
#ifdef CONFIG_TASK_WDT_PANIC
const uint32_t panic_time_param = 11;
_xt_isr_attach(ETS_WDT_INUM, esp_task_wdt_isr, NULL);
_xt_isr_unmask(1 << ETS_WDT_INUM);
WDT_EDGE_INT_ENABLE();
ESP_LOGD(TAG, "Enable task watch dog panic, panic time parameter is %u", panic_time_param);
#else
const uint32_t panic_time_param = 1;
#endif
ESP_LOGD(TAG, "task watch dog trigger time parameter is %u", CONFIG_TASK_WDT_TIMEOUT_S);
WDT_REG_WRITE(WDT_OP_ADDRESS, CONFIG_TASK_WDT_TIMEOUT_S); // 2^n * 0.8ms, mask 0xf, n = 13 -> (2^13 = 8192) * 0.8 * 0.001 = 6.5536
WDT_REG_WRITE(WDT_OP_ND_ADDRESS, panic_time_param); // 2^n * 0.8ms, mask 0xf, n = 11 -> (2^11 = 2048) * 0.8 * 0.001 = 1.6384
SET_PERI_REG_BITS(PERIPHS_WDT_BASEADDR + WDT_CTL_ADDRESS, WDT_CTL_RSTLEN_MASK, 7 << WDT_CTL_RSTLEN_LSB, 0);
// interrupt then reset
SET_PERI_REG_BITS(PERIPHS_WDT_BASEADDR + WDT_CTL_ADDRESS, WDT_CTL_RSPMOD_MASK, 0 << WDT_CTL_RSPMOD_LSB, 0);
// start task watch dog1
SET_PERI_REG_BITS(PERIPHS_WDT_BASEADDR + WDT_CTL_ADDRESS, WDT_CTL_EN_MASK, 1 << WDT_CTL_EN_LSB, 0);
WDT_FEED();
return 0;
}
/**
* @brief Reset(Feed) the Task Watchdog Timer (TWDT) on behalf of the currently
* running task
*/
void esp_task_wdt_reset(void)
{
WDT_FEED();
}
/**
* @brief Just for pass compiling and mark wdt calling line
*/
void pp_soft_wdt_stop(void)
{
}
/**
* @brief Just for pass compiling and mark wdt calling line
*/
void pp_soft_wdt_restart(void)
{
}

View File

@ -131,7 +131,7 @@ static void panic_stack(StackType_t *start_stk, StackType_t *end_stk)
* *
* @return none * @return none
*/ */
void panic_info(void *frame) static void panic_info(void *frame, int wdt)
{ {
task_info_t *task; task_info_t *task;
int *regs = (int *)frame; int *regs = (int *)frame;
@ -144,14 +144,14 @@ void panic_info(void *frame)
" A14", " A15", " SAR", "EXCCAUSE" " A14", " A15", " SAR", "EXCCAUSE"
}; };
extern int _Pri_3_NMICount;
panic_str("\r\n\r\n"); panic_str("\r\n\r\n");
if (_Pri_3_NMICount == -1) { if (wdt) {
panic_str("Soft watch dog triggle:\r\n\r\n"); panic_str("Task watchdog got triggered.\r\n\r\n");
show_critical_info(); show_critical_info();
} else if (xPortInIsrContext()) }
if (xPortInIsrContext())
panic_str("Core 0 was running in ISR context:\r\n\r\n"); panic_str("Core 0 was running in ISR context:\r\n\r\n");
if ((task = (task_info_t *)xTaskGetCurrentTaskHandle())) { if ((task = (task_info_t *)xTaskGetCurrentTaskHandle())) {
@ -195,7 +195,7 @@ void panic_info(void *frame)
while (1); while (1);
} }
void IRAM_ATTR panicHandler(void *frame) void IRAM_ATTR panicHandler(void *frame, int wdt)
{ {
int cnt = 10; int cnt = 10;
@ -208,7 +208,7 @@ void IRAM_ATTR panicHandler(void *frame)
// for panic the function that disable cache // for panic the function that disable cache
Cache_Read_Enable_New(); Cache_Read_Enable_New();
panic_info(frame); panic_info(frame, wdt);
} }
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression)

View File

@ -386,3 +386,12 @@ BaseType_t xQueueGenericReceive(QueueHandle_t xQueue, void * const pvBuffer,
configASSERT(xJustPeeking == 0); configASSERT(xJustPeeking == 0);
return xQueueReceive(xQueue, pvBuffer, xTicksToWait); return xQueueReceive(xQueue, pvBuffer, xTicksToWait);
} }
void vApplicationIdleHook(void)
{
extern void pmIdleHook(void);
extern void esp_task_wdt_reset(void);
pmIdleHook();
esp_task_wdt_reset();
}

View File

@ -1418,96 +1418,6 @@ nmi_rfi:
#endif #endif
#endif /* NMI */ #endif /* NMI */
.section .text, "ax"
.global ShowCritical
.type ShowCritical, @function
.align 4
ShowCritical:
movi a2, LABEL(_Pri_,_NMICount)
l32i a2, a2, 0
bnei a2, 1, nmi_reentry_panic
/*
* a2 == 1, the function is not NMI exception function and its stack
* is stored at LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE
*
* a2 >= 1, the function is NMI exception function and its stack
* is stored at LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE + HESF_TOTALSIZE + PRI_N_STACK_SIZE2
*/
movi a2, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE
j nmi_common_panic
nmi_reentry_panic:
movi a2, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE + HESF_TOTALSIZE + PRI_N_STACK_SIZE2
nmi_common_panic:
movi a1, 0XFFFFFFFF
movi a3, LABEL(_Pri_,_NMICount)
s32i a1, a3, 0
movi a1, _chip_interrupt_tmp
addi a1, a1, -XT_STK_FRMSZ
l32i a3, a2, HESF_AR(0)
s32i a3, a1, XT_STK_A0
l32i a3, a2, HESF_AR(1)
s32i a3, a1, XT_STK_A1
l32i a3, a2, HESF_AR(2)
s32i a3, a1, XT_STK_A2
l32i a3, a2, HESF_AR(3)
s32i a3, a1, XT_STK_A3
l32i a3, a2, HESF_AR(4)
s32i a3, a1, XT_STK_A4
l32i a3, a2, HESF_AR(5)
s32i a3, a1, XT_STK_A5
l32i a3, a2, HESF_AR(6)
s32i a3, a1, XT_STK_A6
l32i a3, a2, HESF_AR(7)
s32i a3, a1, XT_STK_A7
l32i a3, a2, HESF_AR(8)
s32i a3, a1, XT_STK_A8
l32i a3, a2, HESF_AR(9)
s32i a3, a1, XT_STK_A9
l32i a3, a2, HESF_AR(10)
s32i a3, a1, XT_STK_A10
l32i a3, a2, HESF_AR(11)
s32i a3, a1, XT_STK_A11
l32i a3, a2, HESF_AR(12)
s32i a3, a1, XT_STK_A12
l32i a3, a2, HESF_AR(13)
s32i a3, a1, XT_STK_A13
l32i a3, a2, HESF_AR(14)
s32i a3, a1, XT_STK_A14
l32i a3, a2, HESF_AR(15)
s32i a3, a1, XT_STK_A15
l32i a3, a2, HESF_EXCCAUSE
s32i a3, a1, XT_STK_EXCCAUSE
l32i a3, a2, HESF_EPC3
s32i a3, a1, XT_STK_PC
l32i a3, a2, HESF_EPS3
s32i a3, a1, XT_STK_PS
mov a2, a1
call0 panicHandler
.global _xt_ext_panic .global _xt_ext_panic
.type _xt_ext_panic, @function .type _xt_ext_panic, @function
.align 4 .align 4
@ -1555,4 +1465,5 @@ _xt_ext_panic:
//Call panic handler //Call panic handler
mov a2, sp mov a2, sp
movi a3, 0
call0 panicHandler call0 panicHandler

View File

@ -20,6 +20,7 @@
#include "esp_wifi_osi.h" #include "esp_wifi_osi.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_task_wdt.h"
#include "esp8266/eagle_soc.h" #include "esp8266/eagle_soc.h"
#include "esp8266/rom_functions.h" #include "esp8266/rom_functions.h"
#include "esp8266/pin_mux_register.h" #include "esp8266/pin_mux_register.h"
@ -136,7 +137,6 @@ bool special_flash_write_status(uint8_t command, uint32_t status, int len, bool
esp_err_t spi_flash_read(size_t src_addr, void *dest, size_t size); esp_err_t spi_flash_read(size_t src_addr, void *dest, size_t size);
uint8_t en25q16x_read_sfdp(); uint8_t en25q16x_read_sfdp();
extern void pp_soft_wdt_feed(void);
extern void pp_soft_wdt_stop(void); extern void pp_soft_wdt_stop(void);
extern void pp_soft_wdt_restart(void); extern void pp_soft_wdt_restart(void);
@ -494,7 +494,7 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const void *src, size_t si
#define FLASH_WRITE(dest, src, size) \ #define FLASH_WRITE(dest, src, size) \
{ \ { \
ret = spi_flash_write_raw(dest, src, size); \ ret = spi_flash_write_raw(dest, src, size); \
pp_soft_wdt_feed(); \ esp_task_wdt_reset(); \
if (ret) { \ if (ret) { \
return ret; \ return ret; \
} \ } \
@ -607,7 +607,7 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src_addr, void *dest, size_t size)
#define FLASH_READ(addr, dest, size) \ #define FLASH_READ(addr, dest, size) \
{ \ { \
ret = spi_flash_read_raw(addr, dest, size); \ ret = spi_flash_read_raw(addr, dest, size); \
pp_soft_wdt_feed(); \ esp_task_wdt_reset(); \
if (ret) \ if (ret) \
return ret; \ return ret; \
} }
@ -1028,7 +1028,7 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(size_t start_address, size_t size)
do { do {
ret = spi_flash_erase_sector(sec++); ret = spi_flash_erase_sector(sec++);
pp_soft_wdt_feed(); esp_task_wdt_reset();
} while (ret == ESP_OK && --num); } while (ret == ESP_OK && --num);
return ret; return ret;