Académique Documents
Professionnel Documents
Culture Documents
1. Introduction.
Dans un système embarqués, les taches utilisateurs et taches systèmes sont ordonnancées et réalise
une activité après qu’un intervalle de temps se soit écoulé. Par exemple, un ordonnanceur RTOS
doit réaliser un changement de contexte périodiquement, entre tache de même priorité, pour
s’assurer que toutes les taches puissent avoir accès au processeur. Un mécanisme de
rafraîchissement de la mémoire dynamique doit être exécuté régulièrement pour éviter la parte des
données. On retrouve des contraintes temporelles dans les systèmes réseau embarqués, dans les
outils de débogage, etc….
Dans tous les cas, une application embarquée a besoin d’ordonnancer les événements à venir. Cet
ordonnancement est réalisé grâce est réalisé grâce à un timer et ses services associés.
Les timers sont des sous-ensembles de nombreux systèmes temps réels. Un timer est un
ordonnancement d’un évènement à venir selon une valeur temporelle prédéfinie, à l’image du
réglage d’un radio réveil.
Un système embarqué complexe est constitué de nombreux modules software différents et de
composants, chacun nécessitant un timer avec des valeurs d’expirations (timeout) différentes.
La plupart des systèmes embarqués utilisent deux types de timers pour conduire les activités
sensibles : des timers hardware et des timers software.
Les timer hardware sont dérivés de composants physiques qui interrompent le processeur lors de
l’expiration de leur timout. Les opérations nécessitant de la précision ou une latence prédictible
utilisent des timer hardware.
Les timers software sont des évènements software qui sont ordonnancés au travers services
software (software facility). Ces services permettent d’ordonnancer efficacement des évènements
software qui ne demandent pas une très grande précision. Des exemples se services sont :
1
Les routines d’interruptions des timer.
Les opérations liées aux timer.
Les timer software.
Les services de management des timers software.
2
3. Les PIT (programmable Interval Timers).
Le PIT, aussi connu comme composant hardware timer (timer chip), est un composant
conçu principalement pour fonctionner comme un compteur d’évènements, pour indiquer
des durées écoulées, pour générer des événements à intervalle de temps régulier.
La fonctionnalité du PIT est souvent incorporée dans le processeur embarqué, où il est appelé
timer intégré (timer on chip). Les PIT sous forme de composants externes (timer chip) sont
utilisés pour réduire le traitement du processeur.
Il existe diverses variétés de Timer sous forme de composants (timer chip), mais ils possèdent
tous des caractéristiques générales communes. Par exemple, une entrée d’horloge avec une
fréquence fixe, mais aussi un ensemble de registres de contrôle programmables. Le rythme
d’interruption du timer (timer interrupt rate) est le nombre d’interruptions que le timer généré
par seconde. Ce rythme est calculé à partir de la fréquence de l’horloge d’entrée et est imposé
dans un registre de contrôle du timer.
La valeur de décompte du timer (timer countdown value) détermine le moment de la
prochaine apparition de l’interruption du timer. Cette valeur de décompte est chargée dans l’un
des registres de contrôle du timer et est décrémenté à chaque cycle de l’horloge d’entrée.
Les autres registres de contrôle internes au timer déterminent les autres modes de
fonctionnement du timer, comme par exemple imposer périodiquement (ou pas) une
interruption et si la valeur de décompte doit être rechargée à la prochaine interruption.
L’initialisation des composants timer (timer chip) est réalisée au démarrage du système.
Généralement, l’initialisation du composant timer impose les étapes suivantes :
Le comportement de la sortie du composant timer (timer chip) est programmable à travers des
registres de contrôle, le plus important étant le registre du rythme d’interruption (timer
interrupt-rate register ou TINTR), qui est de la forme :
TINTR=F ( x )
avec x étant la fréquence du crystal. Les constructeurs de timer chip fournissent cette fonction
et les informations sont disponibles dans les documents constructeurs.
Le rythme d’interruption du timer (timer interrupt rate) est le nombre d’occurrences
d’interruption du timer par seconde. Chaque interruption est appelée tick, elle représente une
unité de temps. Par exemple, si un timer possède un rythme d’interruption de 100 ticks,
chaque tick représentera une durée écoulée de 10 ms.
3
La possibilité de générer des événements de manière périodique de la part du PIT est
importante dans beaucoup de noyaux temps réel. Au cœur du noyau temps réel, on trouve
l’annonce d’une occurrence d’une interruption du timer (tick annoucement), depuis l’ISR vers
le noyau, et également vers l’ordonnanceur du noyau si celui-ci existe. La majorité des
ordonnanceurs respectent un algorithme et l’ordonnancement des taches à chaque tick.
La mise à jour de l’horloge système. A la fois le temps absolu et le temps écoulé sont
mis à jour. Le temps absolu (absolute time) est conservé sous la forme d’un calendrier,
c’est-à-dire date, heure, minutes et secondes. Le temps écoulé (elapsed time) est
habituellement conservé sous forme de ticks et indique depuis combien de temps le
système est en fonctionnement depuis son démarrage.
L’appel d’une fonction interne du noyau pour notifier le passage d’une période pré
programmée. Dans la suite de ce cours, cette fonction sera appelée
announce_time_tick.
L’acquittement de l’interruption, la réinitialisation des registres de contrôle du
timer, et le retour d’interruption.
La fonction announce_time_tick est appelée dans le contexte d’une ISR ; donc toutes les
restrictions applicables dans une ISR le sont également dans la fonction announce_time_tick. En
réalité, la fonction announce_time_tick est une partie de l’ISR du timer. La fonction
announce_time_tick est appelée pour notifier à l’ordonnanceur du noyau l’apparition d’un tick du
timer. Aussi important est l’annonce du tick du timer au service de gestion du timer software (
soft-timer handling facility ) qui sont responsables de la gestion des timers software lors de
chaque tick. Ces concepts sont illustrés ci-dessous.
4
5. Un modèle pour implémenter le service de gestion du timer software (soft-timer handling
facility).
Les fonctions réalisées par le service de gestion du timer software, que nous appellerons
dorénavant timer facility permettent :
5
Dans le modèle ISR vers tache de traitement (ISR-to-processing-task), la tache de travail (worker
task) doit maintenir, au niveau de l’application, une table de décompte des timers (timer-
countdown-table) basée sur une granularité de 100 ms. Dans notre exemple, la table a trois valeurs
de décompte : 2, 3 et 5 représentant 200 ms, 300 ms, et 500 ms qui représentent les valeurs de
timeout associées aux timer soft. Une fonction d’expiration du timer, installée au niveau de
l’application, sera associée à chaque timer comme le montre la figure suivante.
Les trois timer soft, qui seront simplement appelés timer sauf si spécifié autrement, sont décrémenté
par la tache de travail (worker task) à chaque fois qu’elle s’exécute. Lorsque le compteur arrive à
0, le timer d’application a expiré. Dans cet exemple, le timer de 200 ms et la fonction associée
App_timeout_fn1, que l’application installe, est invoqué. Comme indiqué dans les deux figures
précédentes, une seule ISR du timer dirige trois timers d’applications au niveau des taches,
fournissant une bonne raison d’appeler ces timers « timer soft ». La diminution du nombre d’ISR
installées associé aux timers améliore les performances générales du système.
Ces timers installés au niveau de l’application sont appelés soft timers parce que leur traitement
n’est pas synchronisé avec les tick du timer hardware.
Il est intéressant d’explorer plus en profondeur ce concept en examinant les retards possibles qui
peuvent apparaitre le long du trajet qui mène au timer tick.
6
5.1 Les retards associés au traitement.
Le premier retard est dû à l’arrivée d’évènement, le retard dans l’ordonnancement des taches.
Comme indiqué précédemment, la maintenance des timers soft est une partie de la fonction
ISR_timeout_fn et implique la décrémentation d’une valeur lors de l’expiration du timer. Lorsque
le temps d’expiration atteint 0, le timer expire et la fonction associée est invoquée. Comme la
fonction ISR_timeout_fn est une partie de l’ISR, elle doit réaliser le minimum de travail possible
et retarder la majorité du travail pour une étape suivante hors du contexte de l’ISR. Les
implémentations typiques le vrai travail soit à l’intérieur d’une tache de travail (worker task) qui
est une tache daemon dédiée soit au niveau de l’application qui a installé le timer. Le minimum de
travail réalisé dans l’ISR par la fonction installée implique le déclenchement d’un événement
asynchrone vers tache de travail (worker task), ce qui typiquement réalisé par un appel au noyau
du type event_send. Alternativement, le déclenchement peut aussi se traduire par le relâchement
d’un sémaphore sur lequel tache de travail (worker task) est bloquée. Le retard de notification
provoqué par la génération de l’événement depuis l’ISR vers la tache daemonest le premier niveau
de retard, comme indiqué à la figure suivante. Notez que la fonction du noyau event_send et la
fonction de relâchement du sémaphore doivent être appelable depuis l’ISR.
Le second retard est lié à la priorité dans l’ordonnancement des taches. Dans un RTOS classique,
les taches peuvent être exécutées avec différents niveaux de priorité. Par exemple, une tache de
travail (worker task) qui réalise une fonction liée à l’expiration du timer peut ne pas avoir la plus
haute priorité d’exécution. Dans un ordonnancement avec priorités, une tache de travail (worker
task) doit attendre que toutes les taches de plus haute priorité terminent leur exécution avant de
pouvoir continuer son exécution. Dans un ordonnancement du type Round Robin (tourniquet), la
tache de travail (worker task) doit attendre son tour (cycle d’ordonnancement) afin de s’exécuter.
Ce second niveau de retard est représenté à la figure suivante.
Un autre retard est introduit lorsque l’application installe de nombreux timers soft. Ce point sera
présenté lors du traitement des roues temporelles (timing wheels).
7
Une un soft-timer facility doit permettre une insertion efficace d’un timer, sa suppression, son
annulation et sa mise à jour. Ces exigences peuvent, en pratique, entrer en conflit les unes avec les
autres. Par exemple, prenons le cas suivant d’une implémentation des timer sous forme de liste
chainée.
La manière la plus rapide de démarrer un timer et de l’insérer soit en tete de la liste des timers, soit
au niveau de la queue de la liste des timers si le structure des données d’entrée des timers contient
une double liste chainée.
Comme la liste des timers n’est pas triée selon un ordre particulier, le maintien des ticks des timer
peut devenir couteux. La mise à jour de la liste des timer à chaque tick necessite que la tache de
travail (worker task) parcoure la liste chainée entièrement et met à jour chaque entrée de timer.
Lorsque le compteur arrive à 0, la fonction callout est appelée. Un handle timer est retourné à
l’application si l’installation du timer a été réalisée. L’annulation d’un timer nécessite aussi une
tache de travail (worker task)qui traverse la liste entière. Chaque entrée timer est comparée au
handle timer, et , lorsqu’il sont identiques, l’entrée du timer particulier est retirée de la liste timer.
Comme indiqué à la figure suivante (liste des timers non triée), alors que l’installation du timer
peut être réalisée en un temps constant, l’annulation du timer et sa mise à jour peuvent nécessiter
O(N) dans le pire cas.
Le tri des temps d’expiration dans l’ordre croissant résulte en un enregistrement efficace des timer.
Dans l’exemple, uniquement la mise à jour de la première entrée est nécessaire, car tous les autres
timers sont décrémentés implicitement. En d’autres mots, lorsque l’on insère des nouveaux timers,
la valeur du timeout est modifiée par rapport à la première entrée avant d’insérer le timer dans la
liste. La liste suivante est triée.
8
Comme indiqué dans ma figure précédente, alors que les enregistrements sont réalisés à temps
constant, les installations des timer nécessitent des recherches et insertions. Le cout est 0(log(N)),
où N est le nombre d’entrée dans la liste timer. Le cout de l’annulation est aussi 0(log(N)).
Le soft timer facility installe un timeout périodique (a clock tick) en utilisant le timer
hardware sous-jacent. Ce timer hardware périodique, pilote tous les timers soft installé avec
les services (facility). La fréquence du timeout détermine la précision du service timer soft.
Par exemple, si la précision définit l’occurrence d’un tick toutes les 50 ms, chaque slot
représente le passage de 50 ms, qui est le plus petit timeout que l’.on peut implanter dans les
services timers. De plus, une double liste chainée d’handlers d’évenements timeout
(appelée callbacks functions ou callbacks) est stockée dans chaque slot (ou time slot), qui est
invoquée à l’expiration du timer. Cette liste de timers représente les évènements avec la
même durée d’expiration.
Chaque timer slot est représenté à la figure suivante.
A chaque tick, un mécanisme d’incrémentation utilise un repère (clock dial) permet de passer
au slot suivant. On retourne au premier slot du tableau après avoir terminé un parcours
complet du tableau. C’est cette idée qui donne le terme de roue de synchronisation.
9
En conséquence, lorsque l’on installe un nouvel événement timer, la position courante du
repère (clock dial) est utilisé comme un point de référence pour déterminer le slot (ou time
slot) dans lequel un nouvel handler d’évènement sera stocké.
Prenons l’exemple suivant et supposons que chaque time slot représente une durée de 50 ms,
ce qui signifie que 50 ms secondes se sont écoulées entre les ticks.
Le time slot marqué +200 .est le slot dans lequel sera stocké l’handler d’événements si le
développeur veux ordonnancer un timeout de 200 ms dans le futur. La position du clock dial
est le temps de départ de la ligne temporelle (time line), autrement dit le point de référence
(reference point). Au minimum, le handle timer retourné par l’application appelante est
l’index du tableau.
10
Par exemple, pour ordonnancer une timeout à 400 ms lorsque le clock dial est à la position 1,
cet évènement doit être sauvé dans le buffer de dépassement d’évènement (buffer overflow
event) jusqu’à ce que la clock dial atteigne la position 2. Pour ordonnancer un évènement
timer à 500 ms lorsque la clock dial est en position 1, cet évènement doit être conservé dans le
buffer de dépassement d’évènement (buffer overflow event) jusqu’à ce que la clock dial
atteigne la position 3. Les évènements expirés en position 2 et position 3 doivent être traité en
priorité, et alors les nouveaux évènements seront installés dans. Le buffer de dépassement
d’évènement (buffer overflow event) doit etre examiné pour voir si de nouveaux évènements
ont besoin d’être ordonnancés lorsque le clock dial vers le slot suivant à chaque tick
d’horloge. Ce procédé implique que les événements être conservé dans le buffer de
dépassement d’évènement (buffer overflow event) soient triés dans l’ordre croissant. Les
nouveaux évenements sont insérés dans l’ordre et peut devenir couteux si le buffer de
dépassement d’évènement (buffer overflow event) contient un grand nombre d’entrées.
Un autre problème associé à la roue de synchronisation est la précision des timeouts installés.
Prenons la situation dans laquelle un évènement timer est ordonnancé pour 150 ms alors que
l’horloge est en train d’évoluer mais avant que le tick annoucement atteigne la roue de
synchronisation. Est-ce que l’évènement timer doit être ajouté dans un slot à 150 ms ou placé
dans un slot à 200 ms ? En moyenne, l’erreur est approximativement la moitié de la durée d’un
tick, donc dans cet exemple 25 ms.
Un autre problème important concerne le temps d’appel (invocation time) des callbacks
installés dans chaque time slot. En théorie, les callbacks doivent être invoqués au même
instant que l’expiration, mais en réalité cela est impossible. Le travail réalisé par chaque
callback est inconnu, donc leur temps d’exécution l’est également. En conséquence, aucune
garantie ou mesure prédictible existe concernant l’instant d’appel d’une callback placée en
dernière position de la liste. Ce problème introduit un non déterminisme dans le système et ce
n’est pas souhaitable. La figure suivante illustre ce problème.
11
Le handler d’évènement 1 est invoqué à l’instant t1 lorsque le timeout vient juste d’expirer. De
la même manière, le handler d’évènement est invoqué à l’instant tn lorsque les (n-1) handlers
d’évènements ont terminé leur exécution. Les intervalles x et y sont non déterministes car la
durée d’exécution de chaque handler est inconnue. Ces intervalles sont aussi non bornés.
Idéalement, les services des timers peuvent garantir une borne supérieure. Par exemple,
indépendamment du nombre de timers déjà installés dans le système, l’handler d’évènement n
est invoqué avant 200 ms à partir du temps exact d’expiration. Ce problème st difficile et la
solution est spécifique à l’application.
12
En effet, avec la roue de synchronisation hiérarchique, il y aura plusieurs tableaux.
Comme 10*100 ms =1 s, on aura 10 entrées/s dans le premier tableau (à gauche) de la figure
suivante.
Or 60 s = 1 minute, donc 60 entrées/minute dans le second tableau (celui du milieu).
Enfin, dans le troisième tableau (celui de droite), on aura 5 entrées pour 5 minutes.
La réduction de l’espace attribué permet la construction de timer de haute précision avec une
très large gamme de durée.
Par exemple, il est possible d’installer des timeouts de 2 minutes, 4 secondes et 300 ms.
L’handler timeout est installé dans le slot 3minutes en premier. L’handler timeout détermine
qu’il y a encore 4,3 secondes lorsque les deux minutes arrivent. L’handler s’installe elle-même
dans le slot de timeout de 4 secondes. Une fois de plus, lorsque les 4 s se sont écoulés, le
même handler détermine qu’il reste 300 ms avant l’expiration du timer. Finalement, l’handler
est réinstallé dans le slot timeout associé à 300 ms. Le travail est réalisé par l’handler lorsque
les 300 ms expirent.
13
Le premier groupe d’opérations est destinés aux développeurs de BSP. Il est considéré
comme des opérations de bas niveau. Chaque opération du groupe porte un nom de fonction
fictif. Les noms réels dépendent des implémentations.
Opérations du groupe 1 :
Le second groupe d’opérations comprend les opérations sur le cœur du timer qui sont
fortement utilisées par les modules du système et les applications. On peut trouver ces
opérations dans des services de gestion des timers (facility handling timer) indépendants ou
bien intégrés au noyau. Chaque opération du groupe porte un nom de fonction fictif. Les noms
réels dépendent des implémentations.
Les opérations timer_create et timer_start permettent à l’appelant de démarrer un timer qui
expirera après une durée. La fonction fournie par l’appelant est appelée à l’expiration du timer,
qui est spécifiée relativement à l’appel de l’opération timer_start. A travers ces opérations sur
les timers, des applications peuvent installer des timers software (utiles par exemples pour des
applications TCP/IP, du polling sur des E/S, etc…).
Opérations du groupe 2 :
14
appelé lors de l’expiration du timer.
De sortie : un ID pour la structure timer nouvellement
crée.
Timer_delete Supprime un timer. Cette opération supprime un timer software
précédemment crée, libérant la mémoire occupée par une structure
timer. Cette opération prend comme paramètre d’entrée l’ID du
timer précédemment créé.
Timer_start Démarre un timer. Cette opération installe un timer soft
précédemment créé dans des services de gestion des timers
(facility handling timer). Le timer commence à fonctionner à la
fin de cette opération. Cette opération prend comme paramètre
d’entrée l’ID du timer précédemment créé.
Timer_cancel Annule un timer en execution. Cette opération annule e timer en
retirant le timer en exécution des services de gestion des timers
(facility handling timer). Cette opération prend comme paramètre
d’entrée l’ID du timer précédemment créé.
Le troisième groupe est principalement utilisé par les applications de niveau utilisateur. Ces
opérations interagissent soit avec le système d’horloge, soit avec la RTC. Une librairie du
système offre ces services. . Chaque opération du groupe porte un nom de fonction fictif. Les
noms réels dépendent des implémentations.
Opérations du groupe 3 :
15