6
votes

Programmation en présence de WatchDog Timer

Je suis nouveau dans la programmation des systèmes embarqués, même si j'ai eu des cours pendant des études, la programmation pratique est toujours un peu plus éloignée.

Voici le problème: je dois programmer un petit système sur le microcontrôleur NXP LPC2103 (Bras 7 basé), sans système d'exploitation. Il a une minuterie de surveillance qui doit être régulièrement mise à jour. Le système dispose d'un modem GPRS avec TCP / IP Stack intégré et l'initialisation de cela prend du temps plus de temps que le guichet de surveillance doit faire le temps. Lorsque j'appelle la fonction d'initialisation, le système réinitialise.

J'ai parlé à un collègue plus expérimenté et il a suggéré que je dois quitter et rentre la même fonction d'initialisation de la fonction principale dans laquelle je mords la minuterie de surveillance si longtemps jusqu'à ce que la fonction termine l'exécution. L'idée semble bonne, mais j'aimerais également entendre d'autres expériences. En outre, une référence (livre ou site Web) pourrait également être utile, car je ne pouvais trouver rien de spécifique à cela.

Je ne voudrais pas appeler la minuterie de surveillance de la fonction d'initialisation, je ne trouve pas ce bien.


4 commentaires

Salut. Je ne peux pas répondre précisément à votre question, mais voici un excellent site Web sur la conception / la programmation du système en temps réel et intégré: eventHelix. com / realtimemantra


En règle générale, vous vous référez à la réinitialisation de la minuterie de surveillance (compter vers le bas) sur caresser ou chatouillettes le chien de garde. Lorsque le chien de garde est hors du temps, il morsure (c'est un chien, et les chiens peuvent mordre) et réinitialiser généralement le matériel sur des systèmes embarqués.


@Negoose - chez ma compagnie, nous kick le chien de garde.


@Ashelly: Mauvais chien de garde.


5 Réponses :


6
votes

Généralement, il y a deux approches que j'ai adoptées pour cette situation.

Initialisation de la machine d'état

Le premier est grand que votre collègue a suggéré: Mise en œuvre des routines d'initialisation d'une machine à états appelée dans la boucle principale, puis arrêtez d'appeler les routines d'initialisation et commencez à appeler les routines principales.

Ceci est une fonction simple et propre, mais peut être un peu maladroite lorsqu'il s'agit de processus longs particuliers tels que le démarrage d'un oscillateur basse fréquence.

Gestion de surveillance de WatchDog ISR limitée

Il existe une autre alternative si vous avez un "systceau" ou une interruption équivalente, par exemple une interruption qui est tirée tous les 1 ms. Dans cette situation, vous pouvez envisager de nourrir le chien de garde (par exemple) tous les 50 appels de l'interruption, mais limitant le nombre de fois que le chien de garde est introduit pour assimiler au maximum autorisé les routines d'initialisation à compléter. Il est alors généralement nécessaire (si vous le souhaitez, comme vous le souhaitez, un chien de garde fenêtré) pour avoir une courte boucle de synchronisation à la fin de l'initialisation afin de vous assurer que le chien de garde n'est pas alimenté avant que la fenêtre minimale soit atteinte, Mais cela est trivial à mettre en œuvre.

Ceci est une solution assez propre (car elle ne rend pas les routines d'initialisation en une machine à états inutiles) et traite des problèmes d'une suspension de routine d'initialisation. Il est toutefois très important que la limite sur WatchDog appelle dans l'ISR est appliquée.

Discussion

Les deux ont leurs avantages et leurs inconvénients, mais il est utile d'avoir des approches différentes pour différentes exigences. J'ai tendance à préférer la dernière solution où j'ai des choses comme un oscillateur basse fréquence (qui peut prendre un certain temps à démarrer) car elle évite de sur-compliquer les routines d'initialisation, ce qui peut être suffisamment compliqué!

Je suis sûr que d'autres offriront d'autres idées de remplacement ...


1 commentaires

Une bonne chose à propos de «Aide-logiciels» à propos des approches de surveillance «Software-assistée», telles que ceci, c'est que si l'une ait une valeur de code 32 bits , on peut avoir une valeur réinitialiser et réinitialiser chaque fois que Code> (non signé) (réinitialiser_time-courant_time) dépasse une valeur maximale. Le code peut alors essayer de garder principalement réinitialiser_time très proche du actuel_time , mais avant de faire quelque chose de consommer de temps suffisamment à l'avance pour éviter une réinitialisation inattendue.



4
votes

Le chien de garde de la LPC2103 est hautement personnalisable. Vous avez de nombreuses options pour le contrôler:

Vous pouvez ne pas l'activer jusqu'à ce que votre séquence d'initialisation soit terminée.

Vous pouvez prolonger la période entre les aliments très longs.

La question est de savoir à quoi utilisez-vous le chien de garde?

S'il est utilisé pour vérifier si votre logiciel fonctionne bien et non gelage, je ne vois pas comment l'option ISR de AI vous aidera (ISR peut continuer à travailler même que votre programme est bloqué).

Pour plus de détails sur WatchDog Options Voir WatchDog Timer (WDT) Chapitre (17) dans le manuel d'utilisation de votre MCU. http://www.nxp.com/documents/user_manual/um10161.pdf


3 commentaires

Changer la période de la DEO est une option viable. Et Al a souligné que vous devez limiter les mises à jour de la WD dans la routine d'interruption à un certain nombre de fois pour éviter de ne pas détecter une routine d'initiale suspendue


1. LPC2103 n'a pas de fenêtre minimale pour alimenter le chien de garde, de sorte que vous puissiez limiter la période de sauvegarde des ressources du processeur mais ne pas avoir à le faire. 2. Comment vérifiez-vous les routines suspendues à l'ISR? Comment nourrir le chien de garde d'ISR est utile?


1. Si vous pouvez étendre la période de DEU à une durée suffisante, vous n'utiliserez pas la méthode ISR. L'utilisation d'une ISR pour prolonger artificiellement la période de la DEO est une option disponible sur la plupart des MCU- Cette solution est générale et peut-être pas nécessaire dans LPC2103 pour la tâche donnée 2. Vous ne pouvez pas vérifier les routines suspendues. Mais vous pouvez limiter l'ISR pour réinitialiser le WD uniquement un nombre fixe de fois (comme 100 fois), puis la laisser expirer.



1
votes

Vous pouvez reconsidérer où dans le code, la minuterie WD est desservie.

Typiquement, la minuterie WD doit être service pendant le temps d'inactivité (boucle inactive ou tâche inactive) et dans les pilotes de niveau les plus bas (par exemple, lorsque vous lisez / écrivez du modem GPRS ou du Mac pour votre connexion TCP / IP , etc.).

Si cela ne suffit pas, votre firmware peut également ne rien faire mais brûler des cycles de processeur dans une routine de retard. C'est une amende pour ajouter un service de minuterie WD ici, mais vous devrez peut-être régler votre minuterie de retard pour tenir compte du temps de service de WD.

Si votre application dispose simplement de nombreuses tâches intensives de la CPU qui prennent plus de temps pour exécuter que la période de minuterie de WD permet, vous pourriez envisager de rendre l'intervalle de minuterie de WD un peu plus longtemps. Cela peut ne pas toujours être possible, mais j'aime garder les références de minuterie de WD hors des couches supérieures du micrologiciel afin de conserver la couche d'application aussi portée que possible. Les minuteries WD sont généralement dépendantes du matériel. Par conséquent, toutes les références de minuterie de WD dans votre code sont rarement portables. Les pilotes de basse niveau sont rarement portables de toute façon, de sorte que cela constitue généralement un meilleur endroit pour servir une minuterie de WD.


0 commentaires

7
votes

Je ne voudrais pas appeler la minuterie de surveillance de la fonction d'initialisation, je ne trouve pas ce bien. P>

Cela pourrait être surchargé pour cette situation, mais une technique générale que j'ai utilisée pour les opérations de course à longueurs où vous voudrez peut-être effectuer d'autres travaux consiste à utiliser la fonction de fonctionnement à long terme accepter un pointeur de fonction de rappel qui sera appelé périodiquement. Le modèle que j'utilise habituellement est d'avoir un prototype de rappel pouvant ressembler à: p>

int watchdog_callback( void* progress, void* context)
{
    kick_the_watchdog();

    return 0;  // zero means 'keep going...'
}


void init_modem( callback_t pCallback, void* callback_context)
{
    // do some stuff

    pCallback( 0, callback_context);

    // do some other stuff

    pCallback( 1, callback_context);


    while (waiting_for_modem()) {
         // do work...

         pCallback( 2, callback_context);
    }    
}

1 commentaires

+1 Des motifs tels que ceci sont fondamentalement un moyen d'émuler des avantages de C ++ sur C. Qu'est-ce qui est également génial de cette abstraction, c'est que vous pouvez utiliser la composition pour joindre plusieurs gestionnaires de rappels à cette fonction, sans qu'il soit nécessaire de modifier tout code du tout. Par exemple, votre fonction de rappel pourrait lui-même invoquer une liste d'autres pointeurs de fonction, l'une d'entre elles de frapper le chien de garde, l'autre mise à jour de la barre de progression d'affichage, etc.



3
votes

Les horlogements sont superbes, mais aussi une douleur à l'arrière lorsque votre programme ou votre système ne l'adapte pas facilement. Le travail meilleur lorsque vous avez du code qui a l'air (généralement) comme: xxx pré>

Très souvent, vous pouvez concevoir votre programme de manière à ce que cela fonctionne, et c'est généralement une preuve très trompeuse (mais pas Totalement). P>

Mais dans des cas comme la vôtre, cela ne fonctionne pas si bien. Vous finissez par avoir à concevoir et à créer (ou éventuellement utiliser une bibliothèque) un cadre qui dispose de diverses conditions qui doivent être remplies ce contrôle si / lorsque le chien de garde est fait piété. Cela peut être très délicat, cependant. La complexité de ce code pourrait elle-même introduire ses propres erreurs. Vous pouvez très bien écrire une application parfaite à l'exception de la framework WatchDog et votre projet peut réinitialiser beaucoup ou que tout votre code pourrait être mauvais et tout simplement pour animaux de garde de garde, ce qui lui faisait ne jamais réinitialiser. P>

un Un bon moyen de changer le code ci-dessus pour gérer des situations plus complexes serait de modifier les fonctions Subsystemx_work pour suivre l'état de l'état. Cela peut être fait avec des variables statiques dans les fonctions ou en utilisant des pointeurs de fonction plutôt que des fonctions et modifier la fonction réelle exécutée pour refléter l'état actuel de ce sous-système. Chaque sous-système devient une machine à états. P>

Une autre façon de faire fonctionner autour de longues attentes intentionnelles avec un chien de garde à mordre rapide consiste à rompre la fonction longue course en morceaux plus courts. Plutôt que: p> xxx pré>

vous pouvez faire: p> xxx pré>

puis étendre ceci pour étirer la minuterie de surveillance en faisant:

int x;
fscanf(input, "%i", x); // Passed uninitialized x rather than address of x


0 commentaires