Programmation multitâches & OS temps réel
1.0
|
Attention: les diagrammes de classes UML ne constituent qu'une vue partielle qui indique comment architecturer vos classes, mais ne représentent pas nécessairement ces classes de manière exhaustive.
La classe Chrono
implémente les fonctionnalités de mesures de temps d’un chronomètre. Son interface est définie par la figure 1. L'implémentation des méthodes de la classe Chrono
doit utiliser la librairie des fonctions timespec_
développée à la question (a) du TD-1.
m_startTime
au temps courant par un appel à restart()
.restart()
.stop()
fixe la valeur de m_stopTime
au temps courant.stop()
n’a pas été appelé après un appel à restart()
.restart()
n’a pas été appelé après un appel à stop()
.lap()
renvoie le temps courant (en millisecondes) écoulé depuis le dernier appel à restart()
.lap()
renvoie le temps (en millisecondes) écoulé entre les derniers appels à restart()
et stop()
.Implémentez la classe
Chrono
en C++ en utilisant vos fonctionstimespec_
.
Testez votre classe par exemple en utilisant votre propre montre.
L’objectif est de programmer une classe Timer
qui encapsule les fonctionnalités d’un timer Posix. La classe Timer
doit implémenter l’interface définie par la figure 2. Cette classe est abstraite puisque l’opération callback()
ne peut être implémentée au niveau de la classe Timer
. En vous référant à la partie du cours concernant les timers POSIX, écrivez le code de la classe Timer
en respectant les spécifications suivantes:
Timer()
.~Timer()
.start()
indiquent la durée du compte à rebours du timer et si le timer doit se réarmer périodiquement.stop()
arrête le compte à rebours du timer. S’il n’est pas démarré, l’appel de stop()
n’a aucun effet.callback()
doit être implémentée au niveau d’une classe spécifique dérivant de la classe Timer
.call_callback()
est une fonction de classe qui doit donc être déclarée static
en C++. En effet, la librairie des timers POSIX impose que le handler d’un timer doit être une fonction C ayant une signature bien précise. On ne peut pas utiliser callback()
comme handler pour les timers POSIX car toute méthode non statique d’une classe possède (en tant que fonction C) un premier paramètre implicite de type pointeur de la classe. La signature de callback()
en tant que fonction C est void Timer::callback(Timer* this)
. Mais si on déclare une opération comme static
, alors, sa signature sera exactement telle que spécifiée, comme dans notre cas void Timer::call_callback(int, siginfo_t*, void*)
qui est la signature attendue pour un handler de timer POSIX.call_callback()
n’a pas accès à l’objet Timer
(pas d'accès à la variable this
), il faudra donc passer le pointeur de l’objet Timer
en paramètre de la fonction call_callback
en utilisant la structure siginfo_t
dont l’adresse est passée en 2e paramètre d'un handler POSIX. Le mécanisme à utiliser est indiqué dans le cours.Pour chaque élément de classe de la figure 2, expliquez pourquoi il est public, privé ou protégé.
Expliquez quelle est l’utilité de la méthode de classe (statique)call_callback()
.
Spécifiez quelles opérations doivent être définies comme virtuelles.
Implémentez le code de la classeTimer
en C++ .
Testez-la en implémentant une classe dérivéeCountDown
imprimant à l’écran un compte à rebours à 1 Hz depuis un nombren
jusqu’à0
.
La figure 3 propose une architecture orientée objets pour refaire l’exercice du TD-1 :
Calibrator
dérive de PeriodicTimer
et implémente une méthode callback()
lui permettant de mesurer les paramètres a et b de l’équation l(t)=a×t+b où l est le nombre de boucles effectuées par la méthode Looper::runLoop()
pendant le temps t.Calibrator
et utiliser les méthodes getSample()
et stopLoop()
d'un objet Looper
. Normalement, il ne doit y avoir qu’une seule instance de Calibrator
dans votre programme, utilisé par tous les objets de type CpuLoop
.Calibrator::nLoops()
est la méthode qui convertit son paramètre duration_ms
en nombre de boucles grâce à l(t).CpuLoop::runTime(duration_ms : double)
fait appel à Calibrator::nLoops()
puis appelle la méthode runLoop
héritée de Looper
. Chaque instance de CpuLoop
est utilisable par une seule tâche dont on veut contrôler le temps d’exécution.Faites un programme analogue à celui du TD-1 en implémentant et en testant les classes de la figure 3.