Exécutif temps réel

Transcription

Exécutif temps réel
Exécutif temps réel
Pierre-Yves Duval (cppm)
Ecole d’informatique temps réel - La Londes les Maures 7-11 Octobre 2002
Plan
Exécutif
Tâches
Evénements et synchronisation
Partage de ressources
Communications entre taches
Gestion de la mémoire
Gestion du temps
Interruptions
Fichiers temps réel
POSIX et le temps réel
1
Rôle d’un exécutif
Principal :
- ordonnancer les exécutions des tâches
mais aussi:
- protéger l’accès aux ressources partagées
- recevoir et transmettre les signaux de synchronisations
Composé d’agences spécialisées dans un type de fonction
- gestion des tâches
- gestion des événements matériels et logiciels (de synchronisation)
- gestion communications entre tâches
- gestion du temps
- gestion des ressources partagées
- gestion de la mémoire
- gestion des exceptions
Structure d’un exécutif
Tâches applicatives
Appels de service
activation
horloge
lanceur
ordonnanceur
communication
agence
événements
agence
tâches
agence
Exécutif
temps
agence
ressources
agence
interruptions
Monde matériel
2
Exécutif ou noyau temps réel
C’est d’abord un système d’exploitation.
La principale différence entre un OS généraliste et un OS temps
réel est le comportement très
déterministe.
Ensuite on trouvera quelques différences dans l’API (voir POSIX à la fin):
-politique d’ordonnancement plus élaborée
-gestion plus précise de plus de réveils (timers) à la résolution plus fine
-plus d’ouverture sur le hardware sous-jacent en particulier les connexions aux IT matérielles
-plus de modularité dans la construction du noyau
Tâche
Agent actif d’une application avec 4 attributs:
-contexte d’exécution
registres du processeur,
pile exécution,
ressources détenues
- priorité
-état d’exécution
-état de protection (préemptible ou pas)
3
Tâche
Dans les OS d’aujourd’hui les tâches sont implantées comme des
fils d’exécution (thread).
L’ordonnanceur de l’OS gère les threads/tâches.
La notion de processus définie un espace d’adressage protégé dans
lequel s’exécute au moins une tâche (le main thread) qui est activé
quand le processus est lancé. Le processus se termine quand la dernière
tâche qu’il contient se termine.
Dans certains OS simples il n’y a pas d’espace mémoire protégé, il
y a identité entre les termes:
processus = thread = tâche
Etats d’exécution SCEPTRE
Inexistant
Supprimer
Créer
Supprimer
Hors Services
Lancer
Arrêter Arrêter
Créer
Actif
Supprimer
Continuer
Sélection
Prêt
Opération d’attente
En Cours
Préemption
En Attente
Arrivée événement
4
Synchronisation par événements
synchrones
Phases temporelles de l’occurrence d’un événement:
apparition
production
prise en compte
consommation
Code d’IT jusqu’à l’appel du service de signalisation
Délai de réveil tâche destinataire
Traitements avant effacement
Les événements sont dits synchrones si l’application consommatrice
va les lire de façon explicite.
Synchronisation par événements
synchrones
Types d’événements:
Fugace:
Si aucune tâche est en attente à son occurrence il est perdu
Mémorisé: L’occurrence est mémorisée mais aucune autre ne sera
prise en compte avant sa consommation
A compte: Mémorisé avec incrémentation du compteur à chaque
occurrence et décrémentation chaque consommation
5
Synchronisation par événements
synchrones
Services génériques événements
Créer (événement)
Supprimer(événement)
Attendre_occurrence( événement )
Signaler_occurrence( événement )
IT
Lire data
Copie mémoire
Signaler(evt)
Créer (evt)
Boucle
Attendre(evt)
Traiter data
Fin boucle
Synchronisation par événements
synchrones: exemple
/* variable condition POSIX utilisable avec rtlinux */
/*-----------------------------------------------------------*/
pthread_cond_t cond;
void coureur(){
int ret;
ret = pthread_cond_timedwait(&cond, …, délai );
courrir();
}
void arbitre(){
int ret;
decompte();
ret = pthread_cond_signal(&cond);
}
main(){
int ret;
ret = pthread_cond_init(&cond, NULL);
ret = pthread_create( …, coureur, …);
ret = pthread_create( …, arbitre, …);
attente_fin();
}
6
Signalisation asynchrone
Une tâche est associée à un signal et elle sera automatiquement activée
quand l’événement associé au signal arrivera. La tâche est appelée
pilote (handler) du signal.
La tâche n’a donc pas besoin de se mettre en attente du signal.
Exemple: signaux UNIX (lent), attachement à une IT matérielle
Services génériques signaux asynchrone:
Créer( signal )/ Détruire( signal )
Connecter( pilote, signal )
Envoyer( signal )
Il peut exister des masques qui permettent d’empêcher temporairement
la réception de signaux (avec perte, mémorisation ou comptage)
Signalisation asynchrone:
exemple
/* signal POSIX simple */
/*---------------------------*/
int stopbit;
void signalled(){
stopbit = 1;
}
main(){
stopbit = 0;
signal( SIGINT, signalled);
while( !stopbit)
{ … faire un travail qui sera arrêté par CtrlC …}
terminer_proprement();
}
7
Partage de ressources
Problème:
- gérer un nombre limité de ressources ( de 1 à n ) entre plusieurs
tâches
- assurer la modification cohérente de données partagées
Objet:
Sémaphore binaire (mutex) un utilisateur à la fois
Sémaphore à compte pour n utilisateurs maxi
Autres possibilités déconseillées en temps réel:
masquage des IT ou interdiction de préemption
Partage de ressources
Services génériques sémaphores:
Créer(sem)/Détruire(sem)
Prendre_ressource(sem) parfois appelée P()
Libérer_ressource(sem) parfois appelée V()
sem
Créer(sem)
Boucle
…
Prendre(sem)
Insérer(elem,liste)
Libérer(sem)
…
Fin boucle
Détruire(sem)
liste
Boucle
…
Prendre(sem)
exploiter(liste)
…
sortir(elem,liste)
Libérer(sem)
Fin boucle
8
Partage de ressources: exemple
/* sémaphore à compte POSIX */
/*------------------------------------*/
sem_t sem;
void consommateur(){
ret = sem_wait(&sem);
manipuler_ressource();
sem_post(&sem);
}
main(){
sem_init(&sem, …, nombre_utilisateurs);
for ( i=0; i<10; i++)
{ pthread_create( …, consommateur, …); }
attente_fin();
sem_destroy(&sem);
}
Communication entre tâches
Boite aux lettres
Service de base permettant les échanges asynchrones de données entre
des tâches concurrentes et non synchronisées
Services génériques (c’est un buffer)
Créer(boite)/Supprimer(boite)
Déposer(mesg)
Lire(mesg)
Test(mesg)
Exemple: FIFOs, tubes UNIX,
queues de messages (POSIX ou system V) (étendues au réseau QNX),
mailbox
9
Communication entre tâches
Boite au lettres: Queue de message POSIX
Tâche réceptrice dans processus 2
#define MQ "/monrep/mesgq"
mqd_t qfd;
struct mq_attr qattr;
char message_lu[20];
/* nb max msg en queue */
qattr.mq_maxmsg = 32;
/* taille maxi d’un message */
qattr.mq_msgsize = 20;
void recepteur(){
qfd = mq_open (MQ, … , &qattr);
mq_receive (qfd, message_lu,
sizeof (message_lu),…);
print(" %s " , message_lu);
mq_close(MQ);
}
Tâche émettrice dans processus 1
#define MQ "/monrep/mesgq"
mqd_t qfd;
struct mq_attr qattr;
/* nb max msg en queue */
qattr.mq_maxmsg = 32;
/* taille maxi d’un message */
qattr.mq_msgsize = 20;
void émetteur(){
qfd = mq_open (MQ, … , &qattr);
mq_send (qfd, "tout va bien", … );
mq_close(MQ);
mq_unlink(MQ);
}
Communication entre tâches
Socket: programmation répartie
Objet de communication applicatif (BSD UNIX) qui permet un
échange point à point de type boite aux lettres entre deux tâches
sur deux sites différents (sorte de queue de messages).
Ces points sont reliés aux couches réseaux de l’OS qui assurent
le transfert (TCP ou UDP pour Internet).
Intérêt: Base de la programmation distribuée
- indépendante de l’OS
- utilisables en local avec des sockets du domaine UNIX.
10
Communication entre tâches
Tableau noir
Publication de données dans un espace accessible en lecture par
tous les consommateurs.
Exemples: mémoire partagée entre processus (shared memory),
données globales entre thread d’un même processus
Services génériques:
Créer/Détruire
Afficher/Lire
Communication entre tâches
Rendez-vous
Modèle de communication très synchrone ou producteur et consommateur
doivent être présents lors de l’échange de donnée.
Exemple: support d’exécution du langage ADA
Services génériques:
Appeler_entrée demande de rendez-vous
Accepter_entrée déclaration de la capacité à recevoir des demandes
de rendez-vous
Terminer_entrée
11
Gestion de la mémoire
Selon les possibilité du hardware sous jacent on peut avoir 3 type de
gestion de la mémoire.
-espace plat ou toute la mémoire est visible et accessible par n’importe
quelle tâche
-séparation entre les espace système/noyaux et les tâches applicatives
-mémoire virtuelle séparée et protégée associée à chaque processus
L’allocation de la mémoire peut être statique (à la création) ou
dynamique (automatique) en fonction des besoins
Gestion du temps
La précision dépend du support matériel
- horloge temps réel
- réveils (timer)
disponibles sur la carte.
L’horloge génère un signal périodique qui sert de pulsation à l’activité
de l’exécutif et maintien la date de la machine
Les tâches utilisatrices peuvent:
-obtenir la date
-se synchroniser sur une durée
-se synchroniser sur une heure absolue
-limiter un blocage sur un délai de garde (timeout)
12
Gestion du temps
Services génériques:
Initialiser_date
Lire_date/Lire_heure
Attendre_date(date)
Signaler_a_date(date)
Attendre_délai(delai)
suspend la tâche jusqu’à la date
signaler un événement à une date
suspendre la tâche pendant un délai
Créer_réveil/Supprimer_réveil réveil=timer
Arrêter_réveil
Signaler_top_horloge
permet d’envoyer un signal périodique
Certain OS offrent des possibilités pour une tâche de se déclarer comme
périodique et de se faire activer avec une période donnée.
Gestion des interruptions
Prend en compte les sollicitations matérielles du monde extérieur.
Une routine d’interruption (ISR) doit être aussi courte que possible:
- pendant son exécution la source d’IT est masquée (mais imbrication
d’IT de niveaux de priorités différents possible)
- ce n’est pas un mode d’exécution « normal »
Le temps de latence d’IT est le délai entre arrivée de l’interruption et
le début de l’exécution du code applicatif associé c’est une
caractéristique importante qui différencie un system TR d’un système
généraliste.
13
Gestion des interruptions:
exemple
/* rtlinux capter le signal d’horloge temps réel */
/*------------------------------------------------------*/
#define RTC_IRQ 8
void intr_handler(int sig){
faire_truc();
rtl_hard_enable_irq(RTC_IRQ);
}
int init_module(void){
struct sigaction act;
act.sa_handler = intr_handler;
sigaction( RTC_IRQ, &act, NULL);
programmer_horloge( fréquence );
rtl_hard_enable_irq(RTC_IRQ);
return(0);
}
Gestion des fichiers
Certains services permettent d’optimiser l’accès aux fichiers
- plus rapides
- plus déterministes
pour des applications temps réel.
Ce sont:
- fichiers projetés en mémoire (évitent les I/O pendant l’usage)
- les fichiers stream ou temps réel (permettent écrire de façon
continues sur des pistes physiquement contiguës d’un disque)
- les écritures/lectures asynchrones
14
POSIX
Depuis 1984 à l’IEEE
P1003.1 interface de programmation pour UNIX de base
gestion des processus (fork, exec, kill …)
fichiers et terminaux (open, fopen , fgetc, dup ,fcntl ,mkdir …)
information runtime (getpid, cuerid, uname …)
signaux de base (signal, raise, sigaction … )
gestion mémoire (malloc, memcpy, free …)
gestion du temps ( time, clock …)
exécution (setjmp, longjmp …)
communication (pipe, mkfifo (named pipes), setbuf stream, …)
POSIX temps réel
P1003.1b (ex POSIX.4) extensions temps réel
ordonnancement
sémaphores
queues de messages
signaux temps réel (nouveaux, queue, paramètres
horloge haute résolution
entrées sorties synchrones/asynchrones
mémoire partagée
P1003.1c (ex POSIX.4a) extensions multithreadées
thread
mutex
variables conditions
P1003.1d (ex POSIX.4b) gestion des IT
15
OS temps réel du marché
Tornado,VxW orks
Blue C atLinux and LynxO s
Q N X N eutrino
H ard H atLinux
Lineo,Em bedix
Et beaucoup d’autres … dont certaines solutions pour compléter
Windows NT ou Linux avec des fonctions « temps réel stricte ».
OS temps réel du marché
16