TD et TP défaillances « temps réel »

I Cas d’étude

Nous allons considérer un véhicule dont la vitesse doit être asservie à une vitesse V_cmd. Ce véhicule est équipé d’un capteur de position. L’application que nous considérons est une application de contrôle de la trajectoire du véhicule. Cette application est constituée de quatre tâches fonctionnelles:

  • pos_sensor : cette tâche récupère la position courante du véhicule.
  • speed_cmp : à partir d’un tableau de positions successives dont on connaît la fréquence de mesure, cette tâche calcule la vitesse du véhicule.
  • obst_detect : cette tâche récupère la distance qui sépare le véhicule d’éventuels obstacles sur sa trajectoire.
  • traject_ctrl : cette tâche contrôle la trajectoire du véhicule en calculant les commandes à envoyer aux moteurs en fonction (i) de l’évolution de la vitesse, et (ii) de la présence d’obstacles sur la trajectoire.

II Etude théorique du problème.

L’ordonnancement considéré est RMS, et nous considérerons l’hypothèse deadline=période. 

Les Périodes des tâches sont

  • pos_sensor : 100 ms
  • speed_cmp : 1000 ms
  • obst_detect : 50 ms
  • traject_ctrl : 2000 ms

Les temps d’exécution des taches sont aléatoires dans un intervalle donné:

  • pos_sensor : [10, 45] (ms)
  • speed_cmp : [75,200] (ms)
  • obst_detect : [10,10] (ms)
  • traject_ctrl : [100, 200] (ms)

Vous pouvez vous servir de l’outil SIMSO (en version WEB) pour vous convaincre que cet oe jeu de tâche est ordonnançable. Vous pouvez saisir vous même les paramètres. Dans ce cas particulier (période toutes divisibles par 50), le test d’ordonnancement consiste à vérifier que le taux d’utilisation est inférieur à 1. On pourra aller dans les onglets « taches » pour vérifier le champ deadline_ok pour les différentes activations de chaque tâche.

Question 1 Quel est l’impact d’une défaillance de obst_detect faisant passer son WCET de 10 ms à 30 ms sur deux périodes consécutives à partir de la date 500 ms ? On pourra s’aider du tableau de temps de réponse des différentes tâches.

Question 2 En utilisant le fait que le test basé utilisation est dans ce cas exact, calculez l’allowance sous hypothèse de faute unique pour chaque tâche.

Question 3 Un ingénieur vous rappelle qu’EDF est un ordonnancer optimale pour mono-coeur et que donc son allowance devrait être plus élevée. Est il correcte dans ce cas de prétendre qu’elle serait strictement plus élevée ?

Question 4 En supposant que le dépassement d’échéance est le seul mécanisme présent sur notre plateforme, quelle est la latence de détection envisageable pour un budget de la tâche pos_sensor passant définitivement de 45ms à 65ms dès le départ de l’exécution ? (vous pouvez utiliser un argument formel ou une simulation adéquate).

III Dépassement d’échéance et watchdog

Nous vous fournissons le code de l’exemple ci-dessus ici. Dans le code fourni, la détection des dépassements d’échéance n’est pas implémentée. Seul le code correspondant au modèle initial est fourni. Cette archive contient les fichiers sources suivants:

  • main.c/.h: creation et initialisation des tâches fonctionnelles
  • threads_dispatch.c/.h: ensemble de fonctions pour l’implémentation de tâches périodiques
  • wdlibs.c/.h: ensemble de fonctions pour l’implémentation de la tâche watchdog
  • functions.c: code des fonctions de calcul/contrôle des tâches
  • types.h: définition des types utilisés dans main.c, threads_dispatch.c, et wdlib.c
  • periods.h: macros #define pour les périodes des tâches

Nous vous demandons ici de modifier le code fourni pour implémenter un watchdog logiciel qui se chargera de détecter qu’une tâche dépasse son échéance. Vous pouvez utiliser ce site pour l’exécution de votre code : ici. Nous suggérons l’implémentation suivante :

  • Au début de son exécution, une tâche fonctionnelle arme un timer auquel est associé un signal. A la fin de son exécution, la tâche fonctionnelle désarme ce timer. Un signal sig_watchdog doit être associé au timer de sorte que si il expire, l’OS émet ce signal.
  • Une tâche watchdog de très forte priorité attend sur la réception du signal sig_watchdog. Si toutes les tâches fonctionnelles terminent leurs travaux avant leurs échéances, le timer est désarmé et la tâche watchdog ne se réveille pas. Au contraire, si (au moins) une tâche fonctionnelle dépasse son échéance alors la tâche watchdog se réveillera. Reste à savoir laquelle, ou lesquelles pour journaliser cette information …

Exercice 1 : a) Le code correspond au cas où a pos_sensor a un temps d’exécution trop élevé (normalement sans entrainer de défaillance pour cette fonction). Observez la propagation de la faute aux autres tâches (augmentez légèrement les paramètres si nécessaire (pas plus de 75 ms pour pos sensor

b) Implémentez le mécanisme de watchdog dans wdlib et utilisez le dans main.c

Indications : .

Voici la liste des fonctions de (RT-)POSIX dont vous pourriez avoir besoin. sigwaitinfo, timer_create, timer_settime, timer_delete, sigemptyset, et sigaddset (voir le cours sur RT-POSIX).

Exercice 2 :

  1. Modifiez la signature et le contenu de void wd_recovery () de sorte de pouvoir afficher le PID du thread ayant dépassé son échéance (dans cette version chaque « thread » possède un PID différent.
  2. Modifiez la fonction wd_recovery en utilisant pthread_cancel() pour retirer la tâche du lot de tâche à ordonnancer.