ESP32-任务看门狗笔记

看门狗机制用于监控嵌入式系统运行并在发生不可知的软硬件故障时将系统复位。系统正常运行时,看门狗定时器溢出之前会被重置计数值,也就是“喂狗”。定时器溢出意味着无法“喂狗”,系统异常。

基于ESP-IDF4.1

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include "freertos/FreeRTOS.h"
 4 #include "freertos/task.h"
 5 #include "esp_task_wdt.h"
 6 
 7 #define TWDT_TIMEOUT_S          3
 8 #define TASK_RESET_PERIOD_S     2
 9 
10 /*
11  * 检查任务看门狗输出的宏,并在返回错误代码的时候触发中止
12  */
13 #define CHECK_ERROR_CODE(returned, expected) ({                        \
14             if(returned != expected){                                  \
15                 printf("TWDT ERROR\n");                                \
16                 abort();                                               \
17             }                                                          \
18 })
19 
20 static TaskHandle_t task_handles[portNUM_PROCESSORS];
21 
22 //用户任务的回调函数
23 void reset_task(void *arg)
24 {
25     //将任务添加到任务看门狗,并检查是否已添加
26     CHECK_ERROR_CODE(esp_task_wdt_add(NULL), ESP_OK);
27     CHECK_ERROR_CODE(esp_task_wdt_status(NULL), ESP_OK);
28 
29     while(1){
30         //每2秒重置一次看门狗
31         CHECK_ERROR_CODE(esp_task_wdt_reset(), ESP_OK);  //注释这一行可以触发看门狗超时
32         vTaskDelay(pdMS_TO_TICKS(TASK_RESET_PERIOD_S * 1000));
33     }
34 }
35 
36 void app_main(void)
37 {
38     printf("Initialize TWDT\n");
39     //初始化和重新初始化任务看门狗
40     CHECK_ERROR_CODE(esp_task_wdt_init(TWDT_TIMEOUT_S, false), ESP_OK);
41 
42     //启动时未订阅空闲任务,则订阅到任务看门狗
43 #ifndef CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
44     esp_task_wdt_add(xTaskGetIdleTaskHandleForCPU(0));
45 #endif
46 #ifndef CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1
47     esp_task_wdt_add(xTaskGetIdleTaskHandleForCPU(1));
48 #endif
49 
50     //创建用户任务并添加到任务看门狗
51     for(int i = 0; i < portNUM_PROCESSORS; i++){
52         xTaskCreatePinnedToCore(reset_task, "reset task", 1024, NULL, 10, &task_handles[i], i);
53     }
54 
55     printf("Delay for 10 seconds\n");
56     vTaskDelay(pdMS_TO_TICKS(10000));   //延迟10秒
57 
58     printf("Unsubscribing and deleting tasks\n");
59     //从任务监视程序中删除并取消订阅用户任务,然后取消订阅空闲任务
60     for(int i = 0; i < portNUM_PROCESSORS; i++){
61         vTaskDelete(task_handles[i]);   //首先删除用户任务(防止重置未订阅的任务)
62         CHECK_ERROR_CODE(esp_task_wdt_delete(task_handles[i]), ESP_OK);     //从任务看门狗取消订阅任务
63         CHECK_ERROR_CODE(esp_task_wdt_status(task_handles[i]), ESP_ERR_NOT_FOUND);  //确认任务已经取消订阅
64 
65         //取消订阅空闲任务
66         CHECK_ERROR_CODE(esp_task_wdt_delete(xTaskGetIdleTaskHandleForCPU(i)), ESP_OK);     //从任务看门狗取消订阅空闲任务
67         CHECK_ERROR_CODE(esp_task_wdt_status(xTaskGetIdleTaskHandleForCPU(i)), ESP_ERR_NOT_FOUND);      //确认空闲人取消订阅
68     }
69 
70 
71     //取消订阅所有任务后,取消初始化任务看门狗
72     CHECK_ERROR_CODE(esp_task_wdt_deinit(), ESP_OK);
73     CHECK_ERROR_CODE(esp_task_wdt_status(NULL), ESP_ERR_INVALID_STATE);     //确认任务看门狗取消初始化
74 
75     printf("Complete\n");
76 }

 

原文:https://gitee.com/EspressifSystems/esp-idf/tree/master/examples/system/task_watchdog

posted @ 2020-11-12 12:42  kerwin cui  阅读(3400)  评论(0编辑  收藏  举报