Multitâche
2-1 Introduction :
Un système temps réel interagit avec un
environnement extérieur souvent complexe et en évolution. Dans le
monde réel les périphériques et l'environnement du
système évoluent simultanément (en parallèle ou
concurrence) Si l'on veut réduire la complexité de conception et
calquer fidèlement la réalité il faut s'appuyer sur de la
programmation concurrente :
· utiliser un modèle de tâches.
· utiliser des moyens de communication et de
synchronisation inter tâches ou inter processus (mémoire
partagée, boites aux lettres, files de messages, moniteurs, ...).
Le modèle utilisé en programmation des
systèmes temps réel est un modèle basé sur
la concurrence (applications concurrentes). L'exécution
de ces applications se fait généralement dans un environnement
mono-processeur.? On "simule" l'exécution concurrente des
processus par la mise en oeuvre du pseudo-parallélisme
: le parallélisme est apparent à
l'échelle de l'utiisateur mais le traitement sur le
processeur (unique) est fait séquentiellement en tirant
profit des entrées/sorties réalisées par les processus.
[4]
2-2 Notion de Tâche :
Une tâche est un programme ou une partie de programme
en exécution. Elle possède son propre environnement.
Conceptuellement, chaque tâche est associée à un
processeur virtuel comprenant :
· Son pointeur d'instructions (PC),
· Son pointeur de pile (SP),
· Sa zone de données.
Le processeur réel commute de tâche en
tâche sous le contrôle (et parfois la volonté) d'un module
particulier du NTR : l'ordonnanceur
(scheduler). A chaque commutation, le processeur
réel se retrouve chargé avec le contenu du processeur virtuel de
la nouvelle tâche. Cette opération s'appelle un
changement de contexte.
Les tâches sont des parties de code (fonctions) qui
n'acceptent pas de paramètre et qui ne retournent aucune valeur. Une
tâche doit comporter une boucle infinie
lorsqu'elle n'est jamais sensée se terminer ou
se détruire lorsqu'elle est terminée.
Dans un système multitâche monoprocesseur, les tâches
semblent macroscopiquement s'exécuter simultanément bien qu'en
vérité l'ordonnanceur alloue le contrôle du processeur
d'une manière « entrelacée ». Dans ce modèle,
les tâches ne doivent pas être programmées en faisant des
hypothèses quant à leur durée d'exécution. Le
programmeur n'a plus la maîtrise de l'attribution du processeur à
une tâche, c'est l'ordonnanceur qui s'en acquitte suivant des
règles fixées lors de sa conception. Dans ce cas, toute
temporisation basée sur la notion de boucle doit être exclue.
Par exemple un programme Temps Réel peut être
constitué d'une collection de tâches telles
que :
· des exécutions périodiques de mesures de
différentes grandeurs physiques (pression, température,
accélération etc..). Ces valeurs peuvent être
comparées à des valeurs de consignes liées au cahier des
charges du procédé ;
· des traitements à intervalles réguliers
ou programmés ;
· des traitements en réaction à des
évènements internes ou externes ; dans ce cas les tâches
doivent être capables d'accepter et de traiter en accord avec la
dynamique du système les requêtes associées à ces
évènements. Nous caractérisons ainsi une Application Temps
Réel comme étant une application multitâches [2].
2-3 Caractéristiques des tâches :
Cette section présente d'autres caractéristiques
des tâches, qui peuvent influencer l'ordonnancement : la priorité
utilisateur et la périodicité des tâches.
2-3-1 Notion de priorité :
Toutes les tâches temps réel n'ont pas la
même importance vis à vis du système. On parle alors de
priorité attribuée par le mécanisme d'ordonnancement, afin
de distinguer les tâches entre elles. Cette priorité est
définie par les échéances des tâches. Certaines ont
des échéances très proches, leur exécution est par
conséquent plus urgente, elles sont donc plus prioritaires que d'autres.
Dans un système dynamique, il peut arriver que des tâches ne
soient pas garanties, même si cette éventualité est rare.
Dans ce cas le système doit être capable de choisir entre les
tâches, afin de ne pas écarter des tâches très
importantes. Pour ce faire, des priorités peuvent être
définies par l'utilisateur.
2-3-2 Notion de périodicité :
Les tâches temps réel peuvent ne pas avoir de
priorité utilisateur, auquel cas leurs priorités sont
définies par leurs échéances. Toutefois, la notion de
périodicité que nous introduisons révèle une autre
distinction entre les tâches. Le mécanisme doit donc outre les
priorités des tâches prendre en compte le fait qu'elles peuvent
être : périodiques, apériodiques ou sporadiques.
2-3-2-1 Les tâches périodiques
:
Une tâche Ti est dite périodique de
période Pi si elle est réexécutée chaque
Pi unités de temps. Une telle tâche à ses
paramètres Ri et Di connus. Soit
Tin la niéme exécution de la
tâche Ti, Rin la date au plus tôt est
donnée par le taux d'interarrivée et Din est
déterminé par l'occurrence de la (n+1)iéme
exécution de Ti (comme illustré dans la figure 2.1).
Quand le système doit ordonnancer une tâche périodique, il
doit être capable de garantir toutes les futures occurrences de la
tâche.
Fig 2.1 Notion de périodicité
Dans la plupart des systèmes, une occurrence de
tâche périodique a son échéance égale
à sa période. Nous précisons toutefois que dans certains
modèles l'échéance peut être inférieure
à la période.
2-3-2-2 Les tâches non périodiques
: Sont réparties en deux catégories :
2-3-2-3-1 Les tâches sporadiques : Pas
d'activation régulière mais il existe un temps minimal entre deux
activations. Elles ont donc des contraintes de temps fortes.
2-3-2-3-2 Les tâches apériodiques
: Pas d'activation régulière mais avec des
échéances plus lâches et sans temps minimal entre deux
activations. C'est le temps de réponse du système qui est
privilégié [2].
2-4 Tâches matérielles, tâches
logicielles :
Un système temps réel comporte en
général des tâches soumises à des fortes contraintes
de temps, et des tâches pouvant être différées, tout
en étant exécutées dans l'intervalle de temps voulu.
Les tâches soumises à de fortes contraintes de
temps sont liées à des interruptions et
sont appelées tâches matérielles.
Les tâches différées ou
tâches logicielles sont programmées,
soit dans une boucle de scrutation soit de façon indépendante
(principe utilisé dans ce document). Elles sont alors
exécutées d'une manière
pseudo-simultanée. Lorsque la programmation
est effectuée par une boucle de scrutation, on parle d'un système
temps réel mono tâche ; dans le cas contraire, de système
temps réel multitâche. Dans tous les cas, un programme temps
réel doit gérer l'occupation du processeur en fonction des
échéances de temps liées au processus, des ressources
disponibles, des synchronisations et des échanges de données.
Dès que l'application devient complexe, les systèmes
temps réels sont programmés selon le mode multitâche
en raison d'une plus grande facilité de conception. On fera donc
attention à la distinction entre application multitâche (de type
temps partagé) et application temps réel (multitâche,
aussi, mais soumis à des contraintes temporelles).
Dans le premier cas, l'application gérera
simultanément, de façon concurrente, plusieurs tâches dont
l'ensemble traduit la globalité du processus modélisé.
Dans le second cas, l'application réagira en fonction
d'événements externes asynchrones dans le respect strict des
contraintes de temps imposées par le processus physique
modélisé.
Un système temps réel doit répondre
rapidement à des événements extérieurs pour
interagir efficacement avec l'environnement extérieur, les tâches
(logicielles) s'exécutent au niveau 0 des
priorités du processeur, alors que les ISR (tâches
matérielles) s'exécutent à des niveaux
supérieurs de priorité. Généralement
les ISR réalisent seulement les actions nécessaires
réclamées par l'interruption. La donnée entrée ou
sortante, l'information de contrôle sont passées au niveau des
tâches logicielles pour un futur traitement [2].
2-5 Etats d'une tâche :
Dans un environnement multitâche, les tâches peuvent
être dans un des quatre états suivants :
- RUNNING (en exécution) : Tache en
possession d'un processeur et en cours d'exécution.
- READY (prête à
l'exécution) : Donc en possession de toutes les ressources
nécessaire a son fonctionnement sauf d'un processeur.
- WAITING (en dormie) : Soit en attente
d'une ressource quelconque indispensable à son exécution
future.
- SUSPENDED (suspendue) : La
tâche est présente dans le projet, mais n'est pas prise en compte
par le noyau.
Les trois premiers états sont considérés
comme des états actifs (les tâches existent et jouent un
rôle dans l'application), le dernier étant un état inactif
(les tâches ne jouent pas, ou plus, un rôle dans l'application). Le
passage d'un état à l'autre se fait grâce à des
appels-système ou sur décision de l'ordonnanceur. Dans la
pratique, un changement d'état (même pour une tâche qui ne
possède pas le processeur) aura souvent pour conséquence une
commutation de contexte.
2-5-1 Transition entre tâche :
Il y a six transition d'états entre tache comme la figure
2.2 indique
· READY -* RUNNING
(START) : Correspond à une allocation
du processeur.
· RUNNING -* READY
(PREEMPT) : Correspond a une préemption du
processeur au profit d'une autre tache cette préemption est
décidée selon l'algorithme d'ordonnancement utilisé.
· RUNNING -* WAIT
(WAIT) : Due à un appel system impliquant
l'attente d'une ressource du system (waitEvent),
· WAIT -*
READY(RELEASE) : Appelé réveil
de la tache
· SUSPENDED -* READY
(ACTIVATE): Activation de la tâche
désignée. 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.
· RUNNING -* SYSPENDED
(TERMINATE): Termine la tâche appelante. 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.
Fig 2-2 Transition d'état entre tache
En environnement multitâche, les taches coopèrent
en vue de la réalisation d'une activité commune, alors On
distingue 02 sortes de coopération :
· Coopération temporelle : Faisant
intervenir les notions de blocage et de déblocage de tache.
· Coopération spatiale : Se rapportant
à l'échange d'information entre tache.
Ces 02 types de coopération caractérisent
respectivement la synchronisation et la communication entre taches car les
taches ont besoin d'échanger des données pour coopérer
durant l'exécution d'une application.
Tous les échanges se feront à l'aide de
mécanismes spéciaux sous le contrôle du système. Ces
mécanismes peuvent revêtir des formes multiples : files d'attente,
événements, ... Cette multiplicité s'explique par le fait
qu'aucun mécanisme n'est vraiment satisfaisant et ne permet de couvrir
l'ensemble des besoins de communication, chacun étant adapté
à un modèle d'échange particulier. On associera la notion
de synchronisation entre tâches à celle de communication; en
effet, pour se synchroniser, les tâches seront obligées de
communiquer entre elles. Cette gestion des taches qui est la synchronisation et
la communication entre taches est assurée par un noyau tempos
réel [5] .