mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-21 09:05:59 +08:00
feat(freertos): Add option for panic
This commit is contained in:
@ -149,6 +149,37 @@ config DISABLE_ROM_UART_PRINT
|
|||||||
help
|
help
|
||||||
"Disable main part of ROM UART print when rom bootloader process."
|
"Disable main part of ROM UART print when rom bootloader process."
|
||||||
|
|
||||||
|
config PANIC_FULL_STACK
|
||||||
|
bool "Output full stack data of task"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Output full stack data of task although some stack space is not used.
|
||||||
|
|
||||||
|
choice ESP_PANIC
|
||||||
|
prompt "Panic handler behaviour"
|
||||||
|
default ESP_PANIC_PRINT_REBOOT
|
||||||
|
help
|
||||||
|
If an unhandled exception, the panic handler is invoked.
|
||||||
|
Configure the panic handlers action here.
|
||||||
|
|
||||||
|
config ESP_PANIC_PRINT_HALT
|
||||||
|
bool "Print registers and halt"
|
||||||
|
help
|
||||||
|
Outputs the relevant registers over the serial port and halt the
|
||||||
|
processor. Needs a manual reset to restart.
|
||||||
|
|
||||||
|
config ESP_PANIC_PRINT_REBOOT
|
||||||
|
bool "Print registers and reboot"
|
||||||
|
help
|
||||||
|
Outputs the relevant registers over the serial port and immediately
|
||||||
|
reset the processor.
|
||||||
|
|
||||||
|
config ESP_PANIC_SILENT_REBOOT
|
||||||
|
bool "Silent reboot"
|
||||||
|
help
|
||||||
|
Just resets the processor without outputting anything
|
||||||
|
endchoice
|
||||||
|
|
||||||
config MAIN_TASK_STACK_SIZE
|
config MAIN_TASK_STACK_SIZE
|
||||||
int "Main task stack size"
|
int "Main task stack size"
|
||||||
default 3584
|
default 3584
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
#include "esp_libc.h"
|
#include "esp_libc.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
|
||||||
#include "esp8266/eagle_soc.h"
|
#include "esp8266/eagle_soc.h"
|
||||||
#include "esp8266/rom_functions.h"
|
#include "esp8266/rom_functions.h"
|
||||||
@ -29,6 +30,7 @@
|
|||||||
|
|
||||||
#define STACK_VOL_NUM 16
|
#define STACK_VOL_NUM 16
|
||||||
|
|
||||||
|
#ifndef CONFIG_ESP_PANIC_SILENT_REBOOT
|
||||||
#ifndef DISABLE_FREERTOS
|
#ifndef DISABLE_FREERTOS
|
||||||
/*
|
/*
|
||||||
* @Note: If freeRTOS is updated, the structure must be checked.
|
* @Note: If freeRTOS is updated, the structure must be checked.
|
||||||
@ -80,9 +82,10 @@ static void panic_stack(const uint32_t *reg, const uint32_t *start_stk, const ui
|
|||||||
|
|
||||||
if (stk_ptr <= start_stk || stk_ptr >= end_stk) {
|
if (stk_ptr <= start_stk || stk_ptr >= end_stk) {
|
||||||
ets_printf("register map is %x error\n", stk_ptr);
|
ets_printf("register map is %x error\n", stk_ptr);
|
||||||
while (1);
|
|
||||||
} else {
|
} else {
|
||||||
|
#ifndef CONFIG_PANIC_FULL_STACK
|
||||||
start_stk = (const uint32_t *)((uint32_t)stk_ptr & (~(STACK_VOL_NUM * sizeof(const uint32_t *) - 1)));
|
start_stk = (const uint32_t *)((uint32_t)stk_ptr & (~(STACK_VOL_NUM * sizeof(const uint32_t *) - 1)));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size = end_stk - start_stk + 1;
|
size_t size = end_stk - start_stk + 1;
|
||||||
@ -123,6 +126,7 @@ static void panic_stack(const uint32_t *reg, const uint32_t *start_stk, const ui
|
|||||||
static __attribute__((noreturn)) void panic_info(void *frame, int wdt)
|
static __attribute__((noreturn)) void panic_info(void *frame, int wdt)
|
||||||
{
|
{
|
||||||
extern int _chip_nmi_cnt;
|
extern int _chip_nmi_cnt;
|
||||||
|
extern int __g_is_task_overflow;
|
||||||
|
|
||||||
task_info_t *task;
|
task_info_t *task;
|
||||||
uint32_t *regs = (uint32_t *)frame;
|
uint32_t *regs = (uint32_t *)frame;
|
||||||
@ -149,7 +153,7 @@ static __attribute__((noreturn)) void panic_info(void *frame, int wdt)
|
|||||||
|
|
||||||
panic_stack(regs, &_chip_nmi_stk, &LoadStoreErrorHandlerStack);
|
panic_stack(regs, &_chip_nmi_stk, &LoadStoreErrorHandlerStack);
|
||||||
} else {
|
} else {
|
||||||
if (xPortInIsrContext() && !wdt) {
|
if (xPortInIsrContext() && !wdt && !__g_is_task_overflow) {
|
||||||
extern const uint32_t _chip_interrupt_stk, _chip_interrupt_tmp;
|
extern const uint32_t _chip_interrupt_stk, _chip_interrupt_tmp;
|
||||||
|
|
||||||
ets_printf("Core 0 was running in ISR context:\r\n\r\n");
|
ets_printf("Core 0 was running in ISR context:\r\n\r\n");
|
||||||
@ -179,17 +183,17 @@ static __attribute__((noreturn)) void panic_info(void *frame, int wdt)
|
|||||||
ets_printf("\r\n");
|
ets_printf("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#ifdef CONFIG_ESP_PANIC_PRINT_HALT
|
||||||
* Todo: add more option to select here to 'Kconfig':
|
|
||||||
* 1. blocking
|
|
||||||
* 2. restart
|
|
||||||
* 3. GBD break
|
|
||||||
*/
|
|
||||||
while (1);
|
while (1);
|
||||||
|
#else
|
||||||
|
esp_restart();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif /* !CONFIG_ESP_PANIC_SILENT_REBOOT */
|
||||||
|
|
||||||
void __attribute__((noreturn)) panicHandler(void *frame, int wdt)
|
void __attribute__((noreturn)) panicHandler(void *frame, int wdt)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_ESP_PANIC_SILENT_REBOOT
|
||||||
/* NMI can interrupt exception. */
|
/* NMI can interrupt exception. */
|
||||||
vPortEnterCritical();
|
vPortEnterCritical();
|
||||||
do {
|
do {
|
||||||
@ -197,6 +201,9 @@ void __attribute__((noreturn)) panicHandler(void *frame, int wdt)
|
|||||||
} while (REG_READ(INT_ENA_WDEV) != 0);
|
} while (REG_READ(INT_ENA_WDEV) != 0);
|
||||||
|
|
||||||
panic_info(frame, wdt);
|
panic_info(frame, wdt);
|
||||||
|
#else
|
||||||
|
esp_restart();
|
||||||
|
#endif /* !CONFIG_ESP_PANIC_SILENT_REBOOT */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void esp_error_check_failed_print(const char *msg, esp_err_t rc, const char *file, int line, const char *function, const char *expression)
|
static void esp_error_check_failed_print(const char *msg, esp_err_t rc, const char *file, int line, const char *function, const char *expression)
|
||||||
|
@ -57,6 +57,8 @@ uint32_t cpu_sr;
|
|||||||
|
|
||||||
uint32_t _xt_tick_divisor;
|
uint32_t _xt_tick_divisor;
|
||||||
|
|
||||||
|
int __g_is_task_overflow;
|
||||||
|
|
||||||
/* Each task maintains its own interrupt status in the critical nesting
|
/* Each task maintains its own interrupt status in the critical nesting
|
||||||
variable. */
|
variable. */
|
||||||
static uint32_t uxCriticalNesting = 0;
|
static uint32_t uxCriticalNesting = 0;
|
||||||
@ -309,7 +311,7 @@ int xPortInIsrContext(void)
|
|||||||
void __attribute__((weak, noreturn)) vApplicationStackOverflowHook(xTaskHandle xTask, const char *pcTaskName)
|
void __attribute__((weak, noreturn)) vApplicationStackOverflowHook(xTaskHandle xTask, const char *pcTaskName)
|
||||||
{
|
{
|
||||||
ets_printf("***ERROR*** A stack overflow in task %s has been detected.\r\n", pcTaskName);
|
ets_printf("***ERROR*** A stack overflow in task %s has been detected.\r\n", pcTaskName);
|
||||||
|
__g_is_task_overflow = 1;
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user