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
This commit is contained in:
Angus Gratton 2018-09-10 16:31:20 +08:00
commit f9bed53ea2
2 changed files with 23 additions and 7 deletions

View file

@ -37,6 +37,8 @@
#include "esp_task_wdt.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'
#define ASSERT_EXIT_CRIT_RETURN(cond, ret) ({ \
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
* triggers panic if configured to do so
@ -131,7 +144,7 @@ static void task_wdt_isr(void *arg)
TIMERG0.wdt_wprotect=0;
//Acknowledge interrupt
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,
//something bad already happened and reporting this is considered more important
//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);
//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) {
if (!twdttask->has_reset) {
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");
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++) {
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
ets_printf("Aborting.\n");
ESP_EARLY_LOGE(TAG, "Aborting.");
portEXIT_CRITICAL(&twdt_spinlock);
esp_reset_reason_set_hint(ESP_RST_TASK_WDT);
abort();

View file

@ -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
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
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
can be initialized by calling :cpp:func:`esp_task_wdt_init` which will configure