Question

J'ai un système intégré qui comporte plusieurs tâches (> 20) exécutées selon des priorités différentes. J'ai également une tâche de surveillance qui s'exécute pour vérifier que toutes les autres tâches ne sont pas bloquées. Mon chien de garde fonctionne, car chaque fois dans une lune bleue, il redémarre le système, car une tâche n'a pas été enregistrée.

Comment déterminer quelle tâche est morte?

Je ne peux pas tout simplement reprocher à la tâche la plus ancienne de donner un coup de pied au chien de garde, car elle aurait pu être retardée par une tâche de priorité plus élevée qui ne cédait pas.

Des suggestions?

Était-ce utile?

La solution

Un chien de garde par tâche exige que les tâches de priorité supérieure cèdent pendant un temps suffisant pour que toutes puissent lancer le chien de garde. Pour déterminer quelle tâche est en cause, vous devez trouver celle qui affame les autres. Vous devrez mesurer le temps d'exécution des tâches entre les contrôles de surveillance pour localiser le coupable.

Autres conseils

Même si je travaillais depuis quelques semaines sur le problème de réinitialisation de Watchdog. Mais heureusement pour moi, dans les fichiers ramdump (dans l’environnement de développement ARM), qui possède un tampon de trace du gestionnaire d’interruptions, contenant PC et SLR à chacune des interruptions. Ainsi, à partir du tampon de trace, je pouvais savoir exactement quelle partie du code était en cours d'exécution avant la réinitialisation de WD.

Je pense que si vous avez le même type de mécanisme de stockage PC, reflex à chaque interruption, vous pouvez alors identifier précisément la tâche du coupable.

Est-ce préventif? Je suppose que, car sinon, une tâche de surveillance ne serait pas exécutée si l’un des autres était resté bloqué.

Vous ne faites aucune mention du système d'exploitation, mais si une tâche de surveillance peut vérifier si une tâche n'a pas été archivée, il doit exister des canaux de communication distincts entre chaque tâche et l'agent de surveillance.

Vous devrez probablement modifier le chien de garde pour vider en quelque sorte le numéro de la tâche de celle qui n'a pas archivé et vider les blocs de contrôle des tâches et la mémoire afin de pouvoir effectuer un post-mortem. .

Selon le système d'exploitation, cela peut être facile ou difficile.

En fonction de votre système et de votre système d'exploitation, les approches peuvent être différentes. Une approche de très bas niveau que j'ai utilisée consiste à faire clignoter un voyant lorsque chacune des tâches est en cours d'exécution. Vous devrez peut-être placer une lunette sur les voyants pour pouvoir effectuer une commutation de tâche très rapide.

Pour un chien de garde régi par des interruptions, il vous suffit de faire en sorte que le sélecteur de tâches mette à jour le numéro de la tâche en cours d'exécution à chaque modification, ce qui vous permet d'identifier celui qui n'a pas donné.

Cependant, vous suggérez que vous avez vous-même écrit le chien de garde comme une tâche. Par conséquent, avant de redémarrer, le chien de garde peut sûrement identifier la tâche affamée? Vous pouvez stocker cette information en mémoire qui persiste au-delà d'un redémarrage à chaud ou l'envoyer via une interface de débogage. Le problème, c’est que la tâche affamée n’est probablement pas celle qui pose problème: vous voudrez probablement connaître les derniers commutateurs de tâche (et leur durée) afin d’en identifier la cause.

Une approche simpliste à l'arrière de la serviette ressemblerait à ceci:

int8_t wd_tickle[NUM_TASKS]

void taskA_main()
{
   ...
   // main loop
   while(1) {
     ...
     wd_tickle[TASKA_NUM]++;
   }
}

... tasks B, C, D... follow similar pattern

void watchdog_task()
{
   for(int i= 0; i < NUM_TASKS; i++) {
     if(0 == wd_tickle[i]) {
       // Egads! The task didn't kick us! Reset and record the task number
     }
    }
}

Comment votre système fonctionne-t-il exactement? J'utilise toujours une combinaison de chiens de garde logiciels et matériels. Laissez-moi vous expliquer ...

Mon exemple suppose que vous travaillez avec un noyau préemptif en temps réel et que vous avez un support de surveillance dans votre CPU / microcontrôleur. Ce chien de garde effectuera une réinitialisation s'il n'a pas été lancé au bout d'un certain temps. Vous voulez vérifier deux choses:

1) Le minuteur système périodique ("horloge RTOS") est en cours d'exécution (sinon, les fonctions telles que "veille" ne fonctionneraient plus et votre système serait inutilisable).

2) Tous les threads peuvent s'exécuter avec un délai raisonnable.

Mon RTOS (www.lieron.be/micror2k) offre la possibilité d'exécuter du code dans le gestionnaire d'interruptions d'horloge RTOS. C’est le seul endroit où vous actualisez le chien de garde matériel, vous êtes donc sûr que l’horloge fonctionne tout le temps (sinon, le chien de garde réinitialisera votre système).

Dans le thread inactif (toujours à la priorité la plus basse), un "chien de garde logiciel" " est rafraîchi. Il s’agit simplement de définir une variable à une certaine valeur (par exemple 1000). Dans l'interruption d'horloge RTOS (où vous lancez le chien de garde matériel), décrémentez et vérifiez cette valeur. S'il atteint 0, cela signifie que le thread inactif ne s'est pas exécuté depuis 1 000 horloges et que vous redémarrez le système (vous pouvez le faire en boucle indéfiniment dans le gestionnaire d'interruptions pour laisser le chien de garde matériel redémarrer).

Maintenant, répondez à votre question initiale. Je suppose que l'horloge système continue de fonctionner, c'est donc le chien de garde logiciel qui réinitialise le système. Dans le gestionnaire d’interruptions d’horloge RTOS, vous pouvez effectuer une "collecte de statistiques". au cas où la situation du chien de garde logiciel se produirait. Au lieu de réinitialiser le système, vous pouvez voir quel thread est en cours d'exécution à chaque tick d'horloge (après que le problème se soit produit) et essayer de savoir ce qui se passe. Ce n’est pas idéal, mais cela aidera.

Une autre option consiste à ajouter plusieurs chiens de garde de logiciels à des priorités différentes. Définissez VariableA sur 1000 pour le thread inactif et définissez la variable B sur un thread (moyenne) de priorité moyenne. Dans le gestionnaire d'interruptions d'horloge RTOS, vous vérifiez les deux variables. Avec cette information, vous savez si le thread en boucle a une priorité supérieure à "moyen". ou inférieur à "moyen". Si vous le souhaitez, vous pouvez ajouter un 3e ou 4e ou combien de chiens de garde de logiciels que vous aimez. Dans le pire des cas, ajoutez un chien de garde logiciel pour chaque priorité utilisée (cela vous coûtera cependant autant de threads supplémentaires).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top