2009-03-19 7 views
9

J'ai un chien de garde dans mon microcontrôleur qui, s'il n'est pas kické, va réinitialiser le processeur. Mes applications fonctionnent bien pendant un certain temps, mais vont finalement se réinitialiser parce que le chien de garde n'a pas été kické. Si je parcours le programme, ça fonctionne bien.Comment déboguer un timeout chien de garde

Quels sont les moyens de déboguer cela?

EDIT: Conclusion: La façon dont j'ai trouvé mon bogue était la chapelure du chien de garde. J'utilise un PIC qui a un vecteur ISR haut et bas. Le vecteur High était censé gérer la matrice LED et le vecteur Low devait gérer le tick du timer. Mais j'ai mis les deux gestionnaires ISR dans le vecteur haute. Ainsi, lorsque j'ai désactivé la matrice ISR de la matrice LED et que le service ISR du timer tick tick est nécessaire, le processeur serait bloqué dans le ISR bas pour gérer le tick timer, mais le gestionnaire de tick timer n'était pas là. Le fil d'Ariane a limité ma recherche à la fonction qui gérait la matrice LED et désactivait spécifiquement l'interruption de la matrice LED.

Répondre

9

Ajoutez une variable globale non initialisée dont les valeurs sont différentes dans le code. Spécifiquement, définissez-le avant et après les appels de fonction principaux.

Mettez un point d'arrêt au début de la ligne principale.

Lorsque le processeur est réinitialisé, la variable globale conserve la dernière valeur définie. Continuez à ajouter ces "miettes de pain" pour affiner la fonction problème.

+0

Juste à ajouter pour quiconque vient ici: Une "variable globale non initialisée" nécessitera une sémantique spéciale avec des compilateurs C. La norme dit que même les variables globales qui ne sont pas affectées d'une valeur doivent être initialisées à zéro. Donc, on aura typiquement besoin d'attributs pour ces variables comme par ex. ".noinit" pour avr-gcc. – FourtyTwo

0

Question toutes les hypothèses que vous faites, deux fois:

  • Assurez-vous que le chien de garde est donné le coup (je ne sais pas les installations d'exploitation forestière sur le processeur).
  • Assurez-vous que le chien de garde, lorsqu'il est kické, ne réinitialise pas le processeur.

Et demandez-vous quelles sont les différences entre «passer à travers» et courir seul; les contraintes de timing auront sûrement de l'importance.

3

De nombreux chiens de garde logiciels sont automatiquement désactivés lorsque vous attachez un débogueur (pour l'empêcher de redémarrer alors que l'application a été arrêtée par le débogueur).

Cela dit, voici quelques notions de base:

Est-ce une des applications multithread? Utilisez-vous un planificateur RT? Si oui, votre tâche de surveillance est-elle affamée?

Assurez-vous que votre tâche de surveillance ne peut pas être bloquée sur quoi que ce soit (sémaphore en attente, attente d'un message, etc.). Parfois, les fonctions peuvent bloquer de manière inattendue. par exemple, j'ai une plate-forme Linux sur laquelle je travaille en ce moment où je peux obtenir printf pour bloquer assez facilement.

S'il s'agit d'un seul thread, un profileur peut vous aider à identifier les problèmes de synchronisation.

S'il s'agit d'un nouveau système, assurez-vous que le chien de garde fonctionne correctement; tester un code simple qui vient frapper le WD, puis dort dans une boucle infinie.

+1

+1 en particulier pour le premier paragraphe. –

+0

seconde à vous! :) Chaque fois que la nouvelle carte d'émulation arrive pour le débogage, la première chose dont je m'assure est que l'unité WD est coupée! –

2

J'utilise la programmation basée sur l'état et un truc que j'ai toujours voulu utiliser était de réserver un port de sortie pour l'état actuel en binaire.Ensuite, connectez un analyseur logique et voir les timings des changements d'état. Vous pouvez faire quelque chose de similaire ici: Faites ce que Robert a dit et créez une variable globale et changez sa valeur aux points clés - de préférence avec une fonction qui définit immédiatement la valeur du port à l'état actuel (ie changeState (nextState); état lorsque vous entrez dans la fonction qui donne un coup de pied au chien, puis revenez à l'état précédent avant de quitter la fonction. Vous devriez être capable de voir à partir de quelles fonctions il ne reçoit pas de coup de pied et ensuite vous pouvez travailler sur ceux-ci.

Bonne chance, cela ressemble à un problème de synchronisation et ceux-ci sont difficiles à résoudre.

1

Habituellement, la tâche/le thread de surveillance fonctionne avec une priorité faible. Donc, si le chien de garde ne reçoit pas de coup de pied, cela devrait être dû au fait que le processeur est occupé à faire autre chose - probablement quelque chose qu'il ne devrait pas faire.

Il serait vraiment utile de vider le contexte d'exécution (pile locale, état de planification, etc.) pour chaque tâche/thread juste avant que le processeur ne se réinitialise. Avec un peu de chance et de travail, vous serez en mesure de déterminer ce qui empêche la tâche du chien de garde de lancer le chronomètre.

1

J'utiliserais une broche de sortie supplémentaire, réglée haut puis bas aux points appropriés dans le code pour limiter la portée de l'endroit où je regarde. Ensuite, je le tracerais sur un oscilloscope numérique ou un analyseur logique. Ceci est équivalent à la méthode de chapelure mentionnée par une autre affiche, mais vous serez en mesure de corréler le temps avec l'impulsion de réinitialisation beaucoup mieux.

0

Vous pouvez insérer une boucle while dans votre code et activer une LED dans la boucle while. C'est le moyen efficace de vérifier si la carte est en cours de réinitialisation.