TP2 : Xenomai
Documentation
-
les explications sur ce qu'est Xenomai, quels problèmes il résout, et comment il le fait sont ici https://source.denx.de/Xenomai/xenomai/-/wikis/home
-
Les API de Xenomai sont documentées ici : https://xenomai.org/documentation/xenomai-3/html/xeno3prm/index.html
Test de l'environnement
Après avoir démarré vos machine avec l'image Debian, placez vous dans le répertoire /usr/lib/xenomai
(peut être légèrement différent sur les machines de l'école) et cherchez un exécutable nommé latency
. Lancez cet exécutable avec les privilèges administrateur.
Si cela fonctionne, vous avez bien démarré le bon noyau, bravo.
Vous pouvez également essayer la commande dmesg | grep -i xenomai
pour vérifier que vous avez des sorties ressemblant à I-pipe: head domain Xenomai registered.
HelloWorld
-
Vous allez chercher dans la docs de Xenomai ou dans les répertoires de tests fournis comment écrire un programme très simple, qui lance une tâche à la plus haute priorité temps réel (99) pour afficher le message "Hello Real-time World", en utilisant
printf()
- au debut de votre main, ajoutez la ligne
mlockall( MCL_CURRENT | MCL_FUTURE );
afin de désactiver le mécanisme de swap mémoire sur disque pour votre application - création d'une tache avec
rt_task_create()
puis démarrage avecrt_task_start()
- ou bien les deux en même temps avec
rt_task_spawn()
rt_task_join()
dans le main après le démarrage de la tâche temps réel pour attendre sa terminaison.
- au debut de votre main, ajoutez la ligne
-
Pour compiler avec l'utilitaire make, vous allez avoir besoin d'un
makefile
un peu particulier. Reportez vous à la page https://source.denx.de/Xenomai/xenomai/-/wikis/Building_Applications_For_Xenomai_3 -
Testez, en cas de soucis, vérifiez que le répertoire
/usr/xenomai/lib
(!! à l'école ce n'est peut petre pas exactement ce répertoire ! adaptez !) se trouve bien dans les répertoires de recherche des librairies dynamiques (variableLD_LIBRARY_PATH
, sous bash, faites unecho $LD_LIBRARY_PATH
pour voir sa valeur et unexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:nouveau
pour ajouter le répertoire nouveau). -
Si ca ne marche pas, vérifiez que vous êtes super-utilisateur pour lancer l’application.
-
Si ca ne marche toujours pas, essayez avec le code et le makefile de cette archive
-
Proposez une autre version du programme, en utilisant
rt_printf
à la place deprintf
.
Changement de contexte et passage en mode secondaire
Modifier vos deux programmes pour que l'affichage soit fait dans une boucle infini avec une attente d'1s :
Tant que VRAI
affichage
attente 1s
Vous pouvez réaliser l'attente avec la fonction rt_task_sleep()
.
- Pour les deux versions du programmes, pendant qu'elles s'exécutent (pas en même temps !), testez dans un autre terminal les commandes suivantes :
ps -eTo pid,ppid,ucmd,class,rtprio,nice --sort class
cat /proc/xenomai/sched
- Expliquez les résultats obtenus.
- Vous pouvez vous aider de cette page https://dchabal.developpez.com/tutoriels/linux/xenomai/?page=page_7
- Regardez notamment les autres fichiers de
/proc/xenomai
Tâche périodique
Pour rendre une tâche périodique, deux choses :
-
Au début de la tâche, appeler
rt_task_set_periodic()
- astuce : une tâche peut obtenir un descripteur de type RT_TASK d'elle même avec la fonction
rt_task_self()
- pour gérer le temps, le type a utiliser est
RTIME
et des constantes sont définies comme par exempleTM_NOW
- astuce : une tâche peut obtenir un descripteur de type RT_TASK d'elle même avec la fonction
-
Entrer dans une boucle infini (prévoyez dans la phase de debug de ne rentrer dans la boucle que 3 ou 4 fois...). Un passage dans la boucle correspond alors à une instance ou un job. Au début de la boucle, appeler la méthode bloquante
rt_task_wait_period()
: c'est elle qui va provoquer la suspension de la tâche jusqu’à sa prochaine activation périodique. -
Tester en faisant une tache qui affiche toutes les secondes le temps courant et la durée écoulée depuis le dernier affichage (voir fonction
rt_timer_read()
. Vérifiez empiriquement la précision de l'activation. -
générez maintenant un coût de 0,8s pour cette tâche grâce à la fonction
rt_timer_spin()
-
observez ce qu'il se passe si vous descendez la période à 0,5s en gardant le coût à 0,8
-
utilisez le paramètre de
rt_task_wait_period()
pour afficher le compteur de dépassement proposé par xenomai. Expliquez comment il fonctionne (si il fonctionne).
Influence de la charge système
- Ecrivez une tache périodique de période 1 ms qui affiche la durée écoulé entre deux activations périodiques en nanosecondes
- Exécutez le programme en redirigeant la sortie vers un fichier pendant quelques secondes (
a.out > fichier.log
par exemple) - Télécharger le code de calc-stat.c et compilez le (avec la librairie mathématique, option -lm de gcc). Ce programme permet de calculer le minimum, la moyenne et l’écart type d’une grandeur se trouvant dans un fichier.
- utilisez le pour obtenir des stats sur le fichiers de résultat obtenu précédemment :
cat fichier.log > ./calc-stat
- refaites l'expérience mais en faisant tourner en parallèle la commande dohell fournie dans les répertoires de xenomai (commande qui génère de la charge parasite)
Mon système de tâche !
Proposez un programme qui lit les fichiers de descriptions de système de taches tel que défini au TP1 et lance les taches périodiques correspondantes (utilisez rt_timer_spin()
) pour simuler les coûts.