MESURES 818 - OCTOBRE 2009 - www.mesures.com
32
S
olutions
MESURES 818 - OCTOBRE 2009 - www.mesures.com 33
S
olutions
Un système temps réel se définit par sa capacité à exécuter une tâche
dans un intervalle de temps donné. Cette caractéristique est appelée
le déterminisme. Bien entendu, chaque application impose un temps
de réponse différent, plus ou moins long selon les cas. Si certaines
peuvent se satisfaire d’un temps de réponse moyen, avec des valeurs
tantôt au-dessus et tantôt en dessous de la valeur annoncée, d’autres
ont absolument besoin d’une synchronisation fine. Elles ne peuvent
accepter aucun dépassement du temps de réponse, au risque de
déclencher un plantage de tout le système. C’est pourquoi les applications
déterministes se divisent en deux catégories : on distingue le traitement
temps réel “dur” du traitement temps réel “mou”.
Le temps réel “mou” fournit la garantie que le processeur garde
suffisamment de ressources disponibles pour effectuer une tâche
prioritaire dans un délai imparti. Typiquement, on optera pour
des systèmes d’exploitation généralistes tels que Linux pour répondre
à ce genre d’applications.
Avec le temps réel “dur”, à l’inverse, on cherche davantage à surveiller
le temps de réponse qu’à mesurer les ressources disponibles
dans le processeur. La criticité concerne le temps que met le système
à répondre (ou réagir) à un événement. Concrètement : on ne doit jamais
manquer de traiter un événement ou une interruption. Ces besoins
en temps réel dur sont encore plus rigoureux lorsqu’il s’agit,
par exemple, d’un calculateur d’ABS automobile. Car aux besoins
en temps de réponse très courts s’ajoutent toutes les contraintes
liées à la sécurité du conducteur. Toutefois, le temps réel dur n’est pas
toujours systématiquement employé. C’est le cas, par exemple,
du traitement audio sur un ordinateur : pour le décodage d’une piste
sonore classique, échantillonnée à 44,1 kHz, le logiciel a besoin
de transférer 32 bits de données vers le matériel toutes les 22,7 micro-
secondes ! Aucun système d’exploitation généraliste n’est capable
d’atteindre ces vitesses de traitement, d’autant que d’autres services,
qui s’exécutent en parallèle, peuvent retarder le système et entraîner
des coupures dans le son. C’est pourquoi on utilise une mémoire
tampon pour compenser ces délais. En remplissant cette mémoire
seulement toutes les 0,1 seconde, on résout un problème de temps réel
dur matériel en utilisant un système d’exploitation temps réel mou.
Toutes les applications dans les domaines de l’aérospatiale,
de la Défense, du contrôle industriel, de l’instrumentation,
de la robotique et des télécoms demandent des temps de traitement
inférieurs à la microseconde et une priorisation des tâches.
Temps réel “dur” et temps réel “mou” se font face
mode “kernel”. Contrairement aux OS
généralistes, ils n’incluaient aucun méca-
nisme d’abstraction pour faciliter les com-
munications entre l’OS et les périphériques.
Cela obligeait les développeurs à travailler au
plus près du matériel. Toutes les communi-
cations entre équipements devaient être
définies par le programme, avec le risque
d’erreurs que cela entraîne. Le temps de
débogage pouvait être très long même pour
un développeur expérimenté.
Heureusement, la puissance des processeurs
augmentant, les dernières générations de
RTOS disposent de mécanismes pour exécuter
des processus non critiques en parallèle des
tâches temps réel. On appelle ces processus
des modes “utilisateur” ou “user mode”. Le
développement de certaines applications
s’effectue alors dans un environnement dif-
férent du mode kernel, et chacun des deux
noyaux utilise un secteur distinct de la
mémoire. Les applications ainsi créées béné-
ficient toujours des performances détermi-
nistes du RTOS, mais disposent d’une
mémoire séparée pour exécuter toutes les
autres tâches annexes. Cela facilite le travail
des développeurs, qui n’utilisent qu’un seul
environnement de programmation.
La comparaison des performances
Avec les fonctions Preempt_RT disponibles
pour le noyau Linux, des niveaux de priorité
peuvent être associés au traitement de
certaines interruptions. Mais les temps de
traitement restent sujets à variations. On
réservera cette méthode à des applications
de contrôle fin, mais non critique. On parle
de temps réel “mou”. Les cœurs temps réel
rendent possible, quant à eux, un traite-
cations pouvant être chargées directement
dans le cœur temps réel. Concrètement, il
faut utiliser un format identique à celui des
systèmes de fichiers et des pilotes de péri-
phériques. Le cœur temps réel communique
directement avec le matériel. On parle
d’“exécution en mode kernel” car l’applica-
tion temps réel s’exécute dans le noyau temps
réel comme s’il s’agissait d’un driver.
Pour résumer, l’approche préemptive a
l’avantage de faire partie intégrante du
monde Linux, et convient bien au dévelop-
pement d’applications temps réel “mou”,
puisqu’elle ne peut pas garantir un véritable
déterminisme. A l’inverse, mettre en place
un cœur temps réel nécessite en quelque
sorte de “s’écarter du monde Linux” (ce
type de cœurs n’est d’ailleurs pas supporté
par la licence GPL). Une approche non stan-
dard, donc, mais qui fournit l’assurance d’un
temps réel “dur” (à condition bien sûr
d’écrire les applications afin qu’elles s’exé-
cutent directement sur ce cœur).
Le choix d’utiliser un RTOS
Ces deux approches tendent à apporter à
Linux les fonctionnalités temps réel qui lui
font défaut. Mais bien entendu, il est possible
d’opter pour la solution inverse : ajouter à un
RTOS la capacité d’exécution de fonctions
non critiques.
L’architecture de base d’un RTOS comprend
un noyau temps réel relié à un ordonnan-
ceur. Ce dernier définit l’ordre de traitement
des tâches en fonction de leur priorité. Un
algorithme préemptif s’exécute en parallèle
afin de vérifier à chaque temps de cycle
qu’une nouvelle interruption critique ne
s’est pas déclenchée. Par ailleurs, contraire-
ment à un système d’exploitation généra-
liste, un RTOS n’utilise qu’un seul espace
mémoire pour exécuter et sauvegarder
toutes les tâches (il n’y a pas de transferts de
données entre mémoire virtuelle et mémoire
physique).
Les RTOS se perfectionnent
Historiquement, les systèmes d’exploitation
temps réel ne traitaient les tâches qu’en
toutefois un grand intérêt. Le projet
“Preempt_RT” n’est plus considéré
aujourd’hui comme un projet annexe. Il fait
même partie des principaux projets. Un
grand nombre de développeurs de la com-
munauté Linux travaillent donc à améliorer
sa qualité et sa maturité.
Rajouter un cœur temps réel
L’approche “cœur temps réel” consiste
quant à elle à rajouter un noyau déterministe
à côté du noyau Linux classique. Le cœur
temps réel partage de la mémoire avec le
cœur Linux, et les deux communiquent par
le biais de files d’attente. Toutes les instruc-
tions sans exception passent par le noyau
temps réel. Ce dernier renvoie toutes les ins-
tructions non critiques vers le noyau Linux
standard et se charge d’exécuter les autres.
Mais il n’envoie les tâches non critiques au
noyau Linux standard qu’après avoir traité
les tâches prioritaires. Principale différence
avec le noyau préemptif : puisque les appli-
cations critiques sont directement chargées
dans le cœur temps réel, elles ont un accès
privilégié aux périphériques dont elles ont
besoin. Leur performance d’exécution est
donc moins sujette à variation qu’avec un
noyau préemptif.
Contrairement au noyau préemptif dont
l’installation est relativement transparente, le
principe du cœur temps réel induit des
différences avec le fonctionnement classique
de Linux, du fait du partage de la mémoire
entre les deux cœurs. Les développeurs
doivent donc s’appliquer à écrire des appli-
Lorsqu’il s’agit de certifier du code embarqué pour un secteur
critique (norme FDA 510k pour le médical, DO-178B pour
l’aéronautique, ou encore IEC 61508 pour les applications de
sécurité), il paraît bien difficile d’intégrer des solutions telles
que des OS Linux. Comment prouver la sûreté de fonctionnement
d’un OS comptant autant de lignes de codes, autant de modules
qui interagissent tous les uns avec les autres ? La certification
ne se limite pas seulement à livrer le code source du système
d’exploitation, il faut pouvoir en expliquer chaque détail.
En ce qui concerne Linux, il n’y a aucune visibilité sur les aspects
de qualité du code, de par le principe même de la communauté :
tout le monde peut rajouter des fonctions, mais à aucun moment
un document ne pourra attester de la validité du code. Pire :
on ne saurait même pas où s’adresser en cas de problème. Car
comme pour n’importe quel logiciel, un OS sans bug n’existe
pas. Le problème n’est pas que des bugs subsistent dans le code,
mais plutôt de savoir où ils sont situés et ce qu’ils font.
Pour les applications critiques, il faut absolument éviter qu’un OS
ne plante sans crier gare ou ne mette le système dans un état
instable. Il est donc impératif d’oublier la notion d’Open Source et
de s’orienter vers les solutions certifiables proposées par certains
éditeurs. Ces OS peuvent être fournis avec des documents
de vérification et de validation, voire même avec des outils de
couverture de tests propres à une norme.
Toutefois, il reste possible d’intégrer un OS Linux à l’intérieur
d’une application critique en faisant appel à la virtualisation
(voir article Mesures n° 810, page 35). Rappelons que
la virtualisation consiste à faire tourner plusieurs OS ou applications
sur un seul et même système, en leur faisant croire qu’ils
s’exécutent sur des systèmes physiquement différents. Une fois
la plate-forme de virtualisation installée (entre la couche
matérielle et l’OS), Linux peut tourner en parallèle de Windows,
d’un RTOS ou même d’applications Java, Ada, etc. De plus,
les outils de virtualisation sont tous légers, ce qui facilite leur
certification (car ce sont eux les garants de la sûreté de fonction-
nement du système). A noter bien sûr que ces deux dernières
solutions ont un coût non négligeable. Que l’on opte pour
une solution Linux propriétaire ou pour un hyperviseur, on
s’éloigne fortement du modèle “gratuit” des OS Linux. Et il reste
encore à programmer et à certifier l’application proprement dite.
Linux n’est pas adapté aux applications certifiées
Architecture
Linux standard
Linux +
cœur temps réel
Architecture optimisée avec mode kernel
et mode utilisateur
Comme tous les systèmes d’exploitation généralistes, Linux
standard forme une couche d’abstraction au-dessus du matériel.
Le c
œ
ur temps réel prend complètement la main sur le système. Il traite
directement les tâches critiques et envoie toutes les autres au noyau Linux.
Les architectures les plus récentes placent une couche d’abstraction au-dessus du c
œ
ur temps réel. Ceci afin
de pouvoir développer des applications sans forcément maîtriser les langages de bas niveau.
➜
➜