Que se passe-t-il s'il y a une erreur d'exécution dans un programme? L'exécution du programme va-t-elle simplement s'arrêter? Existe-t-il un moyen d'obtenir l'Arduino pour me dire quelle est l'erreur?
Que se passe-t-il s'il y a une erreur d'exécution dans un programme? L'exécution du programme va-t-elle simplement s'arrêter? Existe-t-il un moyen d'obtenir l'Arduino pour me dire quelle est l'erreur?
Réponses:
Voyons d'abord quelques exemples de ce qui peut mal tourner.
void setup() {
int status;
pinMode(13, OUTPUT);
digitalWrite(13, status);
}
Comme l'a souligné Edgar Bonet dans les commentaires, les variables locales comme status
dans le code ci-dessus ne sont pas implicitement initialisées par le compilateur C ++. Ainsi, le résultat du code ci-dessus est indéterminé. Pour éviter cela, assurez-vous d'attribuer toujours des valeurs à vos variables locales.
Les choses sont un peu différentes avec les variables globales et statiques:
Les variables globales et statiques sont garanties d'être initialisées à 0 par la norme C.
Cela signifie que vous ne devriez pas vous soucier de les initialiser à 0 dans votre code. En fait, vous devriez vraiment l'éviter, car l'initialisation peut gaspiller de la mémoire. Les initialiser uniquement à des valeurs autres que 0.
int array[10];
int v = array[100];
array[-100] = 10;
Le premier problème ici est que vous ne savez pas ce qui sera attribué à v, mais pire, vous ne savez pas ce que vous avez gâché avec l'affectation au poste -100 de array
.
void doSomething( void ) {
for (int i = 0; i < 1000; i++);
}
void setup ()
{
void (*funcPtr)( void );
funcPtr = &doSomething;
funcPtr(); // calls doSomething();
funcPtr = NULL;
funcPtr(); // undefined behavior
}
Le premier appel à funcPtr()
sera en fait un appel à doSomething()
. Des appels comme le second peuvent conduire à un comportement indéfini.
Eh bien, vous pouvez manquer de RAM, par exemple. Quoi d'autre. Dans tous les cas, je pense que votre programme continuera de fonctionner, probablement pas comme vous le souhaitiez.
Dans les systèmes informatiques, de tels problèmes sont généralement traités à différents niveaux:
Les Arduinos n'ont qu'une protection limitée du compilateur, et probablement rien d'autre. La bonne nouvelle est qu'ils ne sont pas polyvalents, donc le seul programme affecté est le vôtre. Dans tous les cas, l'un de ces bogues entraînera un comportement erratique.
Les hypothèses sont tous les problèmes que j'ai indiqués ci-dessus sont des problèmes d'exécution.
Que se passe-t-il s'il y a une erreur d'exécution dans un programme?
Le programme continuera et ce qui se passera dépendra des effets secondaires de l'erreur d'exécution. Un appel au pointeur de fonction null fera probablement sauter le programme vers un emplacement inconnu.
L'exécution du programme va-t-elle simplement s'arrêter?
Non, cela continuera comme si rien d'extraordinaire ne s'était produit, faisant probablement ce que vous n'aviez pas l'intention de faire. Il peut se réinitialiser ou agir de manière erratique. Il peut transformer certaines entrées en sorties et graver un ou deux capteurs (mais c'est très peu probable ).
Existe-t-il un moyen d'obtenir l'Arduino pour me dire quelle est l'erreur?
Je ne pense pas. Comme je l'ai dit plus tôt, les mécanismes de protection ne sont pas là. Il n'y a pas de support d'exécution de la langue, pas de système d'exploitation, pas de vérifications matérielles pour l'accès à la mémoire hors des limites (le chargeur de démarrage ne compte pas non plus). Vous devez juste être prudent avec votre programme et probablement définir vos propres filets de sécurité.
La raison du manque de protection est probablement parce que les contrôleurs Arduino sont trop bon marché, ont trop peu de mémoire et ne devraient pas exécuter quelque chose de trop important (oui, il semble y avoir un avertissement par AVR quelque part pour que vous n'utilisiez pas les MCU normalement utilisés par Arduino dans les systèmes de survie).
Il n'y a aucune exception d'exécution. Il n'y a qu'un comportement indéfini.
Vraiment, il n'y a aucune exception à tous . Si vous essayez d'effectuer une opération non valide, ses résultats seront inconnus.
Il n'y a aucune vérification d'exécution, sauf ce que vous implémentez. Votre programme fonctionne sur du matériel nu. C'est l'équivalent du bureau de fonctionner en ring-0 tout le temps, car l'ATmega n'a pas de ring .
Il existe un mécanisme qui peut obtenir le MCU d'un état erratique et c'est le temporisateur de surveillance . Si vous implémentez un code qui s'exécutera à plusieurs reprises dans une boucle, qui ne s'exécutera pas plus longtemps qu'une heure fixe, vous pouvez définir cette heure comme période de surveillance et activer le minuteur.
Ensuite, vous devez réinitialiser à plusieurs reprises le minuteur dans la boucle. Si votre code se bloque à une boucle de condition qui ne se terminera jamais, le chien de garde comptera jusqu'à zéro et réinitialisera éventuellement le MCU.
De cette façon, vous perdez des données, mais si vous exécutez l'AVR WDT en mode interruption, vous pouvez stocker certaines données avant de réinitialiser le MCU.
Ainsi, la minuterie de surveillance peut protéger votre code contre les boucles sans fin occasionnelles et involontaires.
Documentation: AVR132: Utilisation de la minuterie de surveillance améliorée
Vous auriez besoin d'un débogueur matériel pour quelque chose comme ça. Mais généralement, vous verrez que le programme ne se comporte pas comme vous vous y attendez et devrez regarder cette section du code pour identifier le problème.
Une façon courante / rapide / facile de le faire consiste à ajouter des instructions print pour imprimer les valeurs des variables ou tout simplement pour que vous sachiez que le programme arrive à ce point dans le code sans problème. Cela vous aidera à isoler davantage le problème.
Je crois que VisualMicro a une fonctionnalité de débogage intégrée.
Je suppose que le processeur AVR n'a pas d'outils de détection ou de récupération d'erreur. Il peut simplement s'arrêter ou continuer à ignorer l'erreur et les conséquences. Comme l'a dit Sachleen, vous devez ajouter des instructions de débogage dans votre programme qui impriment des données au milieu d'une opération, pour tester si cela fonctionne. Si vous utilisez un émulateur ou définissez des points d'arrêt, vous pouvez facilement trouver un problème.
L'Arduino redémarrera (c'est-à-dire qu'il redémarrera setup()
et loop()
).