ITR : Sujets de travaux pratiques

Cette page présente les sujets de travaux pratiques à réaliser dans le cadre de l’option Informatique Temps-Réel. Le texte de ces derniers est volontairement très bref. On se référera à la documentation pour l’API OSEK/VDX, le format des fichiers OIL et l’interface de gestion des capteurs/actionneurs du NXT

Les séances sont découpées en 2 parties: la partie découverte, la partie projet. La 1ère a pour but, comme son nom l’indique, de vous faire découvrir la brique Nxt et les outils utiles. Le projet, quant à lui, a pour but de vous mettre en situation réelle de conception et développement de systèmes avec contraintes de temps.

Avant-propos

Des scripts ont été mis en place afin de faciliter la création et la compilation de programmes pour les briques Nxt. Leur utilisation dans un terminal requiert l’initialisation de ce dernier par le biais de la commande suivante :

source /share/m1info/ITR/env_setup

Le script env_setup ne fonctionne que pour des shells bash. Si vous utilisez tcsh par exemple, il faudra initialiser votre environnement différemment.

Pour créer un nouveau programme, le compiler et l’envoyer sur une brique Nxt:

nxt_create [project]
cd [project]
nxt_goil [project].oil
make
nxt_send [project]_exe.rxe

nxt_create permet de créer un dossier contenant un fichier source C prêt à l’emploi et le fichier OIL correspondant.
nxt_goil fournit le fichier OIL à trampoline pour générer un Makefile et d’autres fichiers de l’application.
nxt_send envoie un fichier sur une brique branchée en USB, en l’occurrence un exécutable.

 make > /dev/null (pour ne voir que les messages d’erreur sur la sortie standard)

Découverte — 3 séances

L’objectif de ce premier TP est de prendre en main le système d’exploitation OSEK/VDX. Plus particulièrement, il vise à vous familiariser avec l’édition simultanée de la description du système, dans le fichier OIL, et son implémentation dans le fichier source correspondant. À cette fin, vous allez manipuler les fonctions de gestion de tâches d’OSEK/VDX (affichage, gestion de priorité, évènement …) et les hooks OSEK/VDX.

Il est conseillé de profiter de ce premier TP pour préparer une petite librairie facilitant l’affichage de messages successifs sur des lignes différentes. L’interface de gestion de l’écran de la brique ne fournit en effet de base que le positionnement du curseur et l’ajout de texte ou de valeurs entières après ce dernier.

API OSEK/VDX utilisée (voir documentation OSEK/VDX) : display_*, *Hook, GetTaskID, *Task, *Event

Hello World!

Dans un premier temps, toutes les tâches ont la même priorité, et seront sporadiques.

Q1: En utilisant PreTaskHook, PostTaskHook, et GetTaskID, lancer au démarrage du système une tâche task0 qui affiche son identifiant unique et indique sur l’écran du Nxt qu’elle s’exécute. Exemple d’affichage:

Task0 : PreTaskHook
Task0 : Hello World !
Task0 : PostTaskHook

NB : Certains évènements PreTaskHook et PostTaskHook sont déclenchés par la tâche idle du système, dans ces cas, GetTaskID fournit la valeur -1.

Q2: Ajouter une tâche task1 activée par task0 (ActivateTask), qui en plus de ses informations de lancement affichera l’heure du système. Ex:

Task0 : PreTaskHook
Task0 : Hello World!
Task0 : PostTaskHook
Task1 : PreTaskHook
Task1 : 42 ms
Task1 : PostTaskHook

NB: Evidemment, vous adapterez l’exemple d’affichage pour que ce soit lisible compte-tenu du nombre de lignes disponibles sur la brique.

Q3: Ajouter une tâche task2, activée au démarrage, qui affichera un message avant d’enchaîner sur la tâche task3 (ChainTask), qui, elle, viendra en complément afficher l’heure.

Que constatez-vous/déduisez-vous sur l’ordre de lancement des tâches en fonction de la manière dont elles sont activées? Si vous rajoutez un petit temps d’attente dans la task0 et/ou task1, ou encore dans le couple 2/3, l’ordre reste t-il le même ? Quid des hooks ?

Q4: Ajouter une dernière tâche task4 qui attendra un évènement, lequel sera lancé après appuie sur la touche “flèche droite”.

Q5: Vous pouvez jouer avec les priorités et les périodicités afin d’en apprendre un peu plus sur leur fonctionnement et leurs effets.

Aller, on joue!

Vous réaliserez 2 versions distinctes de cet exercice, l’une avec des alarmes absolues (dans le fichier oil), l’autre avec des alarmes relatives (dans le source).

Ce deuxième TP a pour objectif de vous faire découvrir l’ordonnancement de tâches, la notion de ressources OSEK et quelques uns des problèmes liés comme l’inversion de priorité.

Dans un premier temps, toutes les tâches ont la même priorité, l’ordonnancement est préemptif.

Construire une application composée des trois tâches suivantes et d’une variable partagée distance. La variable liée à distance indiquera la distance du pare-chocs du robot aux obstacles l’entourant.

  • Détection_contact : tâche périodique de période 100 ms mettant distance à 0 quand le pare-chocs est en contact avec un obstacle
  • Détection_distance : tâche périodique de période 300 ms mettant distance à jour à partir du résultat du capteur ultrason
  • Navigation : tâche périodique de période 200 ms qui selon la valeur de distance entreprend les actions suivantes :
    • Distance = 0 : marche arrière du robot
    • Distance < 50 : faire tourner le robot (pour éviter l’obstacle)
    • Par défaut : toutes les 10 périodes, changement du cap du robot (virage à droite ou à gauche d’un angle aléatoire avant de continuer tout droit)

Vous afficherez sur la 1ère ligne de l’afficheur, le temps système et la valeur de la distance. Puis sur les lignes suivantes, le défilement des lancements/arrêts des tâches.

Que se passe-t-il si les pare-chocs détectent un obstacle à ras de terre mais que le capteur ultrason est interrogé avant que la tâche de navigation ne s’exécute ? Proposer une modification du système pour pallier à ce problème.

NB : On n’oublie pas la règle d’or des applications multi-tâches : Tout accès à une variable partagée doit être protégé en lecture et en écriture par une section critique. Pour cela vous pourrez utiliser une ressource particulière qui bloque temporairement le mode préemptif de l’ordonnanceur, cf. doc.

Et la théorie dans tout ça ?

Dans l’exercice précédent, nous avons utilisé les mêmes priorités pour chaque tâche. Question de rhétorique, mais pensez-vous que ce fût un choix judicieux ? Dans ce 3ème exercice vous avez en charge de construire un petit visualisateur d’ordonnancement. Celui-ci permettra de générer un fichier SVG qui présentera l’ordonnancement de l’exercice précédent. Au choix, il devra pouvoir générer des ordonnancements suivant les politiques RM ou EDF vues en cours, en version préemptive et non-préemptive.

Pour ce faire, vous aurez besoin de plusieurs informations initiales dont le WCET de chaque tâche, leur priorité et l’hyperpériode. Hormis le WCET, vous êtes en mesure de déterminer/calculer ces informations. Attention aux éventuelles inversions de priorités qui devront être gérées avec le système PCP (aussi vu en cours).

Pour le WCET, nous vous proposons d’utiliser l’outils développé dans notre équipe depuis maintenant des décennies, le bien nommé : Heptane. Pour cela vous devez créer 2 fichiers de configuration et un fichier d’annotation (cf la documentation d’Heptane ou juste lire la section Specificitiés d’Heptane avec NXT et Trampoline -à lire impérativement avant de lancer les commandes HeptaneExtract et HeptaneAnalysis-). L’estimation du WCET est une approximation du pire cas réel, pour simplifier notre analyse tout en restant sûr, nous ne prendrons pas en compte les détails de la mirco-architecture de la brique ; i.e. pas de cache, pas de pipeline.

cd DOSSIER_PROJET
cp /share/m1info/ITR/heptane/configExtract.xml .
cp /share/m1info/ITR/heptane/configAnalysis.xml .

Avant de lancer HeptaneExtract et HeptaneAnalysis mettez à jour les fichier configExtract_ARM.xml et configAnalysis_ARM.xml avec les bons paramètres d’entrées (nom de votre source, nom de votre executable, et le nom de votre cfg final).

HeptaneExtract -v configExtract_ARM.xml
HeptaneAnalysis -t configAnalysis_ARM.xml

Que constatez-vous lors de l’utilisation d’Heptane ?

NB: On réduira artificiellement les périodes si l’on ne voit rien sur l’ordonnancement.

Specificitiés d’Heptane avec NXT et Trampoline

L’analyse statique d’une application NXT et Trampoline est très délicate et nécessite l’utilisation de quelques hacks et configurations spécifiques. Voici ce qu’il faut savoir pour l’extraction:

  • Le binaire envoyé à la brique est le “*_exe.rxe” file, cependant ce fichier n’est plus un fichier ELF, il a été modifié par la chaîne d’outils de compilation de NXT & Trampoline. Alors pour analyser statiquement votre programme, vous devrez utiliser le fichier EFL original “*_exe” à la place..
  • Faites attention aux “flags” de compilation que vous utilisez, les outils WCET ne sont pas admirateurs des optimisations de compilateur trop agressives. Par exemple, vous devriez utiliser “-O0” et seulement les “flags” de compilation nécessaires. De même, les “flags” de débogage tels que “-g” ajoutent des informations dans le code d’assemblage qui perturberont la chaîne d’outils Heptane. Exemple d’un fichier goil compatible à l’analyse de WCET:
    CFLAGS = "-c -ffreestanding -fsigned-char -mcpu=arm7tdmi -O0 -Wall -Werror-implicit-function-declaration -ffunction-sections -fdata-sections -std=gnu99";
    
    ASFLAGS = "-mcpu=arm7tdmi --fatal-warnings";
    
    LDFLAGS = "-O0 --allow-multiple-definition --gc-sections";
    
    LDFLAGS = "-L/share/m1info/ITR/osek_env/arm-elf//lib/gcc/arm-elf/4.5.1/ -lgcc -L/share/m1info/ITR/osek_env/arm-elf//arm-elf/lib -lc";
  • Il vous manquera certaines informations telles que les limites des boucles et d’autres éléments. Nous vous conseillons vivement d’utiliser notre fichier d’annotation disponible à /share/m1info/ITR/trampoline-annot.xml ; Il contient les bornes de boucle requises, quelques WCET pour les fonctions de bibliothèque que vous ne pouvez pas trouver par vous-même et les alias de fonction que les Osek/VDX & Trampoline utilisent.
  • Nous n’utiliserons aucune spécificité de l’architecture ARM, comme les caches, pour faciliter l’analyse WCET. Cela créera un WCET pessimiste, mais qui sera tout de même sûr.
  • Rappelez-vous que vous avez besoin du WCET pour toutes les tâches de votre système.
  • Faites attention à l’appellation du nom CFG dans le fichier d’annotation lorsque vous donnez des informations sur le flux de contrôle. Dans votre fichier source C, vous pouvez avoir une tâche nommée “toto”. Dans le fichier binaire, cette tâche est renommée “toto_function”. Il en sera de même dans les CFGs qu’Heptane extraira du binaire.

Le projet — (4 séances + 1 séance tournoi)

Nul vainqueur ne croit au hasard (Nietzsche)

Il est temps de juger vos capacités de réalisation de systèmes temps-réel. Pour cela, nous organisons un grand tournoi : The Wall-e Tournament ; (parce que ça sonne toujours mieux en anglais), on se limitera à une course par équipe par manque de temps.

Votre robot devra se mouvoir sur un parcours délimité par des parois. Au départ, le robot sera placé face à un mur, puis il devra trouver son chemin sur un circuit aléatoirement constitué jusqu’à l’arrivée. Celle-ci sera matérialisée par l’impossibilité pour le robot de trouver une direction dans laquelle se diriger (excepté celle d’où il vient, autrement dit un “cul de sac” –> message que le dit robot devra afficher lorsqu’il l’aura atteint, le cul de sac). Vous serez juger non seulement sur la capacité du robot à atteindre l’arrivée, mais aussi sur ses aptitudes à ne pas détériorer le circuit ainsi que sur sa rapidité de parcours du circuit.

Tous les outils et cours précédemment présentés sont à votre disposition. Seul les robots vous sont prêtés les jours de séance de TPs et du grand tournoi.

Afin de vous attribuer une note d’examen pratique, vous devrez rendre un rapport (1er tiers de la note) comprenant l’ordonnancement que vous avez souhaité mettre en place (et toutes les informations annexes nécessaires à sa génération). Nous organiserons une session de compétition pendant laquelle un jury d’experts attestera de la qualité de votre performance (2ème tiers de la note). Un prix d’une valeur inestimable sera remis au vainqueur du tournoi. Enfin pour compléter le 3ème tiers de votre note d’examen pratique, vous devrez nous remettre le code final (*.c, *.oil) de votre application. Ce rendu se fera par mail à la fin du tournoi.

Les règles du grand tournoi

    • Le tirage de départ pour l’ordre des courses est aléatoire et réalisé une main innocente.
    • Le jury se réserve le droit de décider du parcours initial, et de le changer entre les courses.

  • A l’appel de l’équipe sur la piste, le robot sera placé sur la ligne de départ.
  • Tout retard sur la ligne de départ entraine une disqualitification (même et surtout pour problème de compilation, retard dans l’upload du fichier, etc …).
  • Déplacer un mur entraîne une pénalité de 1 seconde par centimètre
  • Défoncer (déplacer de plus de 15cm) un mur entraîne une disqualification.
  • Si le robot n’arrive pas à la fin du parcours soit parce qu’il est bloqué au milieu, soit parce qu’il fait des aller-retours ou toutes autres situations de ce genre entraine la disqualification. Le jury se réserve le droit de décision quant au moment où le robot est considéré bloqué.
  • Si une règle a été oubliée, le jury se réserve le droit de l’ajouter sur le vif.

Remarques

  • Vous vous êtes déjà rendus compte que le capteur ultrason n’était pas très précis. Utilisez un livre ou une feuille de carton pour tester vos programmes, cela devrait stabiliser les résultats.
  • Notez qu’il faut un temps minimum au capteur ultrason pour stabiliser ses résultats. L’expérience montre que des lectures espacées de moins de 100ms dégradent la qualité des résultats.
  • Une stratégie élégante pour choisir la vitesse du robot consiste à choisir une valeur proportionnelle à la différence entre la distance mesurée et la distance souhaitée. En théorie du contrôle, on appelle ça un contrôleur proportionnel (ou “P-contrôleur”). Les élèves intéressés pour approfondir cet aspect pourront essayer d’implémenter un PID complet.

Pour aller plus loin

Les applications développées dans le cadre de ces travaux ne font qu’effleurer les mécanismes proposés dans la spécification OSEK/VDX avec notamment les alarmes, les tâches, les ressources et les évènements. Vous pouvez expérimenter d’autres outils de base comme les points d’ordonnancement (avec la fonction Schedule en mode non-préemptif), la notion de messages et de boîte aux lettres, les AlarmCallbacks ou les extensions comme les tables d’ordonnancement.

Comments are closed.