3.27. Minuteur de surveillance (watchdog)¶
Un minuteur de surveillance (watchdog) est un matériel qui réinitialise le microcontrôleur si le script en cours d’exécution cesse de le solliciter périodiquement. Le script « nourrit » le watchdog depuis un endroit dont il sait qu’il exécute du code sain ; si un bogue, un blocage ou une exception inattendue empêche un jour la caméra de nourrir le watchdog dans le délai configuré, la puce se réinitialise elle-même et le script repart de zéro.
Sur un appareil déployé sans personne à proximité pour le redémarrer, c’est la différence entre un bogue transitoire qui se rétablit en quelques secondes et une brique nécessitant une intervention de maintenance.
Le compteur du watchdog décompte à partir de son délai d’expiration. Chaque feed() le recharge ; s’il atteint zéro, la puce se réinitialise.¶
3.27.1. La classe machine.WDT¶
machine.WDT active le watchdog et expose une seule méthode, feed(). Une fois démarré, le watchdog ne peut plus être arrêté – les seules issues sont de le nourrir à temps ou de le laisser réinitialiser la puce :
from machine import WDT
wdt = WDT(timeout=2000) # reset if not fed within 2 seconds
while True:
do_work()
wdt.feed()
Le timeout est en millisecondes. La bonne valeur dépend de la durée de l’itération légitime la plus longue de la boucle principale, avec une marge confortable – une boucle de 100 ms avec un délai de 2 s dispose d’une ample marge pour une itération lente sans réinitialisations intempestives.
3.27.2. Où appeler feed()¶
L’emplacement de feed() est la décision de conception critique ; le watchdog ne détecte que les bogues dans les parties du code qui ne s’exécutent pas entre les feeds.
Appelez-le depuis la boucle principale, en haut ou en bas. Le modèle le plus courant. Le watchdog détecte tout ce qui bloque la boucle principale – un interblocage, un
whileinfini, un périphérique qui ne retourne jamais – et réinitialise la puce pour la ramener dans la boucle.N’appelez pas depuis un gestionnaire d’interruption. L’intérêt du watchdog est de détecter les blocages dans le chemin de code normal. Une ISR qui se déclenche que la boucle principale soit bloquée ou non continuerait de nourrir un watchdog qui devrait se déclencher.
N’appelez pas depuis une longue opération bloquante. Une requête réseau ou une lecture de capteur qui prend dix secondes est exactement le genre de blocage que le watchdog devrait détecter. Y placer
feed()annule la protection.
Une règle qui fonctionne pour la plupart des programmes : nourrir une fois par itération de la boucle principale, avec le délai d’expiration réglé à plusieurs fois la durée attendue de la boucle. Si une seule itération nécessite légitimement plus de temps que le délai – une phase de calibration délibérée, par exemple – structurez cette phase en une série de plus petits blocs avec feed() entre eux, ou modifiez le délai avec timeout_ms() (lorsque c’est pris en charge) avant d’y entrer.
3.27.3. Disponibilité¶
Le watchdog est exposé sur la plupart des caméras OpenMV mais pas toutes – le matériel est présent sur chaque puce, mais l’API Python n’est pas encore câblée partout. Consultez la Cartes OpenMV ou tentez de construire un WDT et capturez l”AttributeError s’il n’est pas pris en charge.
Même sur les caméras où WDT n’est pas exposé, un appareil déployé sur le terrain peut utiliser un équivalent logiciel – une tâche distincte ou une étape de la boucle principale qui surveille la progression et déclenche machine.reset() si quelque chose semble coincé. C’est moins robuste qu’un watchdog matériel (un gestionnaire d’interruption coincé peut aussi faire tomber le moniteur logiciel) mais cela couvre les mêmes cas au niveau applicatif.