ESP32的喂狗失败之旅

概述

采用ARDUINO IDE为ESP32进行编程的资料非常有限,中国的乐鑫也没有太多的资料支持。但从乐鑫的官网还是可以看到对FreeRTOS的介绍,试着对Task Watchdog Timer进行理解和编程,最终归于失败,用vTaskDelay()函数防止中断触发,但如果想让程序更快执行没有实现,记录失败过程供大家参考。

Task Watchdog Timer

在ESP32的硬件配置中有中断看门狗和任务看门狗。把中断看门狗的介绍文字贴在这里,这些文字很难理解,肯定不是中国人写的:The interrupt watchdog makes sure the FreeRTOS task switching interrupt isn’t blocked for a long time. This is bad because no other tasks, including potentially important ones like the WiFi task and the idle task, can’t get any CPU runtime. A blocked task switching interrupt can happen because a program runs into an infinite loop with interrupts disabled or hangs in an interrupt. 粘贴到google得到的翻译如下:
中断看门狗确保FreeRTOS任务切换中断不会长时间被阻止。 这很不好,因为没有其他任务(包括可能重要的任务,如WiFi任务和空闲任务)无法获得任何CPU运行时间。 可能会发生阻塞的任务切换中断,因为程序在禁用中断或陷入中断的情况下进入了无限循环。
这部分的描述是不是一头雾水。不知道这些文字是从中文翻译成英文还是从意大利文翻译成英文就这个样子了。最简单的一条是中断看门狗的作用就是不要在任务切换时不能长时间占用CPU的时间。
任务看门狗定时器的描述也不是容易理解的事情,英文也贴在这里:The Task Watchdog Timer (TWDT) is responsible for detecting instances of tasks running for a prolonged period of time without yielding. This is a symptom of CPU starvation and is usually caused by a higher priority task looping without yielding to a lower-priority task thus starving the lower priority task from CPU time. This can be an indicator of poorly written code that spinloops on a peripheral, or a task that is stuck in an infinite loop. 用google翻译看看我们的智能翻译的路其实还有很多路要走:
任务看门狗定时器(TWDT)负责检测长时间运行的任务实例而不会屈服。 这是CPU饥饿的症状,通常是由较高优先级的任务循环导致的,而没有产生较低优先级的任务,因此使较低优先级的任务因CPU时间而饿死。 这可能表明外围设备上的自旋循环编写不佳的代码,或者卡在无限循环中的任务。
这部分看起来也不轻松。

控制看门狗的函数

控制看门狗的函数在程序中找到了,在sdk的目录下面,我机器上的目录是:
C:\用户<User Name>\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\tools\sdk\include\esp32.
头文件名称为:esp_int_wdt.h
乐鑫的文档说明地址:
https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/system/wdts.html
在程序中这些函数都可以使用,编译也可以通过,但就是总重启,无法在任务循环时间小于1秒时喂狗。比如我使用:
esp_err_tesp_task_wdt_init(uint32_t timeout, bool panic); 得到的结果是ESP_OK. 然后再使用:
esp_err_tesp_task_wdt_add(TaskHandle_thandle); 得到的结果也是ESP_OK. 只是在循环过程中用:
esp_err_tesp_task_wdt_reset(void); 无法实现喂狗。程序在循环时总重新启动。
最后没有办法就是在任务中的循环中添加vTaskDelay(1)来避免重启。当选择vTaskDelay(0)时就会使TWDT中断超时并触发以下信息:
ARDUINO_RUNNING_CORE = 1
setup() running on the core 1
TaskBlink on the core 0
E (5812) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (5812) task_wdt: - IDLE0 (CPU 0)
E (5812) task_wdt: Tasks currently running:
E (5812) task_wdt: CPU 0: TaskBlink
E (5812) task_wdt: CPU 1: loopTask
E (5812) task_wdt: Aborting.
abort() was called at PC 0x400d5bd3 on core 0

今天使用Ticker时钟为程序编程,当使用1ms作为定时器时也出现了没有喂狗的问题。
21:31:25.785 -> Timer = 8E (10760) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
21:31:25.785 -> E (10760) task_wdt: - IDLE0 (CPU 0)
21:31:25.820 -> E (10760) task_wdt: Tasks currently running:
21:31:25.820 -> E (10760) task_wdt: CPU 0: esp_timer
21:31:25.820 -> E (10760) task_wdt: CPU 1: loopTask
21:31:25.820 -> E (10760) task_wdt: Aborting.
21:31:25.820 -> abort() was called at PC 0x400d3737 on core 0
这个问题虽然是我的程序有问题,但还是不知道为啥会出现喂狗的问题。看样子Ticker的定时器是运行在CPU0当中的。使用的是esp_timer.

希望了解的大咖加以指点。

猜你喜欢

转载自blog.csdn.net/weixin_44481398/article/details/108333856