赞
踩
陈拓 2022/07/02-2022/07/02
此示例演示如何使用任务看门狗计时器Task Watchdog Timer (TWDT)的以下功能:
https://gitee.com/EspressifSystems/esp-idf/tree/master/examples/system/task_watchdog
《用乐鑫国内Gitee镜像搭建ESP32开发环境》
https://zhuanlan.zhihu.com/p/348106034
https://blog.csdn.net/chentuo2000/article/details/113424934?spm=1001.2014.3001.5501
将官方例子项目复制到ESP-IDF开发工具之外:
cd ~/esp
cp -r ~/esp/esp-idf/examples/system/task_watchdog ~/esp/
cd ~/esp/task_watchdog
tree
get_idf
idf.py set-target esp32
idf.py menuconfig
1) 将闪存设置为4MB
2) 在任务看门狗超时时调用紧急处理程序
保存,退出。
idf.py build
查看USB转串口的COM口号:
烧写:
idf.py -p /dev/ttyS3 -b 115200 flash
idf.py monitor -p /dev/ttyS3
当示例正常运行时,将观察到以下输出:
用户可以注释掉esp_task_wdt_reset()或esp_task_wdt_reset_user()调用以测试触发TWDT,
//CHECK_ERROR_CODE(esp_task_wdt_reset(), ESP_OK);
这将导致以下输出:
看门狗被触发。
因为TWDT超时时间为3秒:
#define TWDT_TIMEOUT_S 3 // TWDT超时时间
延时为10秒:
vTaskDelay(pdMS_TO_TICKS(10000)); // 延时10秒
在10秒延时期间,看门狗有3次触发,之后程序会继续执行:
如果你希望任务看门狗触发之后进行重启。
- void esp_task_wdt_isr_user_handler(void)
- {
- esp_restart();
- }
这样在看门狗触发时程序会重新启动:
- /* Task_Watchdog Examples
- 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 "esp_task_wdt.h"
-
- #define TWDT_TIMEOUT_S 3 // TWDT超时时间
- #define TASK_RESET_PERIOD_S 2 // 任务重置周期时间
-
- /*
- * 宏,用于检查TWDT的输出,如果检测到返回错误码则触发中止程序执行。
- */
- #define CHECK_ERROR_CODE(returned, expected) ({ \
- if(returned != expected){ \
- printf("TWDT ERROR\n"); \
- abort(); \
- } \
- })
-
- static TaskHandle_t task_handles[portNUM_PROCESSORS];
-
- // 回调由app_main()创建的用户任务
- void reset_task(void *arg)
- {
- // 为TWDT添加任务,并检查dwt状态看是否添加
- CHECK_ERROR_CODE(esp_task_wdt_add(NULL), ESP_OK);
- CHECK_ERROR_CODE(esp_task_wdt_status(NULL), ESP_OK);
-
- while(1){
- // 每2秒重置一次看门狗
- //CHECK_ERROR_CODE(esp_task_wdt_reset(), ESP_OK); // 喂狗。注释此行以测试触发TWDT超时
- vTaskDelay(pdMS_TO_TICKS(TASK_RESET_PERIOD_S * 1000));
- }
- }
-
- void esp_task_wdt_isr_user_handler(void)
- {
- esp_restart();
- }
-
- void app_main(void)
- {
- printf("Initialize TWDT\n");
- // 初始化或者重新初始化TWDT
- CHECK_ERROR_CODE(esp_task_wdt_init(TWDT_TIMEOUT_S, false), ESP_OK);
-
- // 如果启动时未订阅空闲任务,则将其订阅到TWDT
- #ifndef CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
- esp_task_wdt_add(xTaskGetIdleTaskHandleForCPU(0));
- #endif
- #if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 && !CONFIG_FREERTOS_UNICORE
- esp_task_wdt_add(xTaskGetIdleTaskHandleForCPU(1));
- #endif
-
- // 创建用户任务并添加到看门狗
- for(int i = 0; i < portNUM_PROCESSORS; i++){
- xTaskCreatePinnedToCore(reset_task, "reset task", 1024, NULL, 10, &task_handles[i], i);
- }
-
- printf("Delay for 10 seconds\n");
- vTaskDelay(pdMS_TO_TICKS(10000)); // 延时10秒
-
- printf("Unsubscribing and deleting tasks\n");
- // 从任务看门狗中删除并取消订阅用户任务,然后取消订阅空闲任务
- for(int i = 0; i < portNUM_PROCESSORS; i++){
- vTaskDelete(task_handles[i]); // 首先删除用户任务(防止重置未订阅的任务)
- CHECK_ERROR_CODE(esp_task_wdt_delete(task_handles[i]), ESP_OK); // 从TWDT取消订阅任务
- CHECK_ERROR_CODE(esp_task_wdt_status(task_handles[i]), ESP_ERR_NOT_FOUND); // 确认任务已取消订阅
-
- // 取消订阅空闲任务
- CHECK_ERROR_CODE(esp_task_wdt_delete(xTaskGetIdleTaskHandleForCPU(i)), ESP_OK); // 从TWDT取消订阅空闲任务
- CHECK_ERROR_CODE(esp_task_wdt_status(xTaskGetIdleTaskHandleForCPU(i)), ESP_ERR_NOT_FOUND); // 确认空闲任务已取消订阅
- }
-
- // 在所有任务取消订阅后取消TWDT
- CHECK_ERROR_CODE(esp_task_wdt_deinit(), ESP_OK);
- CHECK_ERROR_CODE(esp_task_wdt_status(NULL), ESP_ERR_INVALID_STATE); //Confirm TWDT has been deinitialized 确认TWDT已解除初始化
-
- printf("Complete\n");
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。