Récemment, je me suis amusé avec les fonctionnalités multicœur de l’ESP32 et l’épinglage de tâches sur des cœurs spécifiques.

J’utilisais AutoConnect pour gérer la connexion WiFi sans stocker d’identifiants dans le code et proposer des mises à jour OTA via l’interface web.

C’était pour un projet qui devait contrôler des ventilateurs CPU PWM à 4 broches qui se trouvent dans mon placard serveur, pour refroidir l’air à l’intérieur. Pour cela, je voulais séparer la logique en deux tâches.

Une tâche pour gérer les API, la lecture des capteurs, les mises à jour, le WiFi, etc., et une tâche pour gérer l’interruption et le contrôle PWM des ventilateurs.

Tout allait bien, les tâches étaient créées, mais à l’exécution du code, si je mettais l’ESP32 dans le mode où il faut se connecter à lui pour lui dire de rejoindre votre réseau WiFi, il se mettait à avoir un comportement étrange : il réinitialisait le contrôleur toutes les quelques secondes et je n’arrivais pas à établir la connexion.

Ce fut un moment pénible, car il fallait démonter le contrôleur de son emplacement et le brancher en USB pour flasher un nouveau firmware.

Après ça, j’ai remarqué que l’erreur venait du watchdog :

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: ControllerTask

En fouillant un peu, il s’avère que c’est déclenché par le Task Watchdog de l’ESP32, qui s’assure que les tâches aient leur tour d’exécution sur le CPU.

Il semblait aussi qu’AutoConnect n’était pas très flexible dans le contexte d’une tâche, comparé à une exécution en dehors, directement avec tout le reste du code et des fonctionnalités.

Après avoir creusé un peu et essayé différentes choses, il semble que le moyen le plus simple de s’en sortir soit de simplement désactiver le watchdog et d’espérer que tout s’exécute à temps 🙂 La tâche n’est pas critique, donc ce n’est pas grave d’attendre plus longtemps qu’elle termine ce qu’elle fait.

Pour désactiver le watchdog, il faut faire deux choses :

D’abord, inclure l’en-tête esp_task_wdt.h. Pour cela, ajoutez #include <esp_task_wdt.h> dans votre section d’includes.

Ensuite, faire en sorte que le watchdog ne réinitialise pas le contrôleur et attende plus longtemps. Pour cela, ajoutez esp_task_wdt_init(30, false); au début du code de votre tâche.

void manage_core_task(void *pv_parameters) {
    esp_task_wdt_init(30, false);
    // .... rest of the code ...
}

Cela règle le délai du watchdog à 30 SECONDES et désactive la réinitialisation du contrôleur s’il se déclenche.

Si vous voulez que le contrôleur se réinitialise quand même après le déclenchement du watchdog, changez le second paramètre de l’appel de fonction de false à true.