Chapitre III
Noyau temps réel pour système
Embarqué
3-1 Les Systèmes
Embarqués
Les Systèmes Embarqués sont
caractérisés par leur intégration à un
système plus grand. Ils sont composés de un ou plusieurs
processeurs, ainsi que de mémoire de plus ou moins grande taille. On
rencontre des mémoires ROM, pour les programmes à
exécuter, et RAM, pour le stockage temporaire des données. La
figure 3-1 montre le principe de fonctionnement d'un Système
Embarqué. Les informations en entrée viennent de capteurs, En
sortie, ce sont des actionneurs, des écrans d'affichage, ou des signaux
de communication [1].
Fig. 3-1 Principe des Systems embarquée
3-2 Les Systèmes d'Exploitation pour
Systèmes Embarqués
Les Systèmes d'Exploitation (SE) servent à
rendre disponible les éléments matériels d'un
système informatique pour les applications. En fonction du contexte
d'exécution, des objectifs du SE, les types de tâches qu'il
supporte, son architecture, peuvent varier, même si son rôle reste
toujours globalement identique.
L'usage de Systèmes d'Exploitation est devenue
nécessaire dans les Systèmes embarqués, du fait de la
complexité croissante de ces systèmes (ex : Systèmes sur
puce), de la présence de fortes contraintes temps réel, de la
limitation des ressources disponibles, tant en mémoire qu'en
énergie disponible et donc en puissance de calcul.
Parmi les Systèmes d'Exploitations pour les
Systèmes Embarqués, on distingue les SE temps-réel (RTOS -
Real Time Operating Systems), qui se caractérisent par la
présence de contrainte temps-réel.
3-3 Noyaux pour systèmes embarqués
Ce sont des noyaux exécutifs de petites tailles, assez
performants et particulièrement appropriés à des
systèmes embarqués simples où les besoins sont
essentiellement une exécution et un temps de réaction aux
événements rapide (alarmes, interruptions...). Ils offrent un
ordonnancement par priorités (généralement un ensemble de
priorités prédéfinies est offert), une horloge globale,
des primitives pour la préemption des tâches, pour le retardement
ainsi que des mécanismes de synchronisation, etc. Toutefois, ces noyaux
sont inefficaces pour des systèmes complexes ou de taille importante. En
effet, dans de pareils systèmes, les contraintes sont plus
compliquées et portent à la fois, sur le temps, les ressources,
la communication et il est extrêmement difficile de prédire avec
de pareils noyaux de base que les contraintes seront vérifiées.
La principale cause est due aux délais introduits pour la gestion de ces
systèmes. Dans le cas où ces noyaux sont utilisés, on se
retrouve aussi avec des phénomènes d'inversion de
priorités (voir 3-7-2-2-1) car les mécanismes
d'ordonnancement utilisés dans ces noyaux sont de très bas
niveau. Egalement, des situations où les ressources ne sont pas
disponibles à temps, où les messages ne sont pas
délivrés à temps, etc.
3-3-1 Les Caractéristiques d'un noyau temps
réel :
C'est en fait un ensemble de fonctionnalités,
regroupées sous le terme de SERVICES pour la plupart,
qui forment le noyau. Une des fonctionnalités les plus connues des
noyaux (sans être pour autant un service) est le
SCHEDULER, responsable de la cohabitation des
différents programmes pendant leur exécution. C'est donc le noyau
qui contrôle les ressources et permet leur utilisation de façon
sûre et efficace au travers de SERVICES. Puisque le
noyau garantit la stabilité du système, plusieurs programmes
indépendants peuvent se tenir prêts à fonctionner, au bon
vouloir du noyau. Cette MULTIPROGRAMMATION permet aux
développeurs de créer des programmes sans se soucier de savoir
s'il existe d'autres programmes dans le système. Chacun a l'impression
que le système lui est dédié. Si le noyau le permet, il
est même possible de faire fonctionner ces programmes en parallèle
tout en donnant l'impression à chacun d'être seul à
fonctionner (au prix d'une perte de vitesse bien entendu). Lorsque le noyau
joue parfaitement son rôle de chef d'orchestre (le fonctionnement en
parallèle des tâches incombent au noyau seul) on dit que le noyau
est MULTITACHES PREEMPTIF. Si le noyau n'est pas capable de faire une telle
chose, alors c'est aux tâches de "rendre la main" au noyau de temps en
temps, on dit que le noyau est MULTI-TACHES COOPERATIF.
Le noyau multitâche peut simplement gérer le
parallélisme en découpant le temps en parts égales pour
chaque tâche en mémoire. Le problème, c'est que les
tâches en fonctionnement ont rarement les mêmes besoins, et
certaines, rarement actives, requièrent toute la puissance du
système lorsqu'elles se réveillent.
Les tâches ont donc des PRIORITES différentes, et
doivent pouvoir répondre à un événement dans
un temps le plus court possible. Plutôt que d'assurer un temps de
réactivité quasi-nul (ce qui est
impossible), le noyau se doit de garantir un TEMPS DE LATENCE
constant : c'est le DETERMINISME [6].
3-3-2 Le Noyau temps réel PICOS18 :
Après maintes consultations sur le net à la
recherche de noyaux temps réel gratuits pour l'embarqué, notre
choix, qui était limité, a porté sur le NTR PICOS18.
PICOS18 est un produit de la société PRAGMATEC
distribué gratuitement sous la licence GPL (General Public Licence).
Celle-ci garantit la libre circulation des sources de PICOS. PICOS18 est un
noyau temps réel basé sur la norme automobile OSEK/VDX et
destiné aux microcontrôleurs PIC18 de la société
Microchip Technologie Inc [6].
3-3-3 Les Caractéristiques de PICos18 :
Le noyau PICos18 possède les caractéristiques
suivantes :
Fig. 3-2 Caractérise de PICOS18
· Le coeur du noyau (Init + Scheduler + Task
Manager) qui a la responsabilité de gérer les tâches de
l'application et donc de déterminer la prochaine tâche active en
fonction de l'état et la priorité de chaque tâche.
· ?Le gestionnaire d'alarmes et de
compteurs (Alarm Manager). Proche du coeur du noyau, il répond
à l'interruption du TIMER0 afin de mettre à jour
périodiquement les alarmes et compteurs associées aux
tâches.
· Les Hook routines sont proches du coeur du noyau
et permettent à l'utilisateur de dérouter le déroulement
normal du noyau de façon à prendre temporairement le
contrôle du système.
· ?Le gestionnaire de tâches
(Process Manager) est un service du noyau, dont le rôle est d'offrir
à l'application les fonctions nécessaires à la gestion des
états (changer l'état d'une tâche, chaîner des
tâches, activer une tâche...).
· ?Le gestionnaire
d'évènement (Event Manager) est un service du noyau dont le
rôle est d'offrir à l'application les fonctions nécessaires
à la gestion des évènements d'une tâche (mise en
attente sur un évènement, effacer un
évènement...).
?Le gestionnaire d'interruption (INT Manager) offre
à l'application les fonctions nécessaires à l'activation
et la désactivation des interruptions du système [6].
3-4 Historique de la proposition OSEK/VDX
OSEK/VDX est une proposition récente d'exécutif
pour l'électronique embarquée dans les automobiles. Cette
proposition est le fruit des travaux de nombreux constructeurs automobiles et
équipementiers européens depuis septembre 1995. OSEK a
été étudié par les équipes principalement
allemandes et VDX par le GIE PSA-Renault ; OSEK/VDX est le résultat
commun des travaux. L'un des objectifs visés par le consortium est de
standardiser les interfaces du système d'exploitation afin de faciliter
la fourniture de logiciels par de multiples sources, la portabilité,
l'interopérabilité et la réutilisation. Différents
travaux ont été menés dans le cadre d'OSEK/VDX :
- OSEK/VDX OS : les services de base du noyau du
système d'exploitation ;
- OSEK/VDX COM : les services pour la communication
entre des noeuds d'un système réparti ou la communication locale
;
- OSEK/VDX NM (Network Management) : les services de
gestion et de surveillance du réseau
;
- OSEK/VDX OIL (OSEK Implémentation Langage) :
langage de description pour la mise en oeuvre automatisée d'une
application.
La présentation ci-après porte uniquement sur le
noyau du système d'exploitation [7].
3-5 La Gestion des tâches :
La tâche est l'agent actif de l'application. C'est une
portion de code séquentiel correspondant souvent à la notion de
procédure (ou fonction) dans le langage de programmation utilisé
pour coder l'application. La tâche étant un agent actif, il est
naturel de lui associer un diagramme d'état qui représente
l'ensemble de ses états possibles ainsi que les conditions
associées aux transitions d'états (voir figure 3-3).
Fig 3-3 les états d'une tache OSEK/VDX :basique(a gauche),
étendue (a droite).
OSEK/VDX utilise deux types de tâches définis
ci-après :
3-5-1 les tâches basiques : Sont
des modules sans point bloquant, c'est à dire sans appel de service
pouvant provoquer une mise en attente de la tâche. La tâche est
activée, elle s'exécute puis elle doit se terminer, les points de
synchronisation sont donc seulement au début et à la fin de la
tâche. Elle ne possède que trois états:
SUSPENDED (inactive), READY (attente du
processeur), RUNNING (elle a le processeur).
3-5-2 les tâches étendues
: Sont composées de un ou plusieurs modules
séparés par des invocations de services éventuellement
bloquants (WaitEvent). Le diagramme d'état
possède donc un état supplémentaire : l'état
waiting.
Voici quelques exemples de services :
a- ActivateTask
(<TaskName>) : activation de la tâche
désignée, Permet de faire passer l'état d'une tâche
de SUSPENDED à READY. Si la tâche ainsi activée est la
tâche prête la plus prioritaire elle prend immédiatement la
main sur la tâche en cours.
b- TerminateTask (void) : termine
la tâche appelante, Permet de faire passer l'état d'une
tâche de RUNNING à SYSPENDED. La tâche n'est plus alors
considérée par le noyau. Pour l'exécuter de nouveau il est
nécessaire de l'activer à l'aide de la fonction ActivateTask.
c- ChainTask
(<TaskName>) : termine la tâche appelante et
active la tâche désignée, Permet de faire passer
l'état de tâche courante de RUNNING à SUSPENDED. La
tâche dont l'ID est TaskID
passe à l `état READY quelque soit son état
actuel. Si la tâche ainsi activée est la tâche prête
la plus prioritaire elle prend immédiatement la main sur la tâche
en cours.
Remarque : Une application temps réel
comporte souvent des tâches périodiques [7].
3-6 Ordonnancement
Les tâches possèdent une priorité
utilisée pour l'ordonnancement. La valeur de priorité est
statique, non modifiable sauf par l'exécutif lorsqu'il met en oeuvre
l'algorithme « Priority Ceiling Protocol » (voir 3-7-2-2-3)
pour la gestion des ressources. L'ordonnancement peut être :
3-6-1 Non-préemptif : La
tâche rend le processeur lorsqu'elle se termine (TerminateTask),
lorsqu'elle active une autre tâche (ChainTask), ou lorsqu'elle entre dans
un état d'attente (WaitEvent). Dans ce cas le contexte à sauver
pour la tâche est minimal .
3-6-2 Préemptif : Toute
tâche réveillée et plus prioritaire que la tâche en
cours prend le processeur. Le module d'ordonnancement étant
considéré comme une ressource occupée ou
relâchée, une tâche peut se l'approprier dans un contexte
préemptif pour passer en mode non-préemptif.
3-6-3 Mixte : Les deux modes
d'ordonnancement sont utilisés en même temps pour des tâches
différentes. Dans ce cas chaque tâche possède un attribut
indiquant son mode d'ordonnancement. La possibilité d'avoir des
tâches ordonnancées selon un mode non préemptif dans un
contexte préemptif est utile lorsque des tâches sont courtes
(temps d'exécution voisin du temps de changement de contexte), si
l'espace mémoire RAM doit être économisé ou encore
si la non-préemption est nécessaire [7].
3-7 La synchronisation des tâches
On distingue en général deux types de
synchronisation entre tâches ou entre les tâches et l'environnement
: la signalisation synchrone et la signalisation
asynchrone. La signalisation asynchrone qui est utilisée, par
exemple dans les exécutifs UNIX temps réel pour traiter certains
types d'exception, n'a pas été retenue dans OSEK/VDX ; elle ne
sera donc pas présentée ici, compte tenu de la place disponible
[7].
Les événements
Pour OSEK/VDX, la synchronisation est basée sur le
mécanisme des événements privés car appartenant au
consommateur. Les services liés aux événements ne peuvent
être utilisés que par les tâches de type étendu. La
synchronisation est de type synchrone, la tâche réceptrice se
mettant explicitement en attente de l'occurrence pour pouvoir être
réveillée. Chaque tâche peut posséder un certain
nombre d'événements pour lesquels des occurrences seront
signalées par d'autres tâches (de type basique ou étendu)
ou des ISRs. Seule la tâche propriétaire peut se mettre en attente
(OU implicite sur la liste des événements nommés),
l'attente n'étant pas automatiquement surveillée temporellement
(pas de délai de garde) et l'effacement de l'occurrence étant
à la charge de la tâche réceptrice [7].
Voici quelques exemples de services utilisables par les
tâches
a- SetEvent (TaskType TaskID,
EventMaskType Mask)
· Description :Permet de poster un
événement à la tâche dont l'identificateur est ID
et selon le masque d'événements Mask.
· Paramètres : TaskID : ID
de la tâche concernée.
Mask : masque de l'événement
posté.
b- ClearEvent (EventMaskType
Mask)
· Description : Permet de supprimer un
événement reçu par la tâche en cours selon le
masque d'événements Mask.
· Paramètres : Mask :
masque de l'événement supprimé.
c- WaitEvent (EventMaskType
Mask)
· Description : Fait passer l'état
de la tâche en cours de RUNNING à WAITING. La valeur Mask
désigne l'ensemble des événements attendus par la
tâche
· Paramètres : Mask :
Ensemble des événements attendus.
d- GetEvent (TaskType
TaskID, EventMaskRefType Event)
· Description : Permet d'obtenir les
événements reçus par une tâche dont l'identificateur
est
taskID. Lorsqu'une tâche attend plusieurs
événements et qu'elle est réveillée par l'un de
ces
événements, elle peut connaître le ou les
événements postés à l'aide de la fonction GetEvent.
La figure 3-4 montre un exemple de signalisation entre tâches et entre
une tâche et l'environnement utilisant des événements
privés [6].
Fig 3-4 Exemple de synchronisation par événement.
Exemple: (De notre application)
Fig 3-5 Exemple de l'événement
En fait cela s'explique par le fait que la tâche 3 est
plus prioritaire que la tâche 5, donc lorsqu'elle aura posté un
événement à la tâche 5, elle continuera à
s'exécuter jusqu'à ce qu'elle soit mise en sommeil (blocage). La
tache 5 elle réveille avec l'arrivée de l'événement
(POTVAL_EVENT) Apres elle va supprimer ce événement avec
ClearEvent(POTVAL_EVENT); et elle va exécuter sont code tant que la
tache 3 est bloquée car elle est plus prioritaire que la tache 5.
Toutefois cette structure ne permet pas à une tâche d'attendre
l'arrivée de plusieurs événements simultanément.
C'est pourquoi les drapeaux événements apparaissent sous forme de
groupes (event flag groups) de 8 bits, suivant le type de microprocesseur,
chaque bit étant un drapeau événement.
Désigne un ensemble d'événements attendus
ou postés d'une tâche. Valeur 8 bits signée (char) comprise
entre 0 et 128 inclus. Cette valeur est un multiple de 2 (0, 1, 2, 4, 8, 16,
32, 64 et 128). Exemple : #define POTVAL_EVENT 0x08
Les drapeaux événements ont l'avantage de
concentrer beaucoup d'information dans très peu de place. Cependant ils
n'indiquent que si l'événement a eu lieu ou non. C'est ensuite
à la tâche avertie d'aller chercher au besoin des informations sur
l'événement. Pour gérer des groupes de drapeaux
événements, il faut apporter d'autres fonctions aux
précédentes (elles aussi à perfectionner). Quelle que soit
la manière dont ils sont gérés, les groupes doivent
être des structures globales si l'on veut qu'ils soient
reconnus par toute l'application [6].
3-7-1 Partage de ressources et exclusion mutuelle
Il est naturel, dans un contexte où plusieurs
tâches coopérants sont en concurrence, d'avoir à
contrôler et obtenir l'accès cohérent à des
ressources partagées par les tâches. Les ressources peuvent
être de natures très diverses, comme par exemple un système
de fichiers accessible en lecture par plusieurs tâches, ou encore une
imprimante accessible en exclusion mutuelle par les tâches, ou encore un
élément physique du procédé contrôlé
qui ne peut être utilisé que par une tâche à la fois,
ou tout simplement des données communes. On se trouve donc
confronté à un problème de synchronisation entre
tâches afin de respecter le protocole d'accès aux ressources, la
politique la plus classique étant celle de l'accès en exclusion
mutuelle pour une ressource non partageable [2].
3-7-2-1 l'exclusion mutuelle :
L'exclusion mutuelle de 02 taches vis-à-vis d'une
ressource partageable Suppose une phase pendant laquelle, une seule des 02
taches est en possession de la ressource. Cette phase appelée section
critique (partie d'un programme qui conduit à un conflit d'accès
au ressource), OSEK/VDX assure la gestion de l'accès concurrent aux
ressources partagées par le protocole PCP (« Priority Ceiling
Protocol »), ce qui garantit la non-inversion de priorité et
l'absence de blocage par usage des services GetResource et ReleaseResource
« encadrant » la section critique, sous réserve d'une gestion
bien ordonnée (LIFO) des prises de ressources multiples. A
l'intérieur de la section critique, les restrictions classiques sur
l'appel des services concernent les services de terminaison ou de blocage de la
tâche [5].
3-7-2-2 Héritage de priorité (Priority
Inheritance) :
3-7-2-2-1 Inversion de priorité
:
L'exemple décrit dans la figure 3 -6 présente
une situation Inversion de priorité alors que la tâche 1 est en
section critique ( procession de la ressource) et la tâche 3 en attente
de la ressource, une tâche 2, de priorité intermédiaire, se
retrouve prête à l'exécution. Le scheduler préemptif
lui attribue le processeur pour une durée qu'il est impossible
d'estimer.
La tâche 3 doit d'abord attendre que la tâche 2
termine son exécution, ensuite que la tâche 1 libère
la ressource avant de reprendre. On ne peut donc plus déterminer au
bout de quelle durée maximale la
tâche 1 libérera la ressource, il est donc
impossible de savoir si la tâche 3 respectera sa contrainte. C'est donc
un cas de panne logicielle grave [2].
Fig 3-6 Inversion de priorité
On constate que la tâche 3 se trouve « ralentie
» par une tâche de priorité inférieure (la tache 2),
que le temps nécessaire, et indéfini, pour qu'elle finisse son
code, et donc respecte sa contrainte, dépend de cette tâche.
Tout se passe donc comme si les deux tâches de plus forte
priorité avaient inversé leur priorité [2].
3-7-2-2-2 Remèdes :
Pour éviter ceci, en ne permettant pas qu'une tâche
soit préemptée systématiquement si elle est en section
critique, alors le noyau doit autoriser, provisoirement, un
héritage de priorité [2].
3-7-2-2-3 Héritage par la méthode du
plafond de priorité (PCP) :
PICos18 autorise le libre accès à toutes les
ressources du PIC18xxx à toutes les tâches d'une applications.
Ceci permet de vous simplifier l'accès aux périphériques
mais peut engendrer quelques soucis de droit d'accès lorsque ce
même périphérique est utilisé par plusieurs
tâches en même temps. Ceci est résolu par la gestion des
ressources en mode « ceiling protocole >> de la norme OSEK/VDX.
Le principe du « ceiling protocol >> est simple :
Une ressource possède une certaine priorité.
Supposons que 2 tâches cherchent à accéder à
l'EEPROM interne du PIC18. Pour éviter des accès concurrents du
fait que l'application est multitâches, on attribue à la ressource
une priorité supérieure aux 2 autres tâches.
Lorsque l'une des tâches accède à la
ressource, sa priorité est modifiée pour prendre la valeur de
la priorité de la ressource. Sa priorité est ainsi
assurée d'être la plus élevée d'entre les 2
tâches. 32
Laressource ne pourra donc être prise par la tâche
de moindre priorité car celle-ci n'aura pas la main, du fait du jeux des
priorités.
Toutefois la tâche qui a accès à la
ressource peut aussi être ponctuellement suspendue, en appelant par
exemple le service WaitEvent. Pour éviter que la tâche de moindre
priorité n'en profite pour accéder à la ressource
déjà réservée, un champ « lock » a
été ajouté afin de permettre afin de vérifier si la
ressource n'est pas déjà réservée.
L'héritage de priorité garantit qu'aucune
tâche de priorité intermédiaire ne viendra rallonger la
période de blocage (de la tâche la plus prioritaire)
Lorsqu'une tâche obtienne la ressource et qu'une autre
tache la réclame, la priorité de la tâche qui la
possède est augmentée au niveau de la priorité de la
tâche qui réclame (dans le cas où cette priorité est
supérieure). La tâche qui obtienne la ressource hérite
ainsi de la priorité de la tâche qui la réclame. Ceci
permet de limiter à une seule fois le nombre de situations d'inversion
de priorité. Le prix à payer est le blocage des tâches de
priorité intermédiaire qui ne partagent pas la même
ressource.
Pour la mise en oeuvre du protocole PCP une priorité
plafond est affectée à chaque ressource. Cette priorité
doit être supérieure ou égale à la plus haute
priorité des tâches utilisant la ressource tout en étant
inférieure à la plus basse priorité des tâches
n'utilisant pas la ressource, ces dernières étant
néanmoins de plus forte priorité que les tâches utilisant
la ressource. Ce protocole est également utilisé pour le partage
de ressources entre les tâches et les ISRs ou entre les ISRs ; pour ce
faire une priorité virtuelle est allouée à chaque
interruption. La ressource système prédéfinie permet
à une tâche de s'allouer le processeur, puisque l'ordonnanceur est
traité comme une ressource. Ceci permet donc de passer en mode
non-préemptif.
Deux services permettent de contrôler l'accès aux
ressources :
- GetResource (<Res_Name>) : demande
l'accès à la ressource désignée avant
d'exécuter le code d'utilisation de la ressource. Il est possible
d'utiliser plusieurs ressources (différentes) pour une même
tâche, pourvu que les appels soient convenablement imbriqués
(LIFO) ;
- ReleaseResource (<Res_Name>) :
libère l'accès à la ressource désignée.
[7][2].
Fig 3-7 Héritage de priorité
· T1 s'exécute puisque les autres taches sont
suspendues.
· T1 demande la ressource et hérite la plus forte
priorité.
· T4 et T3 demande au même temps le uP, T4 prend le
uP car elle est plus prioritaire a T3.
· T4 libère le uP quand elle se termine.
· T1 reprend le uP et T3 reste toujours bloqué
(même chose pour T2) car T1 est plus prioritaire .
· Quand T1 libere la ressource elle va
récupérer sa priorité initiale, mais ne s'exécute
pas car T3 et
T2 son plus prioritaire.
· La T3 est réveillé et s' exécute.
· T3 demande la ressource, alors sa priorité est
augmente(PCP) et T2 reste bloquée.
· T3 libère la ressource, alors sa priorité
revient à sa valeur initiale.
· A ce moment la T2 est activée elle va
exécuter jusqu'à terminaison. l
· T1 elle réveil est récupère le uP
pour terminé son exécution.
3-8 Les objets Alarme et Compteur
Ces objets, propres à la spécification
OSEK/VDX, permettent principalement le traitement de phénomènes
récurrents dans le temps en provenance de l'environnement
extérieur, comme par exemple une horloge ou des signaux en provenance
d'organes mécaniques d'un moteur automobile (arbre à cames,
vilebrequin). Ils constituent des compléments des mécanismes de
signalisation par événement. Ils permettent également la
mise en oeuvre des chiens de garde, par exemple sur l'émission ou la
réception des messages. C'est un mécanisme à deux <<
étages » pour lequel deux objets sont associés : les
compteurs, qui ne font pas partie de l'API OSEK mais du langage OIL, et les
alarmes. Un compteur est un objet destiné à l'enregistrement de
<< ticks » en provenance d'une horloge ou d'un dispositif quelconque
émettant des stimulis. C'est un dispositif de comptage ayant une
certaine dynamique, qui repasse à zéro après avoir atteint
sa valeur maximale (valeur définie à la génération
de l'application). Il compte les ticks après une éventuelle
pré-division (par exemple 10 ticks représentent une unité
pour le compteur). Plusieurs alarmes peuvent être associées
à un même compteur, ce qui permet de constituer facilement, par
exemple, des bases de temps. Une alarme est associée (statiquement
à la génération du système) à un compteur et
une tâche. L'action associée, lors de l'occurrence de l'alarme,
peut être :
- l'activation de la tâche ;
- la signalisation d'une occurrence pour un
événement de la tâche ;
- l'activation d'une routine pour faire un traitement
spécifique. Elle s'exécute avec certaines restrictions puisqu
`elle est dans le contexte de l'exécutif (ce n'est pas une
tâche).
Une alarme peut être unique ou cyclique, absolue ou
relative. Si elle est relative, la valeur spécifiée par un
paramètre du service est un incrément par rapport à la
valeur courante du compteur (expression d'un délai de garde par exemple)
; si elle est absolue, la valeur spécifiée par un
paramètre du service définit la valeur du compteur qui active
l'alarme. Une autre valeur est spécifiée dans le cas d'une alarme
cyclique afin de préciser (en nombre de ticks) la valeur du cycle. Ainsi
on sait simplement, sur un compteur lié à l'horloge temps
réel, définir au travers de plusieurs alarmes, des tâches
périodiques de périodes différentes. La figure 4 montre
des exemples d'alarmes unique ou cyclique à partir d'un compteur de
dynamique 8 ticks.
Fig 3-8 Fonctionnement des alarmes Voici des exemples de
services :
-SetRelAlarm (<AlarmName>,
<Increment>, <Cycle>) : arme l'alarme désignée avec
une valeur relative, éventuellement cyclique. Si l'alarme est cyclique
la valeur relative indique alors la « distance » par rapport à
la première occurrence ;
- SetAbsAlarm
(<AlarmName>,<Start>,<Cycle>) : arme l'alarme
désignée avec une valeur absolue (référence
à une valeur particulière du compteur), éventuellement
cyclique. Si l'alarme est cyclique, la valeur relative indique alors la «
distance » par rapport à la première occurrence ;
- GetAlarm (<AlarmName>, <Ticks>) :
permet d'obtenir pour l'alarme désignée le nombre de ticks
restant avant l'occurrence de l'alarme ;
- CancelAlarm (<AlarmName>) :
arrête l'alarme désignée (la désactive) [7].
3-9 Conclusion
Nous avons présenté les concepts de base d'un
exécutif temps réel sans toutefois, compte tenu de la place
disponible, prétendre avoir fait une analyse exhaustive : d'autres
points seraient encore à aborder tels que la gestion de la
mémoire, la gestion des exceptions et erreurs, un approfondissement de
la communication inter-systèmes, ainsi que bien entendu
l'approfondissement des exécutifs Unix temps réel et ceux
académiques. Le noyau d'OSEK/VDX, un exemple d'exécutif statique,
développé dans le contexte de « l'électronique
embarquée » pour l'automobile, a été utilisé
afin d'illustrer la nature des services que peut apporter un exécutif et
donc montrer tout l'intérêt de la conception d'une application
s'exécutant sous le contrôle d'un d'exécutif. C'est
là une démarche naturelle puisque la
programmation d'une application sous forme de tâches
reflète bien le découpage fonctionnel que fait le concepteur lors
de l'analyse du cahier des charges. Les produits commerciaux disponibles sont
nombreux et, si initialement leur emploi était restreint aux produits de
haute technologie, actuellement on peut constater une croissance très
importante des domaines d'application [7].
|