Pierre Ficheux (pierre.ficheux@openwide.fr) avec la participation de Patrice Kadionik (kadionik@enseirb.fr) Janvier 2006 Version modifie en mars 2006 pour publication Internet
Rsum
Cet article est une mise jour du dossier Temps rel sous Linux paru en juillet 2003 dans le numro 52 de Linux Magazine. Aprs une dfinition des concepts lis au temps rel, nous nous attacherons dcrire les solutions Linux disponibles en insistant particulirement sur le composant XENOMAI 2. La lecture et la mise en application des exemples dcrits ncessite une bonne connaissance systme de Linux en particulier sur la compilation du noyau. Les codes source des programmes prsents sont disponibles sur http://pficheux.free.fr/articles/lmf/hs24/realtime/hs24_test.tgz
La gestion du temps est l'un des problmes majeurs des systmes d'exploitation. La raison est simple : les systme d'exploitation modernes sont tous multitche, or ils utilisent du matriel bas sur des processeurs qui ne le sont pas, ce qui oblige le systme partager le temps du processeur entre les diffrentes tches. Cette notion de partage implique une gestion du passage d'une tche l'autre qui est effectue par un ensemble d'algorithmes appel ordonnanceur (scheduler en anglais). Un systme d'exploitation classique comme Unix, Linux ou Windows utilise la notion de temps partag, par opposition au temps rel. Dans ce type de systme, le but de l'ordonnanceur est de donner l'utilisateur une impression de confort d'utilisation tout en assurant que toutes les tches demandes sont finalement excutes. Ce type d'approche entrane une grande complexit dans la structure mme de l'ordonnanceur qui doit tenir compte de notions comme la rgulation de la charge du systme ou la date depuis laquelle une tche donne est en cours d'excution. De ce fait, on peut noter plusieurs limitations par rapport la gestion du temps. Tout d'abord, la notion de priorit entre les tches est peu prise en compte, car l'ordonnanceur a pour but premier le partage quitable du temps entre les diffrentes tches du systme (on parle de quantum de temps ou tick en anglais). Notez que sur les diffrentes versions d'UNIX dont Linux, la commande nice permet de modifier la priorit de la tche au lancement. Ensuite, les diffrentes tches doivent accder des ressources dites partages, ce qui entrane des incertitudes temporelles. Si une des tches effectue une criture sur le disque dur, celuice n'est plus disponible aux autres tches un instant donn et le dlai de disponibilit du priphrique n'est pas prvisible. En outre, la gestion des entres/sorties peut gnrer des temps morts, car une tche peut tre bloque en attente d'accs un lment d'entre/sortie. La gestion des interruptions reues par une tche n'est pas optimise. Le temps de latence - soit le temps coul entre la rception de l'interruption et son traitement - n'est pas garanti par le systme. Enfin, l'utilisation du mcanisme de mmoire virtuelle peut entraner des fluctuations 1
Le cas des systmes temps rel est diffrent. Il existe un grande nombre de dfinition d'un systme dit temps rel mais une dfinition simple d'un tel systme pourra tre la suivante : Un systme temps rel est une association logiciel/matriel o le logiciel permet, entre autre, une gestion adquate des ressources matrielles en vue de remplir certaines tches ou fonctions dans des limites temporelles bien prcises. Un autre dfinition pourrait tre : "Un systme est dit temps rel lorsque l'information aprs acquisition et traitement reste encore pertinente". Ce qui signifie que dans le cas d'une information arrivant de faon priodique (sous forme d'une interruption priodique du systme), les temps d'acquisition et de traitement doivent rester infrieurs la priode de rafrachissement de cette information. Il est vident que la structure de ce systme dpendra de ces fameuses contraintes. On pourra diviser les systmes en deux catgories : Les systmes dits contraintes souples ou molles (soft real time). Ces systmes acceptent des variations dans le traitement des donnes de l'ordre de la demi-seconde (ou 500 ms) ou la seconde. On peut citer l'exemple des systmes multimdia : si quelques images ne sont pas affiches, cela ne met pas en pril le fonctionnement correct de l'ensemble du systme. Ces systmes se rapprochent fortement des systmes d'exploitation classiques temps partag. Ils garantissent un temps moyen d'excution pour chaque tche. On a ici une rpartition galitaire du temps CPU aux processus. 2. Les systmes dits contraintes dures (hard real time) pour lesquels une gestion stricte du temps est ncessaire pour conserver l'intgrit du service rendu. On citera comme exemples les contrles de processus industriels sensibles comme la rgulation des centrales nuclaires ou les systmes embarqus utiliss dans l'aronautique. Ces systmes garantissent un temps maximum d'excution pour chaque tche. On a ici une rpartition totalitaire du temps CPU aux tches.
1.
Les systmes contraintes dures doivent rpondre trois critres fondamentaux : 1. Le dterminisme logique : les mmes entres appliques au systme doivent produire les mmes effets. 2. Le dterminisme temporel : un tche donne doit obligatoirement tre excute dans les dlais impartis, on parle d'chance. 3. La fiabilit : le systme doit tre disponible. Cette contrainte est trs forte dans le cas d'un systme embarqu car les interventions d'un oprateur sont trs difficiles ou mme impossibles. Cette contrainte est indpendante de la notion de temps rel mais
la fiabilit du systme sera d'autant plus mise l'preuve dans le cas de contraintes dures. Un systme temps rel n'est pas forcment plus rapide qu'un systme temps partag. Il devra par contre satisfaire des contraintes temporelles strictes, prvues l'avance et imposes par le processus extrieur contrler. Une confusion classique est de mlanger temps rel et rapidit de calcul du systme donc puissance du processeur (microprocesseur, micro-contrleur, DSP). On entend souvent : tre temps rel, c'est avoir beaucoup de puissance: des MIPS voire des MFLOPS Ce n'est pas toujours vrai. En fait, tre temps rel dans l'exemple donn prcdemment, c'est tre capable d'acquitter l'interruption priodique (moyennant un temps de latence d'acquittement d'interruption impos par le matriel), traiter l'information et le signaler au niveau utilisateur (rveil d'une tche ou libration d'un smaphore) dans un temps infrieur au temps entre deux interruptions priodiques conscutives. On est donc li la contrainte dure entre deux interruptions gnres par le processus extrieur contrler. Si cette dure est de l'ordre de la seconde (pour le contrle d'une raction chimique par exemple), il ne sert rien davoir un systme base de Pentium IV ! Un simple processeur 8 bits du type microcontrleur Motorola 68HC11 ou Microchip PIC ou mme un processeur 4 bits fera amplement l'affaire, ce qui permettra de minimiser les cots sur des forts volumes de production. Si ce temps est maintenant de quelques dizaines de microsecondes (pour le traitement des donnes issues de l'observation d'une raction nuclaire par exemple), il convient de choisir un processeur nettement plus performant comme un processeur 32 bits Intel x86, StrongARM ou Motorola ColdFire. L'exemple donn est malheureusement idyllique (quoique frquent dans le domaine des tlcommunications et rseaux) puisque notre monde interagit plutt avec un systme lectronique de faon apriodique. Il convient donc avant de concevoir ledit systme de connatre la dure minimale entre 2 interruptions, ce qui est assez difficile estimer voire mme impossible. Cest pour cela que lon a tendance concevoir dans ce cas des systmes performants (en terme de puissance de calcul CPU et rapidit de traitement dune interruption) et souvent sur-dimensionns pour respecter des contraintes temps rel mal cernes priori. Ceci induit en cas de sur-dimensionnement un sur-cot non ngligeable. En rsum, on peut dire qu'un systme temps rel doit tre prvisible (predictible en anglais), les contraintes temporelles pouvant s'chelonner entre quelques micro-secondes (s) et quelques secondes.
L'exprience dcrite sur la figure ci-dessous met en vidence la diffrence entre un systme classique et un systme temps rel. Elle est extraite d'un mmoire sur le temps rel ralis par William Blachier l'ENSIMAG en 2000.
Le but de l'exprience est de gnrer un signal priodique sortant du port parallle du PC. Le temps qui spare deux missions du signal sera mesur l'aide d'un compteur. Le but est de visualiser l'volution de ce dlai en fonction de la charge du systme. La frquence initiale du signal est de 25 Hz (Hertz) ce qui donne une demi-priode T/2 de 20 ms. Sur un systme classique, cette demi-priode varie de 17 23 ms, ce qui donne une variation de frquence entre 22 Hz et 29 Hz. La figure ci-dessous donne la reprsentation graphique de la mesure sur un systme non charg puis pleine charge :
Sur un systme temps rel, la demi-priode varie entre 19,990 ms et 20,015 ms, ce qui donne une variation de frquence de 24,98 Hz 25,01 Hz. La variation est donc beaucoup plus faible. La figure donne la reprsentation graphique de la mesure:
Figure 3. Reprsentation sur un systme temps rel
Lorsque la charge est maximale, le systme temps rel assure donc une variation de +/0,2 Hz alors que la variation est de +/- 4 Hz dans le cas d'un systme classique. Ce phnomne peut tre reproduit l'aide du programme square.c crit en langage C.
#include #include #include #include #include <stdio.h> <stdlib.h> <fcntl.h> <unistd.h> <asm/io.h>
#define LPT 0x378 int ioperm(); int main(int argc, char **argv) { setuid(0); if (ioperm(LPT, 1, 1) < 0) { perror("ioperm()"); exit(-1); } while(1) { outb(0x01, LPT); usleep(50000); outb(0x00, LPT); usleep(50000); } return(0); }
Le signal gnr sur la broche 2 (bit D0) du port parallle est thoriquement un signal priodique carr de demi-priode T/2 de 50 ms. On observe l'oscilloscope le signal suivant sur un systme non charg (Intel Celeron 1.2Ghz, 128 Mo de RAM). Le systme utilise une distribution Fedora Core 4 quipe d'un noyau 2.6.14 compil partir des sources (ou vanilla kernel).
Figure 4. Gnration d'un signal carr sous Linux 2.6.14 non charg
Ds que l'on stresse le systme (criture rpte sur disque de fichiers de 50 Mo en utilisant la commande dd), on observe le signal suivant :
La forme du signal varie maintenant au cours du temps, il n'est pas de forme carre mais rectangulaire. Linux n'est donc plus capable de gnrer correctement ce signal. Cette exprience met donc en vidence l'importance des systmes temps rel pour certaines applications critiques.
Premption et commutation de contexte
Le noyau (kernel) est le composant principal d'un systme d'exploitation multitche moderne. Dans un tel systme, chaque tche (ou processus) est dcompose en threads (processus lger ou tche lgre) qui sont des lments de programmes coopratifs capables d'excuter chacun une portion de code dans un mme espace d'adressage. Chaque thread est caractris par un contexte local contenant la priorit du thread, ses variables locales ou l'tat de ses registres. Le passage d'un thread un autre est appel changement de contexte (context switch). Ce changement de contexte sera plus rapide sur un thread que sur un processus car les threads d'un processus voluent dans le mme espace d'adressage ce qui permet le partage des donnes entre les threads d'un mme processus. Dans certains cas, un processus ne sera compos que d'un seul thread et le changement de contexte s'effectuera sur le processus lui-mme. Dans le cas d'un systme temps rel, le noyau est dit premptif, c'est dire qu'un thread peut tre interrompu par l'ordonnanceur en fonction du niveau de priorit et ce afin de permettre l'excution d'un thread de plus haut niveau de priorit prt tre excut. Ceci permet d'affecter les plus hauts niveaux de priorit des tches dites critiques par rapport l'environnement rel contrl par le systme. La vrification des contextes commuter est ralise de manire rgulire par l'ordonnanceur en fonction de l'horloge logicielle interne du systme, ou tick timer systme. Dans le cas d'un noyau non premptif - comme le noyau Linux - un thread sera interrompu uniquement dans le cas d'un appel au noyau ou d'une une interruption externe. La notion de priorit tant peu utilise, c'est le noyau qui dcide ou non de commuter le thread actif en fonction d'un algorithme complexe.
IEEE 1003.1-1990 : POSIX Partie 1 : Interface de programmation (API) systme. Dfinition d'interfaces de programmation standards pour les systmes de type UNIX, connu galement sous l'appellation ISO 9945-1. Ce standard contient la dfinition de ces fonctions (bindings) en langage C. IEEE 1003.2-1992 : Interface applicative pour le shell et applications annexes. Dfinit les fonctionnalits du shell et commandes annexes pour les systmes de type UNIX. IEEE 1003.1b-1993 : Interface de programmation (API) temps rel. Ajout du support de programmation temps rel au standard prcdent. On parle galement de POSIX.4. IEEE 1003.1c-1995 : Interface de programmation (API) pour le multithreading.
Pour le sujet qui nous intresse, la plupart des systmes d'exploitation temps rel sont conformes partiellement ou totalement au standard POSIX. C'est le cas en particulier des systmes temps rel LynxOS (http ://www.lynuxworks.com) et QNX (http ://www.qnx.com). Quant Linux, sa conformit par rapport POSIX 1003.1b (temps rel) est partielle dans sa version standard et il ncessite l'application de modification (ou patch) sur les sources du noyau.
Un noyau temps rel est le minimum logiciel pour pouvoir faire du temps rel : ordonnanceur, gestion de tches, communications inter-tches, autant dire un systme plutt limit mais performant. Un excutif temps rel possde un noyau temps rel complt de modules/bibliothques pour faciliter la conception de l'application temps rel : gestion mmoire, gestion des E/S, gestion de timers, gestion d'accs rseau, gestion de fichiers. Lors de la gnration de l'excutif, on choisit la carte les bibliothques en fonction des besoins de l'application temps rel. Pour le dveloppement, on a besoin d'une machine hte (host) et de son environnement de dveloppement crois (compilateur C crois, utilitaires, dbogueur) ainsi que du systme cible (target) dans lequel on va tl-charger (par liaison srie ou par le rseau) l'application temps rel avec l'excutif. Un systme d'exploitation temps rel est le cas particulier o l'on a confusion entre le systme hte et le systme cible qui ne font plus qu'un. On a donc ici un environnement de dveloppement natif.
VxWorks et pSOS
VxWorks est aujourd'hui l'excutif temps rel le plus utilis dans l'industrie. Il est dvelopp par la socit Wind River (http ://www.windriver.com) qui a galement rachet rcemment les droits du noyau temps rel pSOS, un peu ancien mais galement largement utilis. VxWorks est fiable, faible empreinte mmoire, totalement configurable et port sur un nombre important de processeurs (PowerPC, 68K, CPU32, ColdFire, MCORE, 80x86, Pentium, i960, ARM, 8
StrongARM, MIPS, SH, SPARC, NECV8xx, M32 R/D, RAD6000, ST 20, TriCore). Un point fort de VxWorks a t le support rseau (sockets, commandes, NFS, RPC, etc.) disponible ds 1989 au dveloppeur bien avant tous ses concurrents. VxWorks est galement conforme POSIX 1003.1b.
QNX Dvelopp par la socit canadienne QNX Software (http ://www.qnx.com), QNX est un systme temps rel de type UNIX. Il est conforme POSIX, permet de dvelopper directement sur la plate-forme cible et intgre l'environnement graphique Photon, proche de X Window System.
C/OS (micro-C OS) et C/OS II
C/OS, dvelopp par le Canadien Jean J. Labrosse, est un excutif temps rel destin des environnements de trs petite taille construits autour de micro-contrleurs. Il est maintenant disponible sur un grand nombre de processeurs et peut intgrer des protocoles standards comme TCP/IP (C/IP) pour assurer une connectivit IP sur une liaison srie par PPP. Il est utilisable gratuitement pour l'enseignement (voir http ://www.ucos-ii.com).
Windows CE
Annonc avec fracas par Microsoft comme le systme d'exploitation embarqu qui tue, Windows CE et ses cousins comme Embedded Windows NT n'ont pour l'instant pas dtrn les systmes embarqus traditionnels. Victime d'une rputation de fiabilit approximative, Windows CE est pour l'instant cantonn l'quipement de nombreux assistants personnels ou PDA.
LynxOS
LynxOS est dvelopp par la socit LynuxWorks (http ://www.lynuxworks.com) qui a rcemment modifi son nom de part son virage vers Linux avec le dveloppement de Blue Cat. Ce systme temps rel est conforme la norme POSIX.
Nucleus
dvelopp par la socit Accelerated Technology Inc. (http ://www.acceleratedtechnology.com). Il est livr avec les sources et il n'y pas de royalties payer pour la redistribution.
eCOS
Nucleus
est
Acronyme pour Embeddable Configurable Operating System, eCOS fut initialement dvelopp par la socit Cygnus, figure emblmatique et prcurseur de l'open source professionnel, aujourd'hui rattache la socit Red Hat Software. Ce systme est adapt aux solutions trs faible empreinte mmoire et profondment enfouies. Son environnement de dveloppement est bas sur Linux et la chane de compilation GNU avec conformit au standard POSIX.
famille x86 est par exemple de l'ordre de 12 24 mois - les standards logiciels font de mme et de plus en plus d'quipements ncessitent l'intgration de composants que l'on doit importer du monde des systmes informatiques classiques ou du multimdia. De ce fait, les cots de licence et les droits de redistribution des systmes (ou royalties) sont parfois trs levs car l'diteur travaille sur un segment de march trs spcialis, une niche dans laquelle les produits commercialiss le sont pour leur fonction finale et non pour la valeur du logiciel lui-mme. Contrairement au monde de la bureautique o la pression commerciale peut inciter l'utilisateur faire voluer son logiciel frquemment - et donc payer un complment de licence - le logiciel embarqu est considr comme un mal ncessaire souvent destin durer plusieurs annes, en conservant une compatibilit avec du matriel et des processeurs obsoltes. Le cot de dveloppement d'applications autour de systmes propritaires est souvent plus lev car les outils de dveloppement sont mal connus de la majorit des dveloppeurs disponibles sur le march du travail car non tudis l'universit. Il est donc ncessaire de recruter du personnel trs spcialis donc rare. Les formations autour de ces outils sont galement onreuses car trs spcialises ce qui oblige l'diteur pratiquer des cots levs pour compenser le manque d'effet de masse. Tout cela implique un ensemble de spcificits contraignantes pour la gestion globale des outils informatiques de l'entreprise.
10
Dans cette article nous dcrirons en dtail l'utilisation de la technologie XENOMAI qui permet de crer de tches temps rel dans l'espace utilisateur et non plus uniquement dans l'espace noyau comme auparavant avec RTLinux ou RTAI.
Nous avons galement effectu un test l'oscilloscope lors de l'utilisation du programme square dcrit prcdemment. Les rsultats sur un systme stress sont assez peu probants et l'on peut noter plusieurs points largement en dehors de l'pure.
Indpendamment des rsultats, on touche du doigt le problme principal d'une solution base de noyau Linux modifi : on ne peut garantir un respect fiable des chances temporelles dans 100 % des cas et les rsultats constats sont bass sur un comportement moyen ce qui provoque quelques points en dehors des limites autorises. Dans le cas de certains systmes, ce type de comportement n'est pas acceptable.
traditionnels dans l'environnement GNU/Linux. Entre 2003 et 2005, Xenomai a troitement collabor avec le projet RTAI, afin de construire une plate-forme d'aide au dveloppement d'applications temps-rel de qualit industrielle, fortement intgre au systme Linux. De cette collaboration natra la branche spciale de dveloppements dite RTAI/Fusion, fonde sur le coeur de technologie du projet Xenomai. Depuis Octobre 2005, Xenomai poursuit seul cet objectif, avec l'aide renouvele des contributeurs de tous horizons qui ont particip cet effort depuis son lancement. La structure schmatique de Xenomai base sur ADEOS est dcrit sur la figure suivante.
Utilisation d'ADEOS
ADEOS est une couche de virtualisation des ressources dveloppe par Philippe Gerum, sur une ide originale de Karim Yaghmour publie dans un article technique, datant de 2001. Initialement dvelopp pour le projet Xenomai en 2002, ADEOS fut introduit dans l'architecture RTAI ds 2003, afin de se librer des incertitudes lies au brevet logiciel obtenu par les FSMLabs, concernant le principe de virtualisation des interruptions, dont dpend tout sous-systme temps rel hte d'un systme temps-partag comme Linux. Le but d'ADEOS est ainsi de permettre la cohabitation sur la mme machine physique d'un noyau Linux et d'un systme temps-rel. Pour ce faire, ADEOS cre des entits multiples appeles domaines. En premire approximation, on peut considrer qu'un domaine correspond un OS (exemple: Linux et un RTOS). Les diffrents domaines sont concurrents vis vis des vnements externes comme les interruptions. Il ragissent en fonction du niveau de priorit accord chacun d'eux. ADEOS constituant l'interface bas niveau de Xenomai, le portage de Xenomai sur une nouvelle architecture correspond en grande partie au portage d'ADEOS sur cette mme architecture.
Historiquement, les extensions temps-rel classiques comme RTAI et RTLinux sont bases sur la notion de double noyau :
Un noyau temps rel priorits fixes charg de grer les tches temps-rel dur. Le noyau et
12
Le noyau Linux considr comme une tche de plus faible priorit par le noyau temps-rel et grant les autres tches situes dans l'espace utilisateur.
De ce fait, les tches temps-rel taient jusqu' prsent programmes dans l'espace du noyau (kernel-space) ce qui pose des problmes diffrents niveaux : 1. Au niveau lgal, car en toute rigueur, seule la GPL est applicable dans l'espace du noyau. Le code source des tches temps-rel devait donc tre diffus sous GPL. 2. Au niveau technique car l'criture de modules dans l'espace du noyau est complexe et rend plus difficile la mise au point et la maintenance des modules. De plus, il est ncessaire d'utiliser des objets de communication (FIFO ou mmoire partage) entre les tches temps-rel et le reste du programme qui lui rside dans l'espace utilisateur (user-space). Une premire tape franchie par RTAI a permis de disposer d'un environnement de programmation temps-rel plus abordable, ressemblant globalement au contexte d'un module noyau dont l'excution aurait cependant lieu en espace utilisateur (extension LXRT). Xenomai a fortement amlior l'approche introduite dans RTAI-3.x (LXRT) afin de permettre une excution simple et performante des tches temps-rel dans l'espace utilisateur, tout en conservant la cohrence des priorits entre l'espace temps-rel Xenomai et la classe temps-rel Linux, avec une possibilit de migration transparente des tches entre ces espaces. Au-del de cet aspect, c'est le niveau d'intgration du sous-systme temps-rel avec le coeur standard Linux qui a t fortement augment. Xenomai permet ainsi d'excuter un programme temps-rel dans un processus utilisateur Linux multi-threads, tout en gardant l'opportunit de le mettre au point avec un dbogueur classique comme GDB. En rsum, nous pouvons dire que, du point de vue de l'utilisateur, Xenomai rend obsolte la notion de double programmation inhrente aux approches antrieures. Cependant, la programmation de tches temps rel dans l'espace du noyau reste toujours possible.
L'un des objectifs de Xenomai est de permettre la migration aise d'applications issues d'un environnement RTOS traditionnel vers un systme GNU/Linux. L'architecture de Xenomai repose ainsi sur un nano-kernel proposant une API gnrique neutre utilisant les similarits smantiques entre les diffrentes API des RTOS les plus rpandus (fonctions de cration et gestion de thread, smaphores, etc.). Xenomai peut donc muler des interfaces de programmation propritaires en factorisant de manire optimale leurs aspects communs fondamentaux, en particulier dans le cas de RTOS spcifiques (ou maison ) trs rpandus dans l'industrie.
pSOS+ uITron
13
VRTX
Ces interfaces sont utilisables soit dans le contexte d'un module noyau Linux, soit sous la forme d'une machine virtuelle fonctionnant dans le contexte d'un processus Linux. L'application et l'interface temps-rel sont alors associes dans un espace utilisateur protg, et leur fonctionnement est isol du reste des processus Linux (sandboxing). De plus, une interface POSIX temps-rel complte est galement disponible. Enfin, Xenomai dfinit sa propre interface native exploitant au mieux les capacits du systme temps-rel qu'il introduit, dont les principales classes de service sont :
Gestion de tches Objets de synchronisation Messages et communication Entres/sorties Allocation mmoire Gestion du temps et des alarmes Interruptions
Les sources de la distribution sont disponibles sur le site http://www.xenomai.org. Aprs extraction des sources, il est ais de crer rapidement une version utilisable de Xenomai. On doit tout d'abord crer un noyau intgrant l'extension ADEOS. Pour ce faire, on doit patcher le noyau 2.6 utilis avec un des fichiers choisi dans le rpertoire arch/i386/patches. Pour les noyaux rcents, nous conseillons d'utiliser les fichiers adeos-ipipe-*. On utilise donc la squence de commandes suivante.
# cd /usr/src/kernels/linux-2.6.14 # patch -p1 < adeos-ipipe-2.6.14-i386-1.0-10.patch
On recompile ensuite le noyau, on l'installe puis on redmarre le systme sur ce nouveau noyau. ATTENTION: Pour un bon fonctionnement de Xenomai, la gestion de l'alimentation (entre Power management options du menu principal de configuration du noyau) doit tre dsactive. Une fois le systme Linux correctement redmarr, on doit compiler les modules Xenomai. A partir du rpertoire des sources, on utilise les commandes suivantes.
# mkdir build # cd build # make -f ../makefile
14
Pour un premier test on peut laisser les options par dfaut mais il est conseill aux utilisateurs de chipset Intel d'activer le SMI workaround (SMI pour System Management Interrupt) dans le menu Machine (x86)/SMI workaround. Lorsque l'on sort de l'outil de configuration, la compilation se poursuit automatiquement. On doit ensuite installer la distribution binaire par la commande make install. Les fichiers sont installs sur le rpertoire /usr/realtime. Un premier test peut tre effectu en utilisant les programmes de dmonstration disponibles sur le rpertoire testsuite de la distribution binaire. Ce rpertoire contient deux outils latency et klatency, fonctionnant respectivement en mode utilisateur et en mode noyau. Le programme correspond un thread temps-rel affichant la valeur de sa latence (scheduling latency) sur des chantillons de 100 s. On peut effectuer un test de latence en mode utilisateur en faisant.
# cd /usr/realtime/testsuite/latency # ./run * * * Type ^C to stop this application. * * == Sampling period: 100 us RTT| 00:00:02 RTH|-----lat min|-----lat avg|-----lat max|-overrun|----lat RTD| -866| -773| 1295| 0| RTD| -900| -644| 5884| 0| RTD| -887| -774| 435| 0| RTD| -895| -655| 5032| 0|
best|---lat worst -866| 1295 -900| 5884 -900| 5884 -900| 5884
15
0| 0| 0| 0|
Dans le cas prsent, cela indique que la latence maximale est de 5884 ns en appliquant le mme principe de stress qu'au dbut de l'article. Le mme test est disponible dans l'espace noyau.
# cd ../klatency # ./run * * * Type ^C to stop this application. * * RTT| 00:00:01 RTH|----klat min|----klat avg|----klat max| overrun|---klat best|--klat worst RTD| -1984| -1845| 301| 0| -1984| 301 RTD| -1976| -1897| 137| 0| -1984| 301 RTD| -1979| -1833| 3814| 0| -1984| 3814 RTD| -1963| -1899| -758| 0| -1984| 3814 RTD| -1980| -1835| 3845| 0| -1984| 3845 RTD| -1983| -1897| 418| 0| -1984| 3845 RTD| -1975| -1897| 156| 0| -1984| 3845 RTD| -1971| -1833| 3373| 0| -1984| 3845 RTD| -1962| -1898| -726| 0| -1984| 3845
Sur ce test rapide, on s'aperoit que le rsultat est meilleur (3845 ns au maximum) puisque la tche temps rel tourne directement dans l'espace du noyau.
Exemple du programme de test
Le programme de test square a t port vers l'API de Xenomai 2.01 en version espace utilisateur et noyau. Notre programme est plus proche d'un application relle puisqu'il y a dans autre cas utilisation de ressources matrielles (le port parallle du PC) au travers du port 0x378. Nous utilisons l'API native Xenomai. Dans le cas de l'espace utilisateur, le code source est donn ci-dessous. On notera que la programmation est trs proche de celle d'un programme Linux standard en mode utilisateur, mise part les appels l'API Xenomai native.
#include #include #include #include #include #include #include #include #include #include #include #include #include #include <sys/mman.h> <sys/time.h> <sys/io.h> <unistd.h> <stdlib.h> <math.h> <stdio.h> <string.h> <signal.h> <getopt.h> <time.h> <native/task.h> <native/timer.h> <native/sem.h>
16
50000000LL /* 50 ms = 50 x 1000000 ns */
/* * Corps de la tche temps rel. C'est une tche priodique sur 50 ms */ void square (void *cookie) { int err; unsigned long old_time=0LL, current_time=0LL; if ((err = rt_timer_start(TM_ONESHOT)))) { fprintf(stderr,"square: cannot start timer, code %d\n",err); return; } if ((err = rt_task_set_periodic(NULL, TM_NOW, rt_timer_ns2ticks (period_ns))) { fprintf(stderr,"square: failed to set periodic, code %d\n",err); return; } for (;;) { long overrun = 0; test_loops++; if ((err = rt_task_wait_period())) { if (err != -ETIMEDOUT) rt_task_delete(NULL); /* Timer stopped. */ overrun++; } /* Change le niveau de la sortie */ outb(nibl, LPT); nibl = ~nibl; /* * On note la date et on affice ventuellement 1 fois toutes * les N boucles */ old_time = current_time; current_time = (long long)rt_timer_read(); if ((test_loops % loop_prt) == 0) printf ("Loop= %d dt= %ld ns\n", test_loops, current_time old_time); } } void cleanup_upon_sig(int sig __attribute__((unused))) { rt_timer_stop(); exit(0); } int main (int argc, char **argv)
17
{ int c, err; while ((c = getopt(argc,argv,"p:v:")) != EOF) switch (c) { case 'p': period_ns = atoll(optarg) * 1000LL; break; case 'v': loop_prt = atoi(optarg); break; default: fprintf(stderr, "usage: square <loop_print_cnt>]\n"); exit(2); } if (period_ns == 0) period_ns = PERIOD; /* ns */ signal(SIGINT, cleanup_upon_sig); signal(SIGTERM, cleanup_upon_sig); signal(SIGHUP, cleanup_upon_sig); signal(SIGALRM, cleanup_upon_sig); printf("== Period: %Ld us\n",period_ns / 1000); /* Pour accder au port parallle en mode utilisateur */ if (ioperm (LPT, 1, 1) < 0) { perror("ioperm"); exit (1); } /* Cr ation de la tche temps rel */ if ((err = rt_task_create(&square_task,"sampling",0,99,T_FPU))) { fprintf(stderr,"square: failed to create square task, code %d\n",err); return 0; } /* Dmarrage de la tche */ if ((err = rt_task_start(&square_task,&square,NULL))) { fprintf(stderr,"square: failed to start square task, code %d\n",err); return 0; } pause(); return 0; } [-p <period_us>] [-v
Pour compiler le programme, il est ncessaire de mettre en place le fichier Makefile suivant. Il faut galement ajouter le chemin d'accs /usr/realtime/bin la variable PATH de l'utilisateur. De mme, il est ncessaire d'ajouter le chemin d'accs aux bibliothques Xenomai / usr/realtime/lib au fichier /etc/ld.so.conf puis utiliser la commande ldconfig pour valider la modification.
18
# Allow overriding xeno-config on make command line XENO_CONFIG=xeno-config prefix := $(shell $(XENO_CONFIG) --prefix) ifeq ($(prefix),) $(error Please add <xenomai-install-path>/bin to your PATH variable) endif STD_CFLAGS := $(shell $(XENO_CONFIG) --xeno-cflags) STD_LDFLAGS := $(shell $(XENO_CONFIG) --xeno-ldflags) -lnative STD_TARGETS := xenomai_square all: $(STD_TARGETS) $(STD_TARGETS): $(STD_TARGETS:%=%.c) $(CC) -o $@ $< $(STD_CFLAGS) $(STD_LDFLAGS) clean: $(RM) -f *.o *~ $(STD_TARGETS)
La compilation du programme s'effectue par la commande make. Le fichier .runinfo contient les paramtres ncessaires au lancement du programme.
xenomai_square:native:!./xenomai_square;popall:control_c
19
Par rapport aux tests effectus avec le noyau 2.6 standard, on notera qu'il n'y a plus de point l'extrieur d'une limite donne. Dans le cas prsent, on mesure une latence maximale de 40 s. Toute contrainte externe suprieure cette valeur pourra donc tre scrupuleusement respecte. Nous avons galement test une version du programme excutable dans l'espace noyau. Au niveau Linux cela correspond un module classique. Le code source est donn ci-dessous et l'on notera la forte similitude avec la version dveloppe pour l'espace utilisateur.
#include #include #include #include #include <native/task.h> <native/timer.h> <native/sem.h> <xeno_config.h> <nucleus/types.h>
RT_TASK square_task; #define LPT #define PERIOD int nibl = 0x01; 0x378 50000000LL /* 50 ms = 50 x 1000000 ns */
/* Corps de la tche temps rel */ void square (void *cookie) { int err; unsigned long old_time=0LL, current_time=0LL;
20
printk (KERN_INFO "entering square\n"); if ((err = rt_task_set_periodic(NULL, TM_NOW, rt_timer_ns2ticks (period_ns)))) { xnarch_logerr("square: failed to set periodic, code %d\n",err); return; } for (;;) { long overrun = 0; test_loops++; if ((err = rt_task_wait_period())) { xnarch_logerr("square: rt_task_wait_period err %d\n",err); if (err != -ETIMEDOUT) rt_task_delete(NULL); overrun++; } outb(nibl, LPT); nibl = ~nibl; old_time = current_time; current_time = (long long)rt_timer_read(); if ((test_loops % loop_prt) == 0) printk (KERN_INFO "Loop= %d dt= %ld ns\n", test_loops, current_time - old_time); } } /* Chargement de la tche (insmod) */ int __square_init (void) { int err; printk (KERN_INFO "square_init\n"); if ((err = rt_timer_start(TM_ONESHOT))) { xnarch_logerr("square: cannot start timer, code %d\n",err); return 1; } if ((err = rt_task_create(&square_task,"ksampling",0,99,0))) { xnarch_logerr("square: failed to create square task, code %d\n",err); return 2; } if ((err = rt_task_start(&square_task,&square,NULL))) { xnarch_logerr("square: failed to start square task, code %d\n",err); return 4; } return 0; } /* Fin de la tche (rmmod) */
21
void __square_exit (void) { printk (KERN_INFO "square_exit\n"); rt_task_delete (&square_task); rt_timer_stop (); } /* Points d'entre API modules Linux */ module_init(__square_init); module_exit(__square_exit);
Le fichier Makefile utiliser est trs similaire celui d'un module 2.6 classique. Dans notre cas, cela conduit la gnration du module xenomai_square_module.ko.
XENO_CONFIG=xeno-config prefix := $(shell $(XENO_CONFIG) --prefix) ifeq ($(prefix),) $(error Please add <xenomai-install-path>/bin to your PATH variable) endif MODULE_NAME = xenomai_square_module $(MODULE_NAME)-objs = xenomai_square-module.o JUNK = *~ *.bak DEADJOE
# First pass, kernel Makefile reads module objects ifneq ($(KERNELRELEASE),) obj-m := $(MODULE_NAME).o EXTRA_CFLAGS += -I$(PWD)/../include EXTRA_CFLAGS += $(shell $(XENO_CONFIG) --module-cflags) # Second pass, the actual build. else KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) all: $(MAKE) -C $(KDIR) M=$(PWD) modules clean: rm -f *~ $(MAKE) -C $(KDIR) M=$(PWD) clean distclean: clean $(RM) $(JUNK) $(OBJS) help: $(MAKE) -C $(KDIR) M=$(PWD) help # Indents the kernel source the way linux/Documentation/CodingStyle.txt # wants it to be. indent: indent -kr -i8 $($(MODULE_NAME)-objs:.o=.c) install: $(MAKE) -C $(KDIR) M=$(PWD) modules_install endif
22
L'excution du programme correspond au chargement des modules Xenomai puis du module gnr soit.
# # # # insmod /usr/realtime/modules/xeno_hal.ko insmod /usr/realtime/modules/xeno_nucleus.ko insmod /usr/realtime/modules/xeno_native.ko insmod xenomai_square_module.ko
On obtient l'affichage suivant sur l'oscilloscope. On note le mme type de comportement mis part que la valeur maximale de la latence est infrieure, soit 30 s.
23
La nouvelle distribution XENOMAI 2.1 est lgrement diffrente tant au niveau de la mthode de compilation que de certains aspects de l'API native. Au niveau de la compilation, le script prepare_kernel.sh permet d'ajouter un menu de configuration XENOMAI au niveau du menu principal du configurateur du noyau Linux. Pour cela on utilise la commande suivante partir de l'arborescence des sources XENOMAI. Dans l'exemple suivant nous utilisons un noyau 2.6.14 et une architecture i386.
# scripts/prepare-kernel.sh --linux=/usr/src/linux-2.6.14 -adeos=/ usr/src/xenomai-2.1.0/ksrc/arch/i386/patches/adeos-ipipe-2.6.14-i386-1.201.patch --arch=i386
A partir de la, il est possible de configurer XENOMAI avec le configurateur du noyau, soit make menuconfig (ou xconfig) puis Real-time sub-system. Il suffit alors de compiler puis d'installer le nouveau noyau. Lorsque le systme est dmarr sur ce noyau, on peut alors compile XENOMAI par les commandes suivantes:
# # # # # mkdir build cd build ../configure make make install
La distribution est installe par dfaut sur /usr/xenomai (et non plus sur /usr/realtime). Les l'API native sont disponibles dans le fichier ksrc/skins/native/API.CHANGES. Dans le cas de notre exemple, les modifications apporter sont les suivantes.
modifications
de
Suppression des appels rt_timer_start() et rt_timer_stop() Ajout du paramtre NULL l'appel rt_task_wait_period() Remplacement de --module-cflags par --xeno-cflags dans ksquare/Makefile
Conclusions
Avec l'apparition de solutions comme Xenomai 2, le dveloppement d'applications temps rel dur sous Linux est grandement facilit. L'utilisation de l'espace utilisateur permet la fois de respecter les contraintes des licences (GPL/LGPL) mais aussi de disposer des outils classiques de la programmation sous Linux. De nombreux efforts sont en cours pour permettre cette solution d'atteindre une maturit industrielle encore plus grande mais plusieurs rfrences prestigieuses sont dj disponibles (Thales, Thomson, Xerox, etc.) sur diverses architectures (IA32, IA64, PowerPC, PowerPC 64, ARM).
Remerciements
Merci Philippe Gerum (rpm@xenomai.org) pour les informations concernant Xenomai et Patrice Kadionik (kadionik@enseirb.fr) pour la relecture.
Bibliographie
Dossier Temps rel sous Linux de Pierre Ficheux et Patrice Kadionik (juillet 2003) sur
24
http://pficheux.free.fr/articles/lmf/realtime
Patrice
Kadionik
sur
Site du projet XENOMAI sur http://www.xenomai.org Documentation et API XENOMAI sur http://snail.fsffrance.org/www.xenomai.org/documentation/branches/v2.0.x/html/api/index.html Site de FSMlabs/RTLinux sur http://www.fsmlabs.com Site du projet RTAI sur http://www.rtai.org Site du projet ADEOS sur http://home.gna.org/adeos/
25