esp-idf/examples/system/task_watchdog/main/task_watchdog_example_main.c
Darian Leung 616baa239d esp32: New Task Watchdog API
Legacy API of task watchdog used the same function esp_task_wdt_feed() to add
and feed a task. This caused issues of implicitly adding a task to the wdt list
if the function was used in shared code.

The new API introduces init, adding, feeding, deleting, deinit functions. Tasks
must now be explicitly added to the task watchdog using their handles. Deletion
must also be explicit using task handles. This resolves the issue of implicit
task additions to the task watchdog due to shared code calling
esp_task_wdt_feed().

Task watchdog is now fully configurable at runtime by calling the init and
deinit functions.

Also added functions to get the handles of idle tasks of the other core. This
helps when adding idle tasks to the watchdog at run time.

Configuring the task watchdog using menu config is still available, however
menu config will only result in calling the init and add functions for idle
tasks shortly after the scheduler starts.

Menu config also allows for using legacy behavior, however the legacy behavior
willcall the new API functions but with slight variations to make them legacy
compatible.

Documentation and example have also been updated

gcov_rtio.c headers updated to prevent error of freertos header files being
included in the wrong order.

Resolves issue TW#13265
2017-09-29 23:10:55 +08:00

99 lines
3.1 KiB
C

/* Task_Watchdog Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_task_wdt.h"
#ifndef CONFIG_TASK_WDT_LEGACY_BEHAVIOR
#define TIMEOUT 4000
#define TASK_PERIOD 2000
#define ASSERT_PRINT_ERROR(cond, str) ({ \
if(!(cond)){ \
printf("%s\n",str); \
} \
})
void feeding_task(void *arg){
int core = xPortGetCoreID();
//Simple task that periodically feeds watchdog
while(1){
if(esp_task_wdt_feed() == ESP_OK){
printf("Feed Task %d\n", core);
}
vTaskDelay(pdMS_TO_TICKS(TASK_PERIOD));
}
}
void app_main(void)
{
//Initialize task watchdog
if(esp_task_wdt_init(TIMEOUT, false) != ESP_OK){
printf("Error\n");
}
//Create tasks
TaskHandle_t handle_0;
TaskHandle_t handle_1;
xTaskCreatePinnedToCore(feeding_task, "Feed Task 0", 2000, NULL, 15, &handle_0, 0);
xTaskCreatePinnedToCore(feeding_task, "Feed Task 1", 2000, NULL, 15, &handle_1, 1);
//Add tasks to wdt
ASSERT_PRINT_ERROR(esp_task_wdt_add(handle_0) == ESP_OK, "Add failed");
ASSERT_PRINT_ERROR(esp_task_wdt_add(handle_1) == ESP_OK, "Add failed");
#ifndef CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0
//Adding Idles. Idle hook will call feed automatically
TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0);
ASSERT_PRINT_ERROR(idle_0 != NULL, "Get Idle handle failed");
ASSERT_PRINT_ERROR(esp_task_wdt_add(idle_0) == ESP_OK, "Add failed");
#endif
#ifndef CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1
TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1);
ASSERT_PRINT_ERROR(idle_1 != NULL, "Get Idle handle failed");
ASSERT_PRINT_ERROR(esp_task_wdt_add(idle_1) == ESP_OK, "Add failed");
#endif
//Wait 10 seconds
vTaskDelay(pdMS_TO_TICKS(10000));
//Remove tasks form wdt
ASSERT_PRINT_ERROR(esp_task_wdt_delete(handle_0) == ESP_OK, "Failed to delete");
ASSERT_PRINT_ERROR(esp_task_wdt_delete(handle_1) == ESP_OK, "Failed to delete");
//Delete tasks
vTaskDelete(handle_0);
vTaskDelete(handle_1);
#ifndef CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0
ASSERT_PRINT_ERROR(esp_task_wdt_delete(idle_0) == ESP_OK, "Failed to delete");
#endif
#ifndef CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1
ASSERT_PRINT_ERROR(esp_task_wdt_delete(idle_1) == ESP_OK, "Failed to delete");
#endif
#ifndef CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0
#ifndef CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1
//Deinit task watchdog. Can only do so once all tasks (including idle) are deleted from wdt
ASSERT_PRINT_ERROR(esp_task_wdt_deinit() == ESP_OK, "deinit failed");
#endif
#endif
printf("Complete\n");
}
#endif