ESP32 Task Watchdog触发报错:loopTask未及时重置看门狗求助
报错信息
task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (25603) task_wdt: - loopTask (CPU 1)
E (25603) task_wdt: Tasks currently running:
E (25603) task_wdt: CPU 0: Task1
E (25603) task_wdt: CPU 1: loopTask
E (25603) task_wdt: Aborting.abort() was called at PC 0x400dfab9 on core 0
Backtrace: 0x400836ad:0x3ffbec3c |<-CORRUPTED
ELF file SHA256: fde7bf06d933983a
Rebooting...
相关代码
#include <Arduino.h> #include <esp_task_wdt.h> #include <RfidManager.h> #include <DisplayManager.h> #include <EspNowSender.h> #include <BLESlave.h> // const uint8_t receiverAddress[] = {0x88, 0x13, 0xBF, 0x24, 0xBD, 0x98}; RfidManager rfidManager; DisplayManager displayManager; EspNowSender espSender; BLESlave bleSlave; WiFiMulti wifiMulti; uint8_t broadcastAddress[] = {0x88, 0x13, 0xBF, 0x24, 0xDB, 0x98}; typedef struct struct_pilot { int id; int x; int y; } struct_pilot; struct_pilot myPilot; esp_now_peer_info_t peerInfo; void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { Serial.print("\r\nLast Packet Send Status:\t"); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); } void sendDataTask(void *parameter) { for (;;) { myPilot.id = 2; if(digitalRead(15) == 0){ myPilot.x = 0; } if(digitalRead(4) == 0){ myPilot.x = 0; } if(digitalRead(13) == 0){ myPilot.x = 0; } if(digitalRead(12) == 0){ myPilot.x = 1; } if(digitalRead(14) == 0){ myPilot.x = 1; } myPilot.y = random(0,50); esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myPilot, sizeof(myPilot)); if (result == ESP_OK) { Serial.println("Sent with success"); } else { Serial.println("Error sending the data"); } vTaskDelay(pdMS_TO_TICKS(2000)); // Delay for 2 seconds } } void Task1(void *pvParameters);// This rfid task void Task2(void *pvParameters);// This display task void setup() { Serial.begin(9600); wifiMulti.addAP("Nang Luong Xanh", "nangluongxanh360"); Serial.println("Connecting to WiFi..."); while (wifiMulti.run() != WL_CONNECTED) { Serial.print("."); delay(100); } Serial.println("\nConnected to WiFi"); WiFi.mode(WIFI_STA); // Initialize ESP-NOW if (esp_now_init() != ESP_OK) { Serial.println("Error initializing ESP-NOW"); return; } esp_now_register_send_cb(OnDataSent); memcpy(peerInfo.peer_addr, broadcastAddress, 6); peerInfo.channel = 0; peerInfo.encrypt = false; if (esp_now_add_peer(&peerInfo) != ESP_OK) { Serial.println("Failed to add peer"); return; } esp_task_wdt_init(15, true); // 将超时时间设置为15秒 esp_task_wdt_add(NULL); // 将当前任务(main task)添加到WDT xTaskCreatePinnedToCore( Task1, "Task1", 2048, NULL, 2, NULL, 0); // RFID任务 xTaskCreatePinnedToCore( Task2, "Task2", 2048, NULL, 1, NULL, 1);; // 显示任务 xTaskCreate(sendDataTask, "Send Data Task", 2048, NULL, 1, NULL); } void loop() { } void Task1(void *pvParameters) // RFID任务 { rfidManager.RfidManagerSetup(); esp_task_wdt_add(NULL); // 将Task1添加到WDT for(;;) { rfidManager.RfidManagerloop(); esp_task_wdt_reset(); // 重置看门狗 vTaskDelay(100 / portTICK_PERIOD_MS); // 缩短延迟时间 } } void Task2(void *pvParameters) // 显示任务 { displayManager.DisplayManagerSetup(); esp_task_wdt_add(NULL); // 将Task2添加到WDT for(;;) { displayManager.DisplayManagerloop(); esp_task_wdt_reset(); // 重置看门狗 vTaskDelay(500 / portTICK_PERIOD_MS); // 缩短延迟时间 } }
问题分析与解决方法
核心原因
报错明确指向CPU1上的loopTask未及时重置看门狗。ESP32 Arduino框架默认会将运行loop()函数的loopTask加入看门狗监控,但你的loop()函数为空,且未添加看门狗重置逻辑,导致系统判定该任务超时。
另外需要排查同CPU(CPU1)上的Task2是否存在长时间阻塞代码:Task2与loopTask优先级相同(均为1),若DisplayManagerloop()包含无延迟死循环、未超时的阻塞操作,会抢占CPU时间,导致loopTask无法执行看门狗重置。
解决方案
方案1:给loop()添加看门狗重置逻辑
修改空的loop()函数,定期重置看门狗并释放CPU:
void loop() { esp_task_wdt_reset(); vTaskDelay(pdMS_TO_TICKS(100)); // 给任务调度器留出切换时间 }
方案2:移除loopTask的看门狗监控
在setup()函数末尾添加代码,将loopTask从看门狗监控中移除:
// 获取loopTask句柄并取消看门狗监控 TaskHandle_t loopTaskHandle = xTaskGetHandle("loopTask"); if (loopTaskHandle != NULL) { esp_task_wdt_delete(loopTaskHandle); }
方案3:检查自定义任务的阻塞逻辑
排查RfidManagerloop()和DisplayManagerloop()的实现,确保不存在长时间阻塞操作:
- 替换无超时的
while循环为非阻塞逻辑 - 确保所有耗时操作都设置合理超时时间
- 保留
vTaskDelay或taskYIELD()调用,让任务能周期性释放CPU
内容的提问来源于stack exchange,提问作者HaiDinh

