Sie sind auf Seite 1von 28

TP Temps Rel

Jrme Pouiller <j.pouiller@sysmic.org>


Polytech Paris - Mars 2012

Table des matires


1

Avant de commencer

1.1

Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.1.1

Rfrences des pages de man . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.1.2

Standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.2

Erreurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.3

Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Watch file

2.1

Par scrutation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.2

Par notification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Ordonnancement

3.1

Rate Monotonic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.2

Earliest Deadline First . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.3

Ordonnancement conjoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.4

Serveurs de tches asynchrones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.5

Sporadic Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.6

Serveurs diffr et sporadique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.7

Partage de ressources - Inversions de priorits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.8

Partage de ressources - Dead Locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.9

Inversion de priorit - 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.10 Inversion de priorit - 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10


3.11 Inversion de priorit - 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.12 Contraintes de prcdence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4

Protection des structures de donnes

11

Tricky conditions

13

Structures de donnes et mutex

14

Protection de ressources

15

Threads et mutex

16

Tches et smaphores Xenomai

17

10 Implmentation dordonnanceurs

AVANT DE COMMENCER

18

10.1 Algorithmes dordonnancement de tches indpendantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18


10.2 Algorithmes dordonnancement de tches apriodiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
10.3 Ordonnancement et ressources partages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
11 Libtimer

19

11.1 Version synchrone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22


11.2 Version asynchrone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
12 Calculs et temps rel

22

12.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
12.2 criture du Watchdog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
12.3 Ecriture de lISR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
A Instructions dinstallation de la machine virtuelle Xenomai

24

A.1 Mise en service de limage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24


A.2 Lenvironnement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
A.2.1 Se connecter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
A.2.2 Sauver son travail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
A.2.3 Acceder internet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
A.2.4 Travailler avec emacs, geany, etc... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
B criture des programmes Xenomai

25

B.1 Documentation de Xenomai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25


B.2 Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
B.3 Vrouillage de la mmoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
B.4 A propos des noms des objets Xenomai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
B.5 Gestion des Erreurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
B.6 Excution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
C criture des modules noyau

26

C.1 Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
C.2 Excution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
C.3 Log Buffer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
D Modalits de rendu

27

E Modalits de rendu

27

Avant de commencer

Cette section est purement informative. Il ny a pas de questions lintrieur.

1.1

Documentation

1.1

Documentation

1.1.1

Rfrences des pages de man

AVANT DE COMMENCER

Comme le veut lusage, les rfrences des pages de man sont donns avec le numro de section entre parenthses. Ainsi, wait(2)
signifie que vous pouvez accder la documentation avec la commande man 2 wait. Si vous omettez le numro de section,
man recherchera la premire page portant le nom wait (ce qui fonctionnera dans 95% des cas). Le numro de section vous donne
aussi une indication sur le type de documentation que vous aller trouver. Daprs man(1), voici les diffrentes sections :
1. Executable programs or shell commands
2. System calls (functions provided by the kernel)
3. Library calls (functions within program libraries)
4. Special files (usually found in /dev)
5. File formats and conventions (e.g. /etc/passwd)
6. Games
7. Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7)
8. System administration commands (usually only for root)
9. Kernel routines [Non standard]
Vous pouvez trouver une version en ligne de la plupart des pages de man sur The Friendly Manual (http://tfm.cz).
Vous trouverez en particulier les pages relatives lAPI du noyau Linux qui ne sont pas prsentes en local sur vos machine.
Prenez nanmoins garde aux ventuelles diffrences de versions dAPI (trs rare et quasiment exclusivement sur les pages
relatives lABI du noyau).
1.1.2

Standards

Vous subissez aujourdhui tout le poids de lhistoire de la norme Posix (30 ans dhistoire de linformatique). Ne soyez pas tonns
de trouver de multiples interfaces pour une mme fonctionnalit. Cest particulirement vrai sur les fonction relatives au temps.
Nous basons ces exercice sur la norme POSIX.1-2001 que vous pourrez trouver sur http://www.unix-systems.org/
version3/online.html
Vous trouverez plus dinformations sur lhistoire des diffrentes normes existantes sur standards(7).

1.2

Erreurs

Pour indiquer quelle erreur sest produite, la plupart des fonctions Posix utilisent :
soit leur valeur de retour
soit une variable globale de type int nomme errno
Utilisez strerror(3) pour obtenir le message derreur quivalent au code de retour.
Exemple :
1

if (err = pthread_create(&tid, NULL, f, NULL))


printf("Task create: %s", strerror(err));
if (-1 == pause())
printf("Pause: %m");

1.3

Compilation

Pour la plupart des exercices, vous aurez besoin de linker 1 avec -lpthread et -lrt.
Par ailleurs, nous vous conseillons fortement de compiler avec loption -Wall de gcc et dutiliser un systme de Makefile.
1. Cest dire la phase de compilation o vous liez tous vous fichiers .o ensemble

WATCH FILE

Watch file

2.1

Par scrutation

Question 2.1. Implmenter un programme watch_files prenant en paramtre un nom de fichier. Par scrutation, votre programme dtectera chaque fois que le fichier est cr ou supprim. Votre programme devra afficher un message chaque fois quil
dtecte une modification. Vous devrez tre le plus ractif possible lors de la modification de statut du fichier.
Documentation utile: stat(2), touch(1), rm(1)

Question 2.2. Sans effectuer de mesure prcise, quel est lordre de grandeur du temps rponse de votre programme ?

Question 2.3. Que constatez-vous sur le taux dutilisation du CPU ?


Documentation utile: top(1)

Question 2.4. Afin de rendre notre programme moins gourmand, ajouter une temporisation de 1s entre chaque scrutation de
ltat du fichier.
Documentation utile: sleep(3)

Question 2.5. Que constatez-vous sur le taux dutilisation du CPU ?


Documentation utile: top(1)

Question 2.6. Quel est maintenant le temps de rponse de votre programme ?

Question 2.7. Comment voluerait le taux dutilisation du CPU et le temps de rponse si nous devions surveiller ltat de
plusieurs millions de fichiers changeant rarement ?

2.2

Par notification

Afin damliorer notre programme, nous allons utiliser un systme pilot par vnements. Ce mode de fonctionnement est assez
proche dun systme pilot par interruption.
Question 2.8. Modifiez votre programme afin dtre notifi des modifications sur votre fichier.
Documentation utile: inotify(7), inotify_init(2), inotify_add_watch(2), dirname(3), basename(3), strncpy(3), strcmp(3) read(2),
close(2)

Question 2.9. Quel est maintenant le temps de rponse de votre programme ?

Question 2.10. Que constatez-vous sur le taux dutilisation du CPU ?


Documentation utile: top(1)

Question 2.11. Comment voluerait le taux dutilisation du CPU et le temps de rponse si nous devions surveiller ltat de
plusieurs millions de fichiers changeant rarement ?

3
3.1

ORDONNANCEMENT

Ordonnancement
Rate Monotonic

Soit les tches suivantes :


Tche
A
B
C

Arrive
0
0
0

Priode
29
5
10

Capacit
7
1
2

chance
Fin de priode
Fin de priode
Fin de priode

Question 3.1. Calculez le taux dutilisation du CPU avec lalgorithme Rate Monotonic. Le jeu de tche est-il ordonnanable ?

Question 3.2. Calculez les temps de rponses des diffrentes tches.

Question 3.3. Combien de temps devrait-on simuler le systme pour avoir tous les ordonnancements possibles.

Question 3.4. Dessinez les 30 premires units de temps de lordonnancement gnr par Rate Monotonic en version premptive
puis en non-premptive. Que constatez-vous ?
Modifions le jeu de tches :
Tche
A
B
C

Arrive
0
0
0

Priode
30
5
10

Capacit
6
3
2

chance
Fin de priode
Fin de priode
Fin de priode

Dans cet exemple, le jeu de tche est dit harmonique car chaque priode est multiple des autres priodes.
Question 3.5. Calculez le taux dutilisation du CPU avec lalgorithme Rate Monotonic. Le jeu de tche est-il ordonnanable ?

Question 3.6. Dessinez les 30 premires units de temps de lordonnancement gnr par Rate Monotonic en version premptive. Que constatez-vous ?

Question 3.7. Calculez les temps de rponse des diffrentes tches. Que proposez-vous comme explication ?

3.2

Earliest Deadline First

Soit les tches suivantes :


Tche
A
B
C

Arrive
0
0
0

Priode
12
6
24

Capacit
5
2
5

chance
Fin de priode
Fin de priode
Fin de priode

Question 3.8. Calculez le taux dutilisation du CPU avec lalgorithme EDF. Le jeu de tche est-il ordonnanable ?

Question 3.9. Dterminez le nombre dunits de temps libres sur la priode.

3.3

Ordonnancement conjoint

ORDONNANCEMENT

Question 3.10. Dessinez les 24 premires units de temps de lordonnancement gnr par EDF en version premptive puis en
non-premptive.

Question 3.11. Dessinez les 24 premires units de temps de lordonnancement gnr par LST en version premptive.

3.3

Ordonnancement conjoint

On considre le jeu de tches suivant :


Tche
A
B
C
D
E

Arrive
0
0
0
7
12

Priode
12
6
24
-

Capacit
5
2
5
1
3

chance
Fin de priode
Fin de priode
Fin de priode
9
21

Question 3.12. Calculez si le systme est ordonnanable en utilisant lalgorithme Deadline Monotonic.

Question 3.13. Dessinez les 35 premires units de temps de lordonnancement gnr par Deadline Monotonic.

Question 3.14. Dessinez les 35 premires units de temps de lordonnancement gnr par EDF en version premptive.

Question 3.15. Mesurez les temps de rponses des tches apriodiques.

Question 3.16. Dessinez les 35 premires units de temps de lordonnancement gnr par LST.

Question 3.17. Mesurez les temps de rponses des tches apriodiques.

3.4

Serveurs de tches asynchrones

Soit les tches suivantes :


Tche
A
B
S

Arrive
0
0
0

Priode
12
16
10

Capacit
4
6
2

chance
Fin de priode
Fin de priode
Fin de priode

S est un serveur grant les tches asynchrones suivantes :


Tche
1
2
3

Arrive
2
14
28

Priode
-

Capacit
1
4
2

chance
Aucune
Aucune
Aucune

Question 3.18. Dessinez les 32 premires units de temps de lordonnancement gnr par RM (en version premptive) avec un
serveur par scrutation et gestion des tche asynchrone en fond de tche.

Question 3.19. Calculez les temps de rponse des diffrentes tches.


6

3.5

Sporadic Server

ORDONNANCEMENT

Question 3.20. Dessinez les 32 premires units de temps de lordonnancement gnr par RM (en version premptive) avec un
serveur diffr.

Question 3.21. Calculez les temps de rponse des diffrentes tche.

Question 3.22. Lutilisation dun serveur diffr dans cette configuration est-elle sure ?

Question 3.23. Dessinez les 32 premires units de temps de lordonnancement gnr par RM (en version premptive) avec un
serveur sporadique et utilisation des temps creux.

Question 3.24. Calculez les temps de rponse des diffrentes tche.

3.5

Sporadic Server

Soit les tches suivantes :


Tche
A
B
S

Arrive
0
0
0

Priode
24
28
20

Capacit
4
8
4

chance
Fin de priode
Fin de priode
Fin de priode

S est un serveur sporadique grant les tches asynchrones suivantes :


Tche
1
2

Arrive
4
12

Priode
-

Capacit
3
4

chance
Aucune
Aucune

Question 3.25. Dessinez les 30 premires units de temps de lordonnancement gnr par RM (en version premptive).

Question 3.26. Mesurez les temps de rponse des diffrentes tche.

3.6

Serveurs diffr et sporadique

Soit les tches suivantes :


Tche
A
S

Arrive
0
0

Priode
7
6

Capacit
2
3

chance
Fin de priode
Fin de priode

S est un serveur de tches asynchrones grant les tches asynchrones suivantes :


Tche
1

Arrive
21

Priode
-

Capacit
6

chance
Aucune

Question 3.27. Vrifiez que le systme est ordonnanable si on utilise lalgorithme RM

Question 3.28. Calculez les temps de rponse des tches priodiques.


7

3.7

Partage de ressources - Inversions de priorits

ORDONNANCEMENT

Question 3.29. Dessinez les 32 premires units de temps de lordonnancement gnr par RM avec un serveur diffr. Les
temps de rponse des tches priodiques sont-ils respects ?

Question 3.30. Pouviez-vous prdire ce comportement ?

Question 3.31. Dessinez les 32 premires units de temps de lordonnancement gnr par RM et un serveur sporadique. Les
temps de rponse des tches priodiques sont-ils respects ?

Question 3.32. Mesurez les temps de rponse de la tche 1.

Question 3.33. Quel devrait tre la capacit du serveur pour garantir le temps rel avec un serveur diffr ?

Question 3.34. Dessinez les 32 premires units de temps de lordonnancement gnr par RM et un serveur diffr avec cette
nouvelle configuration.

Question 3.35. Mesurez les temps de rponse de la tche 1.

3.7

Partage de ressources - Inversions de priorits

Soit les tches suivantes :


Tche
A
B
C

Arrive
15
0
10

Priode
25
-

Capacit
10
10
20

Priorit
1
2
3

Sections critiques
_____11111
__________
_111111111111111____

Question 3.36. Dessinez les 50 premires units de temps en utilisant un algorithme dordonnancement priorit fixe (premptif) sans prendre en compte les sections critiques.

Question 3.37. Dessinez les 50 premires units de temps en utilisant un algorithme dordonnancement priorit fixe (premptif).

Question 3.38. Proposez une modification du systme de priorit afin de rduire la latence de A. Dessinez les 50 premires
units de temps en utilisant cette nouvelle stratgie dordonnancement.

3.8

3.8

Partage de ressources - Dead Locks

ORDONNANCEMENT

Partage de ressources - Dead Locks

Soit les tches suivantes :


Tche
A
B

Arrive
0
0

Priode
10
25

Capacit
5
8

chance
Fin de priode
Fin de priode

Sections Critiques
_11 12 2
___222 21 12

Question 3.39. Dessinez les 18 premires units de temps en utilisant un ordonnancement EDF et un priority inheritance.

Question 3.40. Dessinez les 18 premires units de temps en utilisant un ordonnancement EDF et un higtest lock (aka Immediate
Ceiling Priority Protocol).

Question 3.41. Dessinez les 18 premires units de temps en utilisant un ordonnancement EDF et un original ceiling priority
protocol (OCPP).

3.9

Inversion de priorit - 1

Soit les tches suivantes :


Tche
A
B
C
D
E

Arrive
4
4
2
2
0

Priode
-

Capacit
4
1
4
1
6

Priorit
1
2
3
4
5

Sections critiques
_11_
_
_22_
_
_ 21 12 12 2_

Question 3.42. Dessinez les 16 premires units de temps ordonnancement priorit statique et sans algorithme de gestion
dinversion de priorit.

Question 3.43. Dessinez les 16 premires units de temps en utilisant un ordonnancement priorit statique et lalgorithme
dhritage de priorit.

Question 3.44. Calculez les temps de rponses des diffrentes tches en utilisant un ordonnancement priorit statique et
lalgorithme higtest lock (aka Immediate Ceiling Priority Protocol).

Question 3.45. Dessinez les 16 premires units de temps du cas prcdant.

Question 3.46. Calculez les temps de rponses des diffrentes tches en utilisant un ordonnancement priorit statique et
lalgorithme original ceiling priority protocol (OCPP).

Question 3.47. Dessinez les 16 premires units de temps du cas prcdant.

3.10

3.10

Inversion de priorit - 2

ORDONNANCEMENT

Inversion de priorit - 2

Soit les tches suivantes :


Tche
A
B
C
D
E

Arrive
4
4
2
2
0

Priode
-

Capacit
4
1
6
1
4

Priorit
1
2
3
4
5

Sections critiques
_11_
_
_11 21 1_
_
_22_

Question 3.48. Dessinez les 16 premires units de temps ordonnancement priorit statique et sans algorithme de gestion
dinversion de priorit.

Question 3.49. Dessinez les 16 premires units de temps en utilisant un ordonnancement priorit statique et lalgorithme
dhritage de priorit.

Question 3.50. Calculez les temps de rponses des diffrentes tches en utilisant un ordonnancement priorit statique et
lalgorithme higtest lock (aka Immediate Ceiling Priority Protocol).

Question 3.51. Dessinez les 16 premires units de temps du cas prcdant.

Question 3.52. Calculez les temps de rponses des diffrentes tches en utilisant un ordonnancement priorit statique et
lalgorithme original ceiling priority protocol (OCPP).

Question 3.53. Dessinez les 16 premires units de temps du cas prcdant.

3.11

Inversion de priorit - 3

Soit les tches suivantes :


Tche
A
B
C
D
E

Arrive
5
5
2
2
0

Priode
-

Capacit
4
1
6
1
5

Priorit
1
2
3
4
5

Sections critiques
_11_
_
_1 12 12 1_
_
_222_

Question 3.54. Dessinez les 16 premires units de temps ordonnancement priorit statique et sans algorithme de gestion
dinversion de priorit.

Question 3.55. Dessinez les 16 premires units de temps en utilisant un ordonnancement priorit statique et lalgorithme
dhritage de priorit.

Question 3.56. Calculez les temps de rponses des diffrentes tches en utilisant un ordonnancement priorit statique et
lalgorithme higtest lock (aka Immediate Ceiling Priority Protocol).

Question 3.57. Dessinez les 16 premires units de temps du cas prcdant.

10

3.12

Contraintes de prcdence

PROTECTION DES STRUCTURES DE DONNES

Question 3.58. Calculez les temps de rponses des diffrentes tches en utilisant un ordonnancement priorit statique et
lalgorithme original ceiling priority protocol (OCPP).

Question 3.59. Dessinez les 16 premires units de temps du cas prcdant.

3.12

Contraintes de prcdence
A

C
E

H
G

Soit les tches suivantes :


Tche
A
B
C
D
E
F
G
H

Arrive
0
0
0
0
0
0
0
0

Priode
-

Capacit
3
1
3
1
5
4
1
1

chance
12
10
20
15
25
37
20
40

Question 3.60. Dessinez les 20 premires units de temps en utilisant un ordonnancement EDF (premptif) sans prendre en
compte les contraintes de prcdence. Est-ce conforme aux besoins de lapplication ?

Question 3.61. Utilisez la mthode de Blazewicz/Chetto pour supprimer les contraintes de prcdence.

Question 3.62. Calculez de nouveau le taux dutilisation et redessinez lordonnancement ainsi gnr sur sa priode dtude.
Conclure sur lordonnanabilit de lapplication.

Protection des structures de donnes

Nous avons implment une structure de liste simplement chane :

/*
* Creation date: 2010-01-03 11:22:08+01:00
* Licence: GPL
* Main authors:
* - Jrme Pouiller <jerome@sysmic.org>
*
* Sample use of mutexes.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

11

16

PROTECTION DES STRUCTURES DE DONNES

typedef struct list_item_s {


struct list_item_s *next;
int value;
} list_item_t;
/* Add an element in list */
void list_add(list_item_t **list, int n) {
list_item_t *item = malloc(sizeof(list_item_t));
item->value = n;
item->next = *list;
*list = item;
}

26

/* Remove an element */
void list_del(list_item_t **list, int n) {
list_item_t *i, *tmp;
if ((*list)->value == n) {
tmp = *list;
*list = (*list)->next;
free(tmp);
return ;
}
for (i = *list; i->next; i = i->next)
if (i->next->value == n) {
tmp = i->next;
i->next = tmp->next;
free(tmp);
return ;
}
printf("Item %d not found\n", n);

36

}
Nous avons crit un scnario de test comme il se doit :

#define N_ITERATIONS 110


void *task(void *arg) {
list_item_t **l = arg;
int i;
list_add(l, 0);
for (i = 1; i < N_ITERATIONS; i++) {
list_add(l, i);
list_del(l, i - 1);
if (!(i % 100))
printf("%08lX: %d\n", pthread_self(), i);
}
list_del(l, N_ITERATIONS - 1);

14

return NULL;
}

24

#define NB_THREAD 2
int main(int argc, char **argv) {
// Initialize an empty list
list_item_t *l = NULL;
pthread_t id[NB_THREAD];
int i;
12

TRICKY CONDITIONS

for (i = 0; i < NB_THREAD; i++)


pthread_create(&id[i], NULL, task, (void *) &l);
for (i = 0; i < NB_THREAD; i++)
pthread_join(id[i], NULL);
if (l)
printf("Error: list is not empty\n");
return 0;

34

}
Nanmoins, le rsultat nest pas celui que nous attendions.
Question 4.1. Observez le comportement avec diffrentes valeurs de N_ITERATIONS et NB_THREAD. Quel est le problme ?
Remarque: La question peut se faire en environ 2 lignes.
Documentation utile: pthread_create(3)

Question 4.2. Rsolvez le problme. Vous prendrez soin de limiter la porte de vos sections critiques.
Remarque: La question peut se faire en moins de 10 lignes.
Documentation utile: pthread_mutex_lock(3), pthread_mutex_unlock(3)

Tricky conditions

Nous avons un problme avec le code ci-dessous :

15

/*
* Creation date: 2010-01-03 11:22:08+01:00
* Licence: GPL
* Main authors:
* - Jrme Pouiller <jerome@sysmic.org>
*
* Sample use of conditions.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static int count = 0;
void *sender(void *arg) {
int i;

25

for (i = 0; i < 10; i++) {


count++;
printf("%08lX: Increment count: count=%d\n", pthread_self(), count);
if (count == 3) {
pthread_cond_signal(&c);
printf("%08lX: Sent signal. count=%d\n", pthread_self(), count);
}
}
13

STRUCTURES DE DONNES ET MUTEX

return NULL;
}

35

void *receiver(void *arg) {


printf("%08lX: Begin waiting\n", pthread_self());
pthread_cond_wait(&c, &m);
printf("%08lX: Received signal. count=%d\n", pthread_self(), count);
return NULL;
}
int main(int argc, char **argv) {
pthread_t id[2];
pthread_mutex_lock(&m);
pthread_create(&id[0], NULL, sender, NULL);
pthread_create(&id[1], NULL, receiver, NULL);

45

pthread_join(id[0], NULL);
pthread_join(id[1], NULL);
pthread_mutex_unlock(&m);
return 0;
}
De temps en temps, le signal envoy par la thread sender nest pas reu par la thread receiver.
Question 5.1. Exacerber le problme en plaant une temporisation dans le code.
Remarque: La question peut se faire en 2 lignes.
Documentation utile: sleep(3)

Question 5.2. Utilisez le mutex m de manire approprie pour rsoudre le problme.


Remarque: La question peut se faire en 4 lignes.
Documentation utile: pthread_cond_wait(3),pthread_mutex_lock(3), pthread_mutex_unlock(3)

Structures de donnes et mutex

Un rseau de chemin de fer relie les villes A, B, C et D. Deux trains circulent sur ce rseau :
Le train circulant entre A, B et C
Le train circulant entre A, B et D
C
A

B
D

On souhaite effectuer une simulation du fonctionnement de ce rseau de chemin de fer sachant que chaque segment de la ligne
ne peut tre utiliser que par un train la fois. Nanmoins, un nombre illimit de trains peuvent se trouver dans la mme gare.
Nous avons dcid de modliser chaque train par une thread et le dplacement dune ville une autre par une temporisation d1s
pendant laquelle le segment de ligne est occup.
Nous utilisons une structure de graphe pour reprsenter notre rseau ferr. Ce choix nous permettra de facilement tendre notre
algorithme de nouveaux cas.
Question 6.1. Implmenter cette simulation.
14

PROTECTION DE RESSOURCES

Remarque: Une manire commune de reprsenter un graphe de X nuds en informatique est dutiliser une matrice de X X
boolens. Chaque valeur reprsente lexistence (ou labsence) dune arte. Dans le cas dun graphe non-orient, la matrice sera
symtrique :

0 1 0 0
1 0 1 1

0 1 0 0
0 1 0 0
Remarque: La question peut se faire en environ 80 lignes.
Documentation utile: pthread_create(3), pthread_mutex_lock(3), pthread_mutex_unlock(3), sleep(3)

Protection de ressources

Nous avons besoin denvoyer 4 messages vers un serveur distant. Nous utilisons le code ci-dessous :
#define SZ 20

void *task(void *arg) {


char *buf = (char *) arg;
send(buf, SZ);
return NULL;
}
int main(int argc, char **argv) {
pthread_t id[4];
int i;
char msgs[4][SZ] = { "HELO sysmic.org\n", "SEND jezz\n", "QUOTA\n", "BYE\n" };

14

for (i = 0; i < 4; i++)


pthread_create(&id[i], NULL, task, msgs[i]);
for (i = 0; i < 4; i++)
pthread_join(id[i], NULL);
printf("\n");
return 0;
}
Dans le cadre de notre tude, nous navons pas daccs rel au serveur, nous avons donc crit une fonction de simulation de
lenvoie des donne :
#include
#include
#include
#include

<unistd.h>
<stdio.h>
<stdlib.h>
<pthread.h>

void send_char(char data) {


double time = (double) random() / RAND_MAX * 8;
struct timespec t;
t.tv_sec = time / 1000;
t.tv_nsec = (int) (time * 1000000) % 1000000000;
nanosleep(&t, NULL);
write(1, &data, 1);
}
15

void send(char *data, size_t len) {

15

THREADS ET MUTEX

unsigned i;
for (i = 0; i < len && data[i]; i++)
send_char(data[i]);
}
Malheureusement, il semblerait quil y ait un problme car les messages reu par le serveurs ne sont pas cohrents :
Aa[1b{cB2(deC3)}DE45Ff]6

Or, pour que le serveur puisse interprter les donnes, il ne faut pas que les messages des tches concurrentes soit enchevtrs.
On propose demballer send dans une nouvelle fonction alternative permettant de rgler le problme :
int safe_send(char *data, size_t len);
Question 7.1. Implmentez safe_send.
Remarque: La question peut se faire en moins de 10 lignes.
Documentation utile: pthread_mutex_lock(3), pthread_mutex_unlock(3)
La fonction safe_send rsout le problme de cohrence, mais cause des problmes de latences dans la fonction task. Dans
certains cas, celle-ci sexcute beaucoup plus lentement quavant.
Question 7.2. crivez un scnario de test permettant de mettre en vidence et de mesurer le phnomne de latence.
Remarque: La question peut se faire en moins de 20 lignes.
Documentation utile: clock_gettime(3), memset(3)
Nous allons essayer de rsoudre le problme de latence. Pour cela, nous allons crer une nouvelle tche permettant denvoyer les
donnes de manire asynchrone.
Afin de transmettre la tche les donnes envoyer, nous devons mettre en place une structure de donnes adquate. Nous
proposons dutiliser une file (FIFO) sous la forme dun buffer circulaire.
Enfin, notre buffer circulaire ncessitera un mcanisme de rveil de la tche denvoi lorsque des donnes sont disponible dans le
buffer.
Question 7.3. Implmentez cette solution.
Remarque: La question peut se faire en moins de 40 lignes.

Documentation utile: pthread_create(3), pthread_mutex_lock(3), pthread_mutex_unlock(3), pthread_cond_wait(3), pthread_cond_signa

Threads et mutex

Question 8.1. crivez un programme avec N taches, N tant une constante dfinie la compilation. Chacune des taches contiendra une boucle incrmentant et affichant un compteur. Utilisez des smaphores pour synchroniser les boucles. Vous devriez
obtenir le comportement suivant (N = 4) :
$ ./concurence
Task: 0, count:
Task: 1, count:
Task: 2, count:
Task: 3, count:
Task: 0, count:
Task: 1, count:
Task: 2, count:
Task: 3, count:

0
0
0
0
1
1
1
1
16

TCHES ET SMAPHORES XENOMAI

Task: 0, count: 2
Task: 1, count: 2
Task: 2, count: 2
[...]
Documentation utile: pthread_create(3), pthread_cancel(3), pthread_join(3), pthread_mutex_init, pthread_mutex_lock(3),
pthread_mutex_unlock(3), pthread_mutex_destroy(3)

Question 8.2. Modifiez votre code pour crer un dead lock sur toutes les taches.

Question 8.3. Fixez N 4. Ajoutez une cinquime tache. La cinquime tache devra monopoliser processeur (ie : for(;;);).
En modifiant les priorits des taches, produisez une inversion de priorit.
Remarque: Sur un systme multicoeurs, il est possible que vous ayez besoin de crer autant de tches que de coeurs afin de
monopoliser le systme.
Documentation utile: pthread_setschedparam(3), pthread_setschedpolicy(3)

Tches et smaphores Xenomai

Afin de faire ce TP, nous vous avons fourni un Linux avec un noyau patch avec Xenomai. Ce patch nous permet davoir un
systme temps rel et profiter dune API spcialise pour le temps rel. Notez que nous utiliserons exclusivement lAPI Native
durant ce TP.
Reportez-vous lannexe B pour les informations concernant lusage de la bibliothque Xenomai.
Question 9.1. crivez un programme avec N taches, N tant une constante dfinie la compilation. Chacune des taches contiendra une boucle incrmentant et affichant un compteur. Utilisez des smaphores pour synchroniser les boucles. Vous devriez
obtenir le comportement suivant (N = 4) :
$ ./concurence
Task: 0, count:
Task: 1, count:
Task: 2, count:
Task: 3, count:
Task: 0, count:
Task: 1, count:
Task: 2, count:
Task: 3, count:
Task: 0, count:
Task: 1, count:
Task: 2, count:
[...]

0
0
0
0
1
1
1
1
2
2
2

Documentation utile: native/task.h, rt_task_create, rt_task_start, rt_task_delete, native/sem.h, rt_sem_create,


rt_sem_delete, rt_sem_p, rt_sem_v, mlockall(2)

Question 9.2. Vrifiez le bon fonctionnement de votre programme avec N = 100.

17

10

10

IMPLMENTATION DORDONNANCEURS

Implmentation dordonnanceurs

Le fichier sched.c implmente un environnement capable de simuler des ordonnanceurs. Ce simulateur est bas sur les fonction
Posix makecontext et swapcontext qui permettent de contrler manuellement le changement de contexte entre plusieurs
tches.
Question 10.1. tudiez sched.c.
Documentation utile: makecontext(3), swapcontext(3)

10.1

Algorithmes dordonnancement de tches indpendantes

Question 10.2. A partir de sched.c, modifiez la fonction elect afin dimplmenter un ordonnanceur priorit statique.

Question 10.3. Plutt que dutiliser une dure de simulation arbitraire, calculez celle-ci afin que la dure de la simulation soit
suffisante pour faire simulation hors-ligne.

Question 10.4. Implmentez un ordonnanceur Rate Monotonic. Bien entendu le membre priority de la structure task_t
ne sera pas utilis pour cet algorithme.

Question 10.5. Implmentez un ordonnanceur Earliest Dealine First. Bien entendu le membre priority de la structure
task_t ne sera pas utilis pour cet algorithme.

10.2

Algorithmes dordonnancement de tches apriodiques

Nous souhaitons ajouter des tche apriodiques. Nous les intgrons notre systme en utilisant des tche avec une priode nulle.
Question 10.6. Ajoutez la gestion de ces tches. Utilisez le temps CPU non-utilis par les tches priodiques pour excuter ces
tches. Vous navez pas besoin de grer de priorits entre les tches asynchrones.

Question 10.7. Effectuez la gestion des tches apriodiques dans un serveur de scrutation (polling server).

Question 10.8. Effectuez la gestion des tches apriodiques dans un serveur diffr (defferable server)

Question 10.9. (Bonus) Effectuez la gestion des tches apriodiques dans un serveur sporadique (sporadic server).

Question 10.10. Implmentez lalgorithme de Round-Robin.

18

10.3

10.3

Ordonnancement et ressources partages

11

LIBTIMER

Ordonnancement et ressources partages

Nous souhaitons ajouter la gestion des mutex dans notre systme. Le patch sched_mutex.patch ajoute les structures ncessaire pour la gestion des mutex.
Question 10.11. Appliquez sched_mutex.patch votre implmentation dordonnanceur priorits statiques et implmentez les fonctions lock et unlock ;

Question 10.12. Implmentez un scnario avec un deadlock.

Question 10.13. Implmentez un scnario avec une inversion de priorit.

Question 10.14. Implmentez lalgorithme ICPP (Immediate Ceiling Priority Protocol).


Documentation utile: qsort(3)

Question 10.15. (Bonus) Implmentez lalgorithme dhritage de priorit.


Documentation utile: qsort(3)

Question 10.16. (Bonus difficile) Dans notre simulation, les date de premption sont connue lavance. Par consquent, nous
avons pu nous affranchir des problme de rentrance. Modifier votre implmentation dhritage de priorit afin de la rendre
rentrante.
Question 10.17. (Sujet de thse) Ajoutez lordonnanceur la possibilit dordonnancer les tches sur plusieurs processeurs
simultanment. Maintenez votre implmentation dhritage de priorit fonctionnelle (et rentrante). Garantissez des temps de
rponse de vos algorithme en o(n) + o(s) (o n est le nombre de tche et s le nombre de sections critiques). Vos propositions sont
envoyer Ingo Molnr, auteur des mutex hritage de priorit, de lordonnanceur Completly Fair et de la premption dite
Temps Relle sur le noyau Linux.

Question 10.18. Implmentez lalgorithme OCPP (Original Ceiling Priority Protocol).


Documentation utile: qsort(3)

Question 10.19. Dtectez les possibles inversions de priorits dans les fonctions m_lock, m_unlock.

Question 10.20. Dtectez les dead locks dans les fonctions m_lock, m_unlock.

11

Libtimer

On se propose dimplmenter une bibliothque libtimer permettant de lancer des tches une date fixe ou aprs une certaine
priode. Le fonctionnement de cette bibliothque est dcrit dans timer.h :
/*
* Author: Jrme Pouiller <jerome@sysmic.fr>
* Created: Fri Dec 11 22:57:13 CET 2009
* Licence: GPL
*
* Define interface for timer services.
*/

19

11

LIBTIMER

#ifndef MYTIMER_H
#define MYTIMER_H
#include <pthread.h>
#include <time.h>
/* Helper to define a task */
typedef void (*task_t)();
/* INSERT YOUR mytimer_s DEFINITION HERE */

19

/* Contains all needed data */


typedef struct mytimer_s mytimer_t;
/*
* All following functions return
* - 0 on success
* - another value on error
*/

29

/*
* Initialize new timer instance.
* Instance is returned using parameter out.
* User have to call this function first
*/
int mytimer_run(mytimer_t *out);
/* Stop timer instance */
int mytimer_stop(mytimer_t *mt);

39

/* Add a task to timer. Task will be executed at time tp */


int mytimer_add_absolute(mytimer_t *mt, task_t t, const struct timespec *tp);
/* Add a task to timer. Task will be executed in ms milliseconds */
int mytimer_add_msecond(mytimer_t *mt, task_t t, unsigned long ms);
/* Add a task to timer. Task will be executed in s seconds */
int mytimer_add_second(mytimer_t *mt, task_t t, unsigned long sec);
/* Add a task to timer. Task will be executed in h hours */
int mytimer_add_hour(mytimer_t *mt, task_t t, unsigned long h);

49

/* Remove first occurence of task t from timer. */


int mytimer_remove(mytimer_t *mt, task_t t);
#endif /* MYTIMER_H */

La structure mytimer_s (que vous dfinirez) contient tout le contexte dexcution.


Les tches lancer sont dcrite par le type task_t.
Lutilisateur de la bibliothque commencera par un appel mytimer_run.
Il ajoutera les tches avec les fonctions mytimer_add.
mytimer_add_absolute excute la tche une heure fixe donne tandis que les autres fonctions mytimer_add excutent la tche un temps relatif linstant prsent. Par exemple, mytimer_add_second(s, t, 3) excutera t 3
secondes aprs lappel cette fonction.
Toutes les fonctions de libtimer retournent un entier. Il sagit dun code derreur. Vous tes libre dans le choix des codes
de retour.

On considre que les tches sont exemptes de bugs et quelles ne tentent pas de mettre en pril la stabilit de votre bibliothque
et du systme.

20

11

LIBTIMER

libtimer tentera dtre le plus prcis possible dans lheure de lancement des tches. Nanmoins, on ignorera le biais introduit
par le systme dexploitation et les autres processus.
Afin de vous aider, vous trouverez une implmentation de liste chane dans list.h et list.c :

15

/*
* Author: Jrme Pouiller <jerome@sysmic.fr>
* Created: Fri Dec 11 22:57:54 CET 2009
* Licence: GPL
*
*/
#ifndef LIST_H
#define LIST_H
#include <stdlib.h>
#include <stdbool.h>
typedef struct list_item_s {
/* ADD YOUR MEMBERS HERE */
struct list_item_s *next;
} list_item_t;
#define EMPTY_LIST NULL
#define NEXT(s) (s)->next
#define FOREACH(I, LIST) for (I = LIST; I; I = NEXT(I))
bool list_isEmpty(list_item_t *l);
int list_size(list_item_t *list);

25

/* Add an element. Dont forget to allocate it before */


void list_add(list_item_t **list, list_item_t *item);
/* Remove an element. Return removed element. Dont forget to free it AFTER removing
*/
list_item_t *list_remove(list_item_t **list, list_item_t *item);
#endif /* LIST_H */
/*
* Author: Jrme Pouiller <jerome@sysmic.fr>
* Created: Fri Dec 11 22:57:54 CET 2009
* Licence: GPL
*
*/
#include "list.h"

bool list_isEmpty(list_item_t *l) {


return (l == EMPTY_LIST);
}
int list_size(list_item_t *list) {
int count = 0;
list_item_t *i;
FOREACH(i, list)
count++;
return count;

19

21

11.1

Version synchrone

12

CALCULS ET TEMPS REL

/* Add an element. Dont forget to allocate it before */


void list_add(list_item_t **list, list_item_t *item) {
item->next = *list;
*list = item;
}

29

/* Remove an element. Return removed element. Dont forget to free it AFTER removing
*/
list_item_t *list_remove(list_item_t **list, list_item_t *item) {
list_item_t *i;
if (*list == item) {
*list = (*list)->next;
return item;
}
FOREACH(i, *list)
if (i->next == item) {
i->next = item->next;
return item;
}
// Nothing found
return NULL;

39

11.1

Version synchrone

On considre pour linstant que le temps dexcution des tches est nul.
Question 11.1. Implmentez libtimer tel que dcrit dans le fichier dentte timer.h.
Documentation utile: pthread_cond_timedwait(3), pthread_cond_wait(3), pthread_cond_signal(3), clock_gettime(2), sleep(3),
pthread_create(3), pthread_mutex_lock(3), pthread_mutex_unlock(3), pthread_mutex_init(3), pthread_cond_init(3), pthread_cancel(3),
ctime_r(3)

11.2

Version asynchrone

Nous avons suppos dans que le temps dexcution des tches taient nul. Nous souhaitons maintenant crire la version finale de
la bibliothque excutant les tches de manire asynchrone.
Question 11.2. Modifiez votre bibliothque de manire excuter les tches de manire concurrente.
Documentation utile: pthread_attr_setdetachstate(3), pthread_create(3), pthread_attr_init(3)

12
12.1

Calculs et temps rel


Introduction

Ce TP est inspir du fonctionnement dun tlphone portable. Sur ce systme, un microphone utilise un DMA pour placer les
donnes acquises en mmoire. Une interruption est ensuite dclenche lorsque que le DMA contient assez de donnes par tre
traites. Le tlphone portable utilise ensuite un systme de compression par paquet dont le temps de traitement est variable.
Enfin, le tlphone doit envoyer ses donnes lantenne toutes les 4.6ms, soit une frquence de 217Hz environ.
Afin de faire ce TP, nous vous avons fourni un Linux avec un noyau patch avec Xenomai. Ce patch nous permet davoir un
systme temps rel et profiter dune API spcialise pour le temps rel.

22

12.2

12.2

criture du Watchdog

12

CALCULS ET TEMPS REL

criture du Watchdog

Nous allons utiliser le priphrique Real Time Clock (RTC) prsent sur les architectures i386 pour gnrer des interruptions
ncessaires la suite de lexercice.
A chaque priode, la RTC produit une interruption. Le driver RTC traduit cette interruption par lcriture dun octet sur le fichier
/dev/rtc0. Le fichier rtc.c vous donne un exemple de programmation du priphrique RTC.
Question 12.1. tudiez le programme, compilez-le, puis programmez la RTC 2 Hz et lancez trois priodes.
Nous utiliserons la bibliothque Xenomai pour les questions suivantes. Reportez-vous lannexe B pour plus dinformations sur
son utilisation.
Nous allons dans la suite du TP travailler avec linterruption produite par la RTC. Une mauvaise gestion de linterruption pourra
produire un IRQ storm. Nous allons donc mettre en place watchdog afin de rendre notre dveloppement plus confortable. Notre
watchdog nous permettra de dtecter si notre systme ne rpond plus et de reprendre la main dessus.
Question 12.2. Modifiez rtc.c de manire ajouter un watchdog. Dclencher votre watchdog sur 1 seconde. Lorsque le
watchdog se dclenche, dsactivez la RTC et avertissez lutilisateur.
Documentation utile: native/alarm.h, rt_alarm_start, rt_alarm_create, rt_alarm_delete, rt_alarm_wait, native/task.h,
rt_task_create, rt_task_delete, rt_task_start, rt_timer_ns2ticks

12.3

Ecriture de lISR

Maintenant que nous avons un bon outil de test, nous pouvons commencer travailler sur linterruption en elle-mme.
Les interruptions doivent forcement tre excutes dans le noyau de Linux. Pour cette raison les questions suivantes sont crire
sous forme de module. Reportez-vous lannexe C pour les informations concernant le dveloppement des modules noyau.
Question 12.3. Placez une ISR sur le linterruption 8 (Real Time Clock). Dans votre ISR, grez un compteur dappel n. Afficher
n dans le buffer du noyau lorsquune interruption survient.
Documentation utile: native/intr.h, rt_intr_create, rt_intr_enable, rt_intr_delete
Remarquez le fonctionnement du nano-kernel Adeos. Votre interruption apparat dans /proc/ipipe/Xenomai alors que les
autres interruption apparaissent dans /proc/ipipe/Linux. Adeos gre Xenomai et Linux comme deux OS diffrents.
Nous allons maintenant simuler le traitement de donnes. Nous choisissons de calculer la suite de Fibonacci pour simuler le temps
de traitement des donnes. Nous utilisons cette fonction en raison de sa grande amplitude de temps de calcul. Ainsi, fibo(34)
se calcule 4 milliards de fois plus lentement que fibo(2).
Question 12.4. Faites une implmentation nave (rcursive) de Fibonacci. Affichez fibo(n % M) lorsquune interruption
survient, M tant une constante dfinie la compilation.
Augmentez M jusqu ce que le temps pass dans linterruption soit mesurable (> 100ms) lorsque n approche un multiple de M.
Remarque: Vous pouvez utilisez le timestamp produit dans le log buffer du noyau comme mesure approximative.

Question 12.5. Augmentez la frquence de la RTC 128Hz. Vrifiez le fonctionnement de linterruption.


Remarque: Vous pouvez utilisez le timestamp produit par le log buffer. Vu que lon casse le temps rel du noyau, ce timestamp
nest sont pas fiable en absolu. Nanmoins, le temps en moyenne est fiable. On peut calculer le nombre dinterruptions entre le
dbut et la fin du test et ainsi voir si on rate des interruption.

Question 12.6. Dportez le calcul et laffichage de fibo dans une seconde tache laide dune queue. Affichez le nombre
dlments dans la queue. Noubliez pas de grer les erreurs.
Documentation utile: rt_queue_create, rt_queue_delete, rt_queue_write, rt_queue_read, rt_queue_inquire, rt_task_create,
rt_task_start, rt_task_delete

23

INSTRUCTIONS DINSTALLATION DE LA MACHINE VIRTUELLE XENOMAI

Question 12.7. Ajoutez la gestion dune file de rsultats. Dans lISR, dpiler un rsultat et affichez-le. Grez intelligemment le
cas o la file est vide.
Documentation utile: native/queue.h, rt_queue_create, rt_queue_delete, rt_queue_write, rt_queue_read

Question 12.8. Chargez le CPU laide des commande dd(1) et ping(1). Vrifiez la qualit de vos taches temps relles.

A
A.1

Instructions dinstallation de la machine virtuelle Xenomai


Mise en service de limage

Nous avons besoin de configurer votre compte pour utiliser limage virtuelle patch avec Xenomai.
Ouvrez un terminal. Commencez par importer la configuration de la machine virtuelle :
vboxmanage import "/opt/TP_vms/jezz-324/Ubuntu 9.04 Xenomai 32bits-nodisk.ovf"
Cette configuration ne contient pas de dique dur. Nous en attachons donc un :
vboxmanage storageattach "Ubuntu 9.04 Xenomai 32bits" --storagectl "SATA Controller"
--port 1 --type hdd --medium "/opt/TP_vms/jezz-324/Ubuntu 9.04 Xenomai 32bitsdisk1.vmdk"
Le disque dur que nous avons ajout nest pas accessible en lecture. Nous allons utiliser le systme dimage incrmentale propos
par Virtual Box. Ainsi, vous navez besoin davoir un accs en criture que sur le fichier contenant le delta. Ce delta pourra tout
de mme atteindre quelques centaine de mgaoctet. Nous choisissons donc un emplacement en local pour le contenir :
vboxmanage modifyvm "Ubuntu 9.04 Xenomai 32bits" --snapshotfolder /var/tmp/snapshotsLOGIN/
Nous pouvons maintenant crer le premier incrment :
vboxmanage snapshot "Ubuntu 9.04 Xenomai 32bits" take "Initial"
Vous pouvez dmarrer VirtualBox et dmarrer la machine virtuelle "Ubuntu 9.04 Xenomai 32bits"

A.2

Lenvironnement

A.2.1

Se connecter

login : user
password : user
A.2.2

Sauver son travail

Dans un terminal utiliser la commande scp(1) pour vous connecter votre machine hte par lIP 10.0.2.2 :
scp -r exo1 pouiller@10.0.2.2:
Linverse fonctionne aussi videment :
scp -r pouiller@10.0.2.2:exo1 .

A.2.3

Acceder internet

Vous devez configurer votre navigateur pour utiliser le proxy de lcole.

24

A.2.4

CRITURE DES PROGRAMMES XENOMAI

Travailler avec emacs, geany, etc...

Vous avez la possibilit dxcuter des commandes en root avec la commande sudo(1) :
sudo apt-get install emacs

B
B.1

criture des programmes Xenomai


Documentation de Xenomai

Vous pourrez trouvez la documentation de lAPI de Xenomai dans /usr/share/doc/xenomai-doc/html/api ou en


ligne sur http://www.xenomai.org/documentation/xenomai-2.4/html.
Remarquez que est capable de prsenter plusieurs interfaces de programmation. Dans notre cas, nous nutiliserons que linterface
native. Par consquent, seule la section Modules/Native Xenomai API de la documentation vous sera utile.
Vous pouvez trouver les headers inclure en explorant longlet files

B.2

Compilation

Les commandes xeno-config --xeno-cflags et xeno-config --xeno-ldflags permettent dobtenir respectivement les options de compilation et les options de link utiliser pour que votre programme fonctionne avec Xenomai. Vous devrez
de plus prciser que vous utilisez la skin Native avec loption -lnative.
Par ailleurs, nous vous conseillons fortement de compiler avec loption -Wall de gcc et dutiliser un systme de Makefile.
Noubliez pas que dans un Makefile, il faut utiliser le mot-clef shell pour lancer une commande. Par exemple :
bin: file.o
gcc -Wall $(shell xeno-config --xeno-ldflags) -lnative $< -o $@
file.o: file.c
gcc -Wall $(shell xeno-config --xeno-cflags) -c $< -o $@

B.3

Vrouillage de la mmoire

En cas de ncessit, le gestionnaire de mmoire du noyau Linux peut-tre amen placer des pages de mmoire virtuelle sur le
disque dur (processus de swaping). Lorsquune de ces pages de mmoire est ncessaire, elle doit tre replace en mmoire avant
dtre utilise. Cela cre une latence qui peut poser problme dans le cas dapplication temps relles.
Un appel la fonction mlockall(1) permet de demander au noyau de vrouiller les pages de mmoire en mmoire physique :
mlockall(MCL_CURRENT | MCL_FUTURE);
La mmoire doit tre vrouille avant tout appel lAPI Xenomai.

B.4

A propos des noms des objets Xenomai

Il est possible dans Xenomai dassocier chaque objet un nom unique sur le systme. Cela permet de binder des objets entre des
processus ou entre des domaines dexcution.
Lutilisation des noms oblige tre rigoureux et correctement dtruire les objets avant de sortir des processus. Les instances
des objets resteront en mmoire.
Par consquent, nous vous conseillons de ne pas utiliser cette fonctionnalit des les exercices suivants et passer un pointeur
NULL comme nom.

25

B.5

B.5

Gestion des Erreurs

CRITURE DES MODULES NOYAU

Gestion des Erreurs

La plupart des fonctions Xenomai retournent une valeur ngative pour indiquer quune erreur sest produite. Vous pouvez utiliser
strerror(3) pour obtenir le message derreur quivalent.
Exemple classique :
if (err = rt_task_start(t, f, NULL))
printf("Task start: %s\n", strerror(-err));

B.6

Excution

Vous aurez besoin dexcuter les programmes que vous crerez avec les droits root. Nous vous dconseillons lutilisation de
sudo(1) pour lancer vos programmes car Ctrl+C sera moins ractif.

C
C.1

criture des modules noyau


Compilation

La manire classique de compiler un module noyau est de crer un Makefile contenant :


EXTRA_CFLAGS=-I/lib/modules/$(shell uname -r)/build/include/xenomai
obj-m += module.o
Puis lancer la compilation avec :
make -C /lib/modules/$(uname -r)/build SUBDIRS=$(pwd) modules
Le systme de compilation du noyau se chargera de compiler votre module avec les bonnes options.
Nous vous fournissons le fichier Makefile reprenant ces lignes.

C.2

Excution

Les modules ne sont pas des applications. Ils nont pas de fonction main. Comme cest souvent le cas lorsque lon souhaite
tendre une application en cours de fonctionnement, vous avez la possibilit de dclarer des fonctions qui seront appeles lors de
certain vnements. Les fonctions les plus utiles sont dclares par MODULE_INIT (chargement du module) et MODULE_EXIT
(dchargement du module).
Vous pourrez charger le module laide de insmod(1) et le dcharger laide de rmmod(1).
Nous vous fournissons le fichier module.c qui vous donne un squelette de module pour le noyau Linux.

C.3

Log Buffer

Le noyau possde un buffer circulaire permettant de logger des messages. Il est possible dcrire dans le buffer depuis un module
laide de printk(9) et des macros pr_debug, pr_info, pr_notice, pr_warning, pr_err, etc.... Il est possible de dumper le contenu
du buffer avec la commande dmesg(1) (utilisant lappel systme syslog(2)). Il est aussi possible de suivre lvolution du buffer
avec la commande :
tail -f /var/log/kern.log

26

MODALITS DE RENDU

Modalits de rendu

Votre rendu fera lobjet dun traitement automatis. Afin dviter tout problme, veuillez suivre les rgles suivantes.
Vous devez rendre votre travail dans une archive gzippe. Larchive devra se nommer TR-nom.tar.gz et se dcompresser
dans le rpertoire du mme nom.
Votre archives ne pas contenir de fichiers binaires. Il ne doit contenir que vos sources (fichiers sources, fichiers enttes, Makefile,
etc... ).
Aucun de vos noms de fichiers ne doit contenir de caractres despacements, accentus ou non-imprimables.
Exemple de cration de rendu :
make clean
cd ..
tar cvzf TR-pouiller.tar.gz TR-pouiller
Vous devrez envoyer votre rendu par e-mail avant le 31 Dcembre 1999 23h59 <rendus@sysmic.fr>. Votre e-mail ne
devra comporter que votre rendu comme unique pice jointe.
Le sujet du mail devra suivre la nomenclature suivante : [TR] nom (exemple : [TR] pouiller).
Enfin, le corps du mail devra contenir une ligne indiquant votre prnom, votre nom et votre email sous la forme :
* Prnom Nom <email@entreprise.dom>
Exemple :
Veuillez trouver en pice jointe le rendu de projet temps rel de :
* Jrme Pouiller <j.pouiller@sysmic.fr>
Cordialement,
-Jrme Pouiller, Sysmic
Expert Linux embarqu

Modalits de rendu

Votre rendu fera lobjet dun traitement automatis. Afin dviter tout problme, veuillez suivre les rgles suivantes.
Vous devez rendre votre travail dans une archive gzippe. Larchive devra se nommer TR-nom.tar.gz o nom sera le nom
dun membre de votre quipe que nous dsignerons par contact administratif. Votre archive devra et se dcompresser dans le
rpertoire du mme nom.
Votre archives ne pas contenir de fichiers binaires. Il ne doit contenir que vos sources (fichiers sources, fichiers enttes, Makefile,
etc... ).
Aucun de vos noms de fichiers ne doit contenir de caractres despacements, accentus ou non-imprimables.
Votre archive devra contenir sa racine un fichier nomm AUTHORS. Ce fichier devra au moins contenir les prnoms, les nom et
les email des membre de votre quipe sous la forme :
2

* Prnom1 Nom1 <email1@entreprise1.dom>


* Prnom2 Nom2 <email2@entreprise2.dom>
[...]
Les lignes ne correspondant pas cette nommenclature sont ignores
Exemple de cration de rendu :
make clean
echo * Jrme Pouiller <j.pouiller@sysmic.fr> >> AUTHORS
echo * Thibaud Hilaire <t.hilaire@sysmic.fr> >> AUTHORS
cd ..
tar cvzf TR-pouiller.tar.gz TR-pouiller

27

MODALITS DE RENDU

Vous devrez envoyer votre rendu par e-mail avant le 31 Dcembre 1999 23h59 <rendus@sysmic.fr>. Votre e-mail ne
devra comporter que votre rendu comme unique pice jointe.
Le sujet du mail devra suivre la nomenclature suivante : [TR] nom o nom est le nom de votre contact administratif (exemple :
[TR] pouiller).
Enfin, le corps du mail devra se conformer au mme formalisme que le fichier AUTHORS.
Exemple :
Veuillez trouver en pice jointe le rendu de projet temps rel de :
* Jrme Pouiller <j.pouiller@sysmic.fr>
* Thibaud Hilaire <t.hilaire@sysmic.fr>
5

Cordialement,
-Jrme Pouiller, Sysmic
Expert Linux embarqu

28

Das könnte Ihnen auch gefallen