Explorar o código

Merge branch 'feature/task_wdt_add_timestamp' into 'master'

esp32/task_wdt: Add timestamp to message isr_twdt

See merge request idf/esp-idf!3053
Angus Gratton %!s(int64=7) %!d(string=hai) anos
pai
achega
f9bed53ea2
Modificáronse 2 ficheiros con 23 adicións e 7 borrados
  1. 20 6
      components/esp32/task_wdt.c
  2. 3 1
      docs/en/api-reference/system/wdts.rst

+ 20 - 6
components/esp32/task_wdt.c

@@ -37,6 +37,8 @@
 #include "esp_task_wdt.h"
 #include "esp_task_wdt.h"
 #include "esp_system_internal.h"
 #include "esp_system_internal.h"
 
 
+static const char *TAG = "task_wdt";
+
 //Assertion macro where, if 'cond' is false, will exit the critical section and return 'ret'
 //Assertion macro where, if 'cond' is false, will exit the critical section and return 'ret'
 #define ASSERT_EXIT_CRIT_RETURN(cond, ret)  ({                              \
 #define ASSERT_EXIT_CRIT_RETURN(cond, ret)  ({                              \
             if(!(cond)){                                                    \
             if(!(cond)){                                                    \
@@ -116,6 +118,17 @@ static void reset_hw_timer()
     }
     }
 }
 }
 
 
+/*
+ * This function is called by task_wdt_isr function (ISR for when TWDT times out).
+ * It can be redefined in user code to handle twdt events.
+ * Note: It has the same limitations as the interrupt function.
+ *       Do not use ESP_LOGI functions inside.
+ */
+void __attribute__((weak)) esp_task_wdt_isr_user_handler(void)
+{
+
+}
+
 /*
 /*
  * ISR for when TWDT times out. Checks for which tasks have not reset. Also
  * ISR for when TWDT times out. Checks for which tasks have not reset. Also
  * triggers panic if configured to do so
  * triggers panic if configured to do so
@@ -131,7 +144,7 @@ static void task_wdt_isr(void *arg)
     TIMERG0.wdt_wprotect=0;
     TIMERG0.wdt_wprotect=0;
     //Acknowledge interrupt
     //Acknowledge interrupt
     TIMERG0.int_clr_timers.wdt=1;
     TIMERG0.int_clr_timers.wdt=1;
-    //We are taking a spinlock while doing I/O (ets_printf) here. Normally, that is a pretty
+    //We are taking a spinlock while doing I/O (ESP_EARLY_LOGE) here. Normally, that is a pretty
     //bad thing, possibly (temporarily) hanging up the 2nd core and stopping FreeRTOS. In this case,
     //bad thing, possibly (temporarily) hanging up the 2nd core and stopping FreeRTOS. In this case,
     //something bad already happened and reporting this is considered more important
     //something bad already happened and reporting this is considered more important
     //than the badness caused by a spinlock here.
     //than the badness caused by a spinlock here.
@@ -140,21 +153,22 @@ static void task_wdt_isr(void *arg)
     ASSERT_EXIT_CRIT_RETURN((twdt_config->list != NULL), VOID_RETURN);
     ASSERT_EXIT_CRIT_RETURN((twdt_config->list != NULL), VOID_RETURN);
 
 
     //Watchdog got triggered because at least one task did not reset in time.
     //Watchdog got triggered because at least one task did not reset in time.
-    ets_printf("Task watchdog got triggered. The following tasks did not reset the watchdog in time:\n");
+    ESP_EARLY_LOGE(TAG, "Task watchdog got triggered. The following tasks did not reset the watchdog in time:");
     for (twdttask=twdt_config->list; twdttask!=NULL; twdttask=twdttask->next) {
     for (twdttask=twdt_config->list; twdttask!=NULL; twdttask=twdttask->next) {
         if (!twdttask->has_reset) {
         if (!twdttask->has_reset) {
             cpu=xTaskGetAffinity(twdttask->task_handle)==0?DRAM_STR("CPU 0"):DRAM_STR("CPU 1");
             cpu=xTaskGetAffinity(twdttask->task_handle)==0?DRAM_STR("CPU 0"):DRAM_STR("CPU 1");
             if (xTaskGetAffinity(twdttask->task_handle)==tskNO_AFFINITY) cpu=DRAM_STR("CPU 0/1");
             if (xTaskGetAffinity(twdttask->task_handle)==tskNO_AFFINITY) cpu=DRAM_STR("CPU 0/1");
-            ets_printf(" - %s (%s)\n", pcTaskGetTaskName(twdttask->task_handle), cpu);
+            ESP_EARLY_LOGE(TAG, " - %s (%s)", pcTaskGetTaskName(twdttask->task_handle), cpu);
         }
         }
     }
     }
-    ets_printf(DRAM_STR("Tasks currently running:\n"));
+    ESP_EARLY_LOGE(TAG, "%s", DRAM_STR("Tasks currently running:"));
     for (int x=0; x<portNUM_PROCESSORS; x++) {
     for (int x=0; x<portNUM_PROCESSORS; x++) {
-        ets_printf("CPU %d: %s\n", x, pcTaskGetTaskName(xTaskGetCurrentTaskHandleForCPU(x)));
+        ESP_EARLY_LOGE(TAG, "CPU %d: %s", x, pcTaskGetTaskName(xTaskGetCurrentTaskHandleForCPU(x)));
     }
     }
 
 
+    esp_task_wdt_isr_user_handler();
     if (twdt_config->panic){     //Trigger Panic if configured to do so
     if (twdt_config->panic){     //Trigger Panic if configured to do so
-        ets_printf("Aborting.\n");
+        ESP_EARLY_LOGE(TAG, "Aborting.");
         portEXIT_CRITICAL(&twdt_spinlock);
         portEXIT_CRITICAL(&twdt_spinlock);
         esp_reset_reason_set_hint(ESP_RST_TASK_WDT);
         esp_reset_reason_set_hint(ESP_RST_TASK_WDT);
         abort();
         abort();

+ 3 - 1
docs/en/api-reference/system/wdts.rst

@@ -44,7 +44,9 @@ elect to be watched by the TWDT. Each watched task must 'reset' the TWDT
 periodically to indicate that they have been allocated CPU time. If a task does 
 periodically to indicate that they have been allocated CPU time. If a task does 
 not reset within the TWDT timeout period, a warning will be printed with 
 not reset within the TWDT timeout period, a warning will be printed with 
 information about which tasks failed to reset the TWDT in time and which 
 information about which tasks failed to reset the TWDT in time and which 
-tasks are currently running on the ESP32 CPUs and.
+tasks are currently running on the ESP32 CPUs. 
+And also there is a possibility to redefine the function `esp_task_wdt_isr_user_handler` 
+in the user code to receive this event.
 
 
 The TWDT is built around the Hardware Watchdog Timer in Timer Group 0. The TWDT
 The TWDT is built around the Hardware Watchdog Timer in Timer Group 0. The TWDT
 can be initialized by calling :cpp:func:`esp_task_wdt_init` which will configure
 can be initialized by calling :cpp:func:`esp_task_wdt_init` which will configure