一、前言
看门狗是一种硬件计时器,用于监控系统的运行状态。它可以在系统出现故障或停止响应时自动重启系统,以确保系统的稳定性和可靠性。ESP-IDF 支持多种类型的看门狗,其中两种主要类型是:中断看门狗定时器和任务看门狗定时器 (TWDT)。中断看门狗定时器和 TWDT 都可以使用项目配置菜单启用,但 TWDT 也可以在运行时启用。中断看门狗负责检测 FreeRTOS 任务切换长时间受阻的实例。TWDT 负责检测长时间运行而不产生任务的实例。
二、看门狗介绍
1.中断看门狗(IWDT)
中断看门狗(IWDT) 的目的是确保中断服务程序(ISR)不会被长时间阻止运行,如果中断服务程序不能及时运行,一是会导致中断任务被延迟(一般的中断任务都比较重要,需要及时执行);二会导致任务无法切换(任务调度在中断里执行)。
当中断看门狗被触发时,默认操作是调用紧急处理程序,并将紧急原因显示为 OR。根据紧急处理程序配置的行为,用户可以调试IWDT超时的来源(通过回溯,OpenOCD,gdbstub等)或简单地重置芯片。
2.任务看门狗(TWDT)
任务监视计时器(TWDT)用于监视特定任务,确保它们能够在给定的超时时间内执行。TWDT主要监视每个CPU的空闲任务,但是任何任务都可以订阅由TWDT监视。通过观察每个CPU的空闲任务,TWDT可以检测到长时间运行而释放CPU的任务实例。
TWDT是围绕定时器组0中的硬件看门狗定时器构建的。当发生超时时,会触发中断。用户可以在用户代码中定义函数esp_task_wdt_isr_user_handler
,用来接收超时事件并制定应对策略。
三、看门狗API
1.订阅任务看门狗
esp_err_t esp_task_wdt_add(TaskHandle_t task_handle)
将任务加入看门狗(TWDT)监视。
此函数为TWDT订阅任务。每个订阅的任务都必须定期调用esp_task_wdt_reset(),以防止TWDT超时。否则将导致TWDT超时。
参数:task_handle,任务的句柄。输入NULL将当前正在运行的任务订阅到TWDT。
返回值:
- ESP_OK:已成功将任务订阅到TWDT
- Other:订阅任务失败
2.重置看门狗
四、代码测试
1.IDLE未及时执行情形
在前面的task状态打印中我们已知IDLE任务的优先级为0,处于最低的优先级,而IDLE是一个喂狗函数,如果未在规定时间内(这里设置了5s)运行IDLE喂狗,单片机将会异常重启。
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "driver/gpio.h"
#include "esp_task_wdt.h"
void blinke_slow(void *pvparam)
{
while (1)
{
;
// printf("靓仔\n");
// vTaskDelay(1000 / portTICK_PERIOD_MS); // 延时
}
}
void app_main(void)
{
TaskHandle_t xHandle = NULL;
xTaskCreate(blinke_slow, "mytask1", 1024, NULL, 1, &xHandle);
}
打印信息如下:第二行表示IDLE函数为未及时运行触发了看门狗,第四行表示触发看门狗时正在运行的是mytask1,这种情况解决办法有两种:一是调高IDLE函数的优先级,使其有资格共享CPU时间片;二是在优先级高的任务中加入延时函数,使其进入阻塞态,此时CPU会运行其他优先级低的任务,两种办法本质上都是让IDLE函数得到CPU时间片运行。
2.添加用户函数进入监控行列
有时候我们需要保证某个函数必须执行,我们可以将我们编写的函数进入看门狗监控列表,一旦发生异常,任务无法顺利执行,看门狗产生异常信号。
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "driver/gpio.h"
#include "esp_task_wdt.h"
void blinke_slow(void *pvparam)
{
while (1)
{
printf("靓仔\n");
vTaskDelay(1000 / portTICK_PERIOD_MS); // 延时
esp_task_wdt_reset();//喂狗
}
}
void app_main(void)
{
TaskHandle_t xHandle = NULL;
xTaskCreate(blinke_slow, "mytask1", 1024, NULL, 1, &xHandle);
esp_task_wdt_add(xHandle);//将mytask1加入看门狗监控列表i
}
THE END!
标签:task,07,Freertos,esp,看门狗,任务,include,TWDT From: https://www.cnblogs.com/seekwhale13/p/17517866.html