From b097dd0a79cab56871fdd3a26d17ab15ace9c065 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Fri, 27 Mar 2020 17:58:12 +0800 Subject: [PATCH] Add Task Watchdog backtrace printing This commit makes the Task Watchdog print the backtrace of both cores when it times out. --- components/esp32/crosscore_int.c | 9 +++++++++ components/esp32s2/crosscore_int.c | 9 +++++++++ .../include/esp_private/crosscore_int.h | 10 ++++++++++ components/esp_common/src/task_wdt.c | 15 ++++++++++++++- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/components/esp32/crosscore_int.c b/components/esp32/crosscore_int.c index 35ca8d3ae..36a1f6c3a 100644 --- a/components/esp32/crosscore_int.c +++ b/components/esp32/crosscore_int.c @@ -17,6 +17,7 @@ #include "esp_attr.h" #include "esp_err.h" #include "esp_intr_alloc.h" +#include "esp_debug_helpers.h" #include "esp32/rom/ets_sys.h" #include "esp32/rom/uart.h" @@ -34,6 +35,7 @@ #define REASON_YIELD BIT(0) #define REASON_FREQ_SWITCH BIT(1) +#define REASON_PRINT_BACKTRACE BIT(2) static portMUX_TYPE reason_spinlock = portMUX_INITIALIZER_UNLOCKED; static volatile uint32_t reason[ portNUM_PROCESSORS ]; @@ -74,6 +76,9 @@ static void IRAM_ATTR esp_crosscore_isr(void *arg) { * to allow DFS features without the extra latency of the ISR hook. */ } + if (my_reason_val & REASON_PRINT_BACKTRACE) { + esp_backtrace_print(100); + } } //Initialize the crosscore interrupt on this core. Call this once @@ -115,3 +120,7 @@ void IRAM_ATTR esp_crosscore_int_send_freq_switch(int core_id) esp_crosscore_int_send(core_id, REASON_FREQ_SWITCH); } +void IRAM_ATTR esp_crosscore_int_send_print_backtrace(int core_id) +{ + esp_crosscore_int_send(core_id, REASON_PRINT_BACKTRACE); +} diff --git a/components/esp32s2/crosscore_int.c b/components/esp32s2/crosscore_int.c index 65da6cd31..6ffada945 100644 --- a/components/esp32s2/crosscore_int.c +++ b/components/esp32s2/crosscore_int.c @@ -17,6 +17,7 @@ #include "esp_attr.h" #include "esp_err.h" #include "esp_intr_alloc.h" +#include "esp_debug_helpers.h" #include "esp32s2/rom/ets_sys.h" #include "esp32s2/rom/uart.h" @@ -35,6 +36,7 @@ #define REASON_YIELD BIT(0) #define REASON_FREQ_SWITCH BIT(1) +#define REASON_PRINT_BACKTRACE BIT(2) static portMUX_TYPE reason_spinlock = portMUX_INITIALIZER_UNLOCKED; static volatile uint32_t reason; @@ -71,6 +73,9 @@ static void IRAM_ATTR esp_crosscore_isr(void *arg) { * to allow DFS features without the extra latency of the ISR hook. */ } + if (my_reason_val & REASON_PRINT_BACKTRACE) { + esp_backtrace_print(100); + } } //Initialize the crosscore interrupt on this core. @@ -101,3 +106,7 @@ void IRAM_ATTR esp_crosscore_int_send_freq_switch(int core_id) esp_crosscore_int_send(core_id, REASON_FREQ_SWITCH); } +void IRAM_ATTR esp_crosscore_int_send_print_backtrace(int core_id) +{ + esp_crosscore_int_send(core_id, REASON_PRINT_BACKTRACE); +} \ No newline at end of file diff --git a/components/esp_common/include/esp_private/crosscore_int.h b/components/esp_common/include/esp_private/crosscore_int.h index d0e3cadc1..d7af7f69b 100644 --- a/components/esp_common/include/esp_private/crosscore_int.h +++ b/components/esp_common/include/esp_private/crosscore_int.h @@ -51,4 +51,14 @@ void esp_crosscore_int_send_yield(int core_id); */ void esp_crosscore_int_send_freq_switch(int core_id); +/** + * Send an interrupt to a CPU indicating it should print its current backtrace + * + * This is use internally by the Task Watchdog to dump the backtrace of the + * opposite core and should not be called from application code. + * + * @param core_id Core that should print its backtrace + */ +void esp_crosscore_int_send_print_backtrace(int core_id); + #endif diff --git a/components/esp_common/src/task_wdt.c b/components/esp_common/src/task_wdt.c index 7b4b9a817..77d97365a 100644 --- a/components/esp_common/src/task_wdt.c +++ b/components/esp_common/src/task_wdt.c @@ -26,6 +26,7 @@ #include "esp_err.h" #include "esp_intr_alloc.h" #include "esp_attr.h" +#include "esp_debug_helpers.h" #include "esp_freertos_hooks.h" #include "soc/timer_periph.h" #include "esp_log.h" @@ -33,6 +34,7 @@ #include "driver/periph_ctrl.h" #include "esp_task_wdt.h" #include "esp_private/system_internal.h" +#include "esp_private/crosscore_int.h" #include "hal/timer_types.h" #include "hal/wdt_hal.h" @@ -172,13 +174,24 @@ static void task_wdt_isr(void *arg) } esp_task_wdt_isr_user_handler(); + if (twdt_config->panic){ //Trigger Panic if configured to do so ESP_EARLY_LOGE(TAG, "Aborting."); portEXIT_CRITICAL_ISR(&twdt_spinlock); esp_reset_reason_set_hint(ESP_RST_TASK_WDT); abort(); + } else { + int current_core = xPortGetCoreID(); + //Print backtrace of current core + ESP_EARLY_LOGE(TAG, "Print CPU %d (current core) backtrace", current_core); + esp_backtrace_print(100); + #if !CONFIG_FREERTOS_UNICORE + //Print backtrace of other core + ESP_EARLY_LOGE(TAG, "Print CPU %d backtrace", !current_core); + esp_crosscore_int_send_print_backtrace(!current_core); + #endif } - + portEXIT_CRITICAL_ISR(&twdt_spinlock); }