Kürzlich habe ich ein bisschen mit der Multicore-Funktionalität des ESP32 und dem Pinning von Tasks auf bestimmte Kerne herumgespielt.
Ich habe AutoConnect verwendet, um eine WLAN-Verbindung ohne im Code gespeicherte Zugangsdaten zu unterstützen und OTA-Updates über die Web-Oberfläche anzubieten.
Das war für ein Projekt, das einige 4-Pin-PWM-CPU-Lüfter in meinem Serverschrank steuern sollte, um die Luft darin zu kühlen. Dafür wollte ich die Logik auf zwei Tasks aufteilen.
Ein Task für APIs, Sensorauslesung, Updates, WLAN usw. und ein Task für den Interrupt und die PWM-Steuerung der Lüfter.
Alles war gut, die Tasks wurden erstellt, aber beim Ausführen des Codes zeigte sich ein seltsames Verhalten, sobald ich den ESP32 in den Modus brachte, in dem man sich mit ihm verbinden muss, um ihm zu sagen, mit welchem WLAN er sich verbinden soll: Er startete alle paar Sekunden den Controller neu, und ich bekam die Verbindung nicht zum Laufen.
Das war eine nervige Zeit, denn ich musste den Controller von seinem Platz abmontieren und per USB anschließen, um eine neue Firmware zu flashen.
Nachdem ich das getan hatte, bemerkte ich, dass der Fehler vom Watchdog kam:
Task watchdog got triggered. The following tasks did not feed the watchdog in time:
IDLE (CPU 1)
Tasks currently running:
CPU 0: ManageTask
CPU 1: ControllerTaskBeim Recherchieren stellte sich heraus, dass das vom Task-Watchdog des ESP32 ausgelöst wird, der sicherstellt, dass alle Tasks ihre Rechenzeit auf der CPU bekommen.
Außerdem schien AutoConnect in einem Task-Kontext nicht besonders flexibel zu sein, verglichen mit der Ausführung außerhalb eines Tasks, direkt zusammen mit dem restlichen Code und den anderen Funktionen.
Nach etwas Herumstöbern und Ausprobieren scheint der einfachste Ausweg zu sein, den Watchdog einfach zu deaktivieren und zu hoffen, dass alles rechtzeitig ausgeführt wird 🙂 Der Task ist nicht geschäftskritisch, also ist es in Ordnung, wenn er etwas länger braucht, um fertig zu werden.
Um den Watchdog zu deaktivieren, musst du zwei Dinge tun:
Erstens: den Header esp_task_wdt.h einbinden. Füge dazu #include <esp_task_wdt.h> zu deinem Include-Bereich hinzu.
Zweitens: den Watchdog so einstellen, dass er den Controller nicht zurücksetzt und länger wartet. Dafür musst du esp_task_wdt_init(30, false); am Anfang deines Task-Codes einfügen.
void manage_core_task(void *pv_parameters) {
esp_task_wdt_init(30, false);
// .... rest of the code ...
}Das setzt das Watchdog-Timeout auf 30 SEKUNDEN und deaktiviert den Controller-Reset, wenn er ausgelöst wird.
Wenn du möchtest, dass der Controller nach dem Auslösen des Watchdogs trotzdem zurückgesetzt wird, ändere den zweiten Parameter des Funktionsaufrufs von false auf true.