Ver Fonte

Merge branch 'feature/twdt_prints_backtrace_v4.1' into 'release/v4.1'

Add Task Watchdog backtrace printing (v4.1)

See merge request espressif/esp-idf!12617
Zim Kalinowski há 4 anos atrás
pai
commit
05ed8331bc

+ 9 - 0
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"
@@ -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[ portNUM_PROCESSORS ];
@@ -75,6 +77,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
@@ -116,3 +121,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);
+}

+ 15 - 1
components/esp32/task_wdt.c

@@ -27,6 +27,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"
@@ -34,7 +35,9 @@
 #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_ll.h"
+#include "hal/timer_types.h"
 
 
 static const char *TAG = "task_wdt";
@@ -167,13 +170,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);
 }
 

+ 9 - 0
components/esp32s2beta/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 "esp32s2beta/rom/ets_sys.h"
 #include "esp32s2beta/rom/uart.h"
@@ -36,6 +37,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;
@@ -72,6 +74,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.
@@ -102,3 +107,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);
+}

+ 10 - 0
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