Vous êtes sur la page 1sur 25

Temps rel sous LINUX (reloaded)

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

Dfinition d'un systme temps rel


Temps partag et temps rel

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

dans les temps d'excution des tches.


Notion de temps rel

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.

Une petite exprience

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.

Figure 1. Test comparatif temps rel/temps partag

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 :

Figure 2. Reprsentation sur un systme classique

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 :

Figure 5. Gnration d'un signal carr sous Linux 2.6.14 charg

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.

Les extensions POSIX


La complexit des systmes et l'interoprabilit omniprsente ncessitent une standardisation de plus en plus grande tant au niveau des protocoles utiliss que du code-source des applications. Mme si elle n'est pas obligatoire, l'utilisation de systmes conformes POSIX est de plus en plus frquente. POSIX est l'acronyme de Portable Operating System Interface ou interface portable pour les systmes d'exploitation. Cette norme a t dveloppe par l'IEEE (Institute of Electrical and Electronic Engineering) et standardise par l'ANSI (American National Standards Institute) et l'ISO (International Standards Organisation). Le but de POSIX est d'obtenir la portabilit des logiciels au niveau de leur code source. Le terme de portabilit est un anglicisme driv de portability, terme lui-mme rserv au jargon informatique. Un programme qui est destin un systme d'exploitation qui respecte POSIX doit pouvoir tre adapt moindre frais sous n'importe quel autre systme POSIX. En thorie, le portage d'une application d'un systme POSIX vers un autre doit se rsumer une compilation des sources du programme. POSIX a initialement t mis en place pour les systmes de type UNIX mais d'autres systmes d'exploitation comme Windows NT sont aujourd'hui conformes POSIX. Le standard POSIX est divis en plusieurs sous-standards dont les principaux sont les suivants:

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.

Tour d'horizon des principaux systmes temps rel


Le but de cette section est d'effectuer un rapide tour d'horizon des principaux systmes d'exploitation utiliss dans les environnement embarqus. Ce tour d'horizon n'inclut pas les systmes base de Linux qui seront bien entendu dcrits en dtails plus loin dans l'article. Il convient avant tout de prciser les diffrences entre noyau, excutif et systme d'exploitation temps rel :

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.

Les contraintes des systmes propritaires


La majorit des systmes propritaires dcrits la section prcdente souffrent cependant de quelques dfauts forts contraignants. Les systmes sont souvent raliss par des socits de taille moyenne qui ont du mal suivre l'volution technologique : le matriel volue trs vite - la dure de vie d'un processeur de la 9

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.

Linux comme systme temps rel


Forts des arguments concernant l'open source, il est normal d'tre tent par l'utilisation de Linux comme systme temps rel. Outre les avantages inhrents l'open source, la fiabilit lgendaire de Linux en fait un candidat idal. Malheureusement, Linux n'est pas nativement un systme temps rel. Le noyau Linux fut en effet conu dans le but d'en faire un systme gnraliste donc bas sur la notion de temps partag et non de temps rel. La communaut Linux tant trs active, plusieurs solutions techniques sont cependant disponibles dans le but d'amliorer le comportement du noyau afin qu'il soit compatible avec les contraintes d'un systme temps rel comme dcrit au dbut de l'article. Concrtement, les solutions techniques disponibles sont divises en deux familles : 1. L'option premptive du noyau Linux 2.6. Les modifications sont drives des patch premptifs utilises dans les noyaux 2.4 et introduits entre autres par la socit Montavista (http://www.mvista.com). Nous parlerons assez peu de cette solution car elle s'applique uniquement dans le cas de temps-rel mou et on parle plus d'amlioration de qualit de service (rduction de latence) que de temps rel. 2. Le noyau temps rel auxiliaire. Les promoteurs de cette technologie considrent que le noyau Linux ne sera jamais vritablement temps rel et ajoute donc ce noyau un autre noyau disposant d'un vritable ordonnanceur temps rel priorits fixes. Ce noyau auxiliaire traite directement les tches temps rel et dlgue les autres tches au noyau Linux, considr comme la tche de fond de plus faible priorit. Cette technique permet de mettre en place des systmes temps rel durs . Cette technologie utilise par RTLinux et les projets europens RTAI et XENOMAI (http://www.xenomai.org). RTLinux est support commercialement par FSMLabs (http://www.fsmlabs.com) qui a des relations chaotiques avec la communaut open source cause du brevet logiciel qui couvre l'utilisation de ce noyau auxiliaire.

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.

Le noyau 2.6 premptif


Le mode dit premptif est slectionn dans les sources du noyau 2.6 dans le menu Processor type and features/Preemption model. Il faut choisir l'option Preemptible kernel puis recompiler le noyau.
Test du programme square

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.

Figure 6. Excution de square sur un noyau 2.6 premptif stress

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.

XENOMAI 2: temps rel dur sous Linux 2.6


Le projet Xenomai a t fond en 2001, dans le but de crer un systme d'mulation de RTOS 11

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.

Figure 7: Structure de Xenomai

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.

Excution des tches temps rel dans l'espace utilisateur

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

les tches associes sont des modules du noyau Linux.

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.

Un coeur de RTOS gnrique

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.

Les API de Xenomai

Xenomai intgre les APIs de RTOS traditionnels suivantes : VxWorks


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

Installation de Xenomai 2.01

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

Ce qui conduit l'affichage de la fentre de configuration.

14

Figure 8: Configuration de Xenomai

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

RTD| RTD| RTD| RTD|

-929| -925| -909| -881|

-771| -772| -652| -768|

1825| 1406| 5718| 1450|

0| 0| 0| 0|

-929| -929| -929| -929|

5884 5884 5884 5884

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>

RT_TASK square_task; #define LPT 0x378

16

#define PERIOD int nibl = 0x01;

50000000LL /* 50 ms = 50 x 1000000 ns */

long long period_ns = 0; int loop_prt = 100; int test_loops = 0;

/* print every 100 loops: 5 s */ /* outer loop count */

/* * 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

Pour excuter le programme, on utilise la ligne suivante.


# xeno-load xenomai_square

La trace sur l'oscilloscope est la suivante.

19

Figure 9: Excution de xenomai_square en mode utilisateur

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 */

long long period_ns = PERIOD; int loop_prt = 100; int test_loops = 1;

/* print every 100 loops: 5 s */ /* outer loop count */

/* 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.

Figure 10: Excution de xenomai_square_module en mode noyau

23

Cas de XENOMAI 2.1

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

Page Systmes embarqus de http://www.enseirb.fr/~kadionik/embedded/embedded.html

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