Vous êtes sur la page 1sur 124

Systèmes d’exploitation temps

réel
Faouzi BOUCHHIMA
ENET’Com
Département informatique industrielle
Programmation des systèmes
embarqués
o Ils existent deux modèles de programmation pour les
systèmes embarqués :
le modèle à boucle infinie (foreground/background
systems ou super-loops)
Le modèle à système d'exploitation
• Dans la majorités des cas ce système d'exploitation est dit temps
réel, on parle de système d'exploitation temps réel ou de Real
Time Operating System (RTOS)

2
Programmation des systèmes embarqués en
utilisant le modèle à boucle infinie
o Modèle très souvent utilisé pour les petits systèmes
embarqués à base de microcontrôleurs
o Pas de noyau temps réel
Arrière plan : une boucle infinie principale (instructions
séquentielles + appels de fonctions)
Premier plan : les ISRs (Interrupt Service Routines) :
déclenchés par des événements matériels
o La temps de réponse pire cas d’une "tâche" dépend du
temps nécessaire pour l’exécution des autres "tâches"
de la boucle infinie Système non déterministe

3
Programmation des systèmes embarqués en
utilisant le modèle à boucle infinie
Application

Arrière plan Premier plan

T1
T2

T3

T4
4
Exemple de système embarqué à
boucle infinie : Radar ultrason

Boucle principale

5
Programmation des systèmes embarqués
en utilisant le modèle à RTOS

Application multitâches
Real-time OS
Drivers
Hardware
6
Exemple de système embarqué
multitâches avec RTOS : Robot
L’horloge de l’OS
Main

Initialisation +
démarrage de
l’OS

Erreur

7
Introduction au RTOS
o Un système d'exploitation temps réel est un système
d'exploitation multitâche destiné aux applications temps
réel
o Facilite l’implémentation d'un système temps réel, mais
ne garantit pas que le résultat final respecte les
contraintes temps réel
o Possédant des fonctionnalités spécifiques permettant :
d’avoir un code organisé en tâches (facile à manipuler)
de respecter les échéances des tâches
d’avoir un comportement déterministe du système (en terme
de temps de réponse des tâches)
8
Introduction au RTOS

o Services fournis par un RTOS :


Gestion des tâches (création, ordonnancement)
Gestion des synchronisations (précédences + partage de
ressources)
Gestion des communications (ex : messages)
Gestion de la mémoire
Gestion du temps: délai, activation périodique
Gestion des périphériques : interfaces, HDD, FDD, etc.

9
Critères de choix d’un RTOS
o Portabilité (y a-t-il un portage pour l’architecture cible ?)
o Richesse de bibliothèques : y a-t-il un support des calculs virgules
flottantes ? y a-t-il une communauté de développeurs mettant en
commun leur savoir-faire en partageant du code ?
o BSP (Board Support Package) : librairies spécifiques au cartes de
développements
o APIs pour la gestion des entrées/sorties (USB, UART, SPI, I2C etc.) et la
gestion des ressources internes du µC ou µP (Timer, convertisseur, DMA,
etc.)
o Support réseau : TCP/IP, CAN
o Certification : un crédit est accordé aux noyau certifiés suivant des normes
comme la DO-1788 (certification d'un logiciel d'avionique)
o Préemptif ou non-Préemptif , nombre max de tâches, précision de
l’horloge (granularité temporelle)
o Footprint : espace occupé dans la mémoire
o Surcharge (2 à 4 % du temps CPU)
o Prix
o Documentation
o … 10
RTOS Non-préemptif (rappel) (1/2)

11
RTOS Non-préemptif (rappel) (2/2)

o Inconvénient :
Une tâche de faible priorité pourra occuper le CPU pour
longtemps ce qui influe sur la réponse d’une tâche prioritaire qui
reste en attente de la fin ce cette tâche
Système non déterministe car le temps de réponse dépond de la charge
du CPU
o Avantages :
La latence d'interruption est généralement faible
Utilisation de fonctions réentrantes sans risque de corruption de
données
12
RTOS Préemptif (rappel)

o Avantage :
Système déterministe : exécution de la tâche de priorité la plus élevée est
déterministe; vous pouvez déterminer quand elle va prendre le contrôle de la CPU
o Inconvénient :
Ne pas utiliser des fonctions non-réentrantes sans accès mutuellement exclusif
(utilisation de mutex) 13
Exemples de RTOS
o Real-Time Operating System : 43 références dans
Wikipedia !
o Systèmes standard (Linux, Windows)
Extensions temps réel (RTLinux, RTX)
o Systèmes temps réel du marché
VxWorks, QNX, LynxOS, Chorus de Chorus Systems, Nucleus
RTOS, WindowsCE
o Système libres
MicroC/OS-II, FreeRTOS, RTEMS, ChibiOS
o Systèmes dédiés
TinyOS : OS pour les réseaux de capteurs sans fil, architecture
à composants
OSEK/VDX : automobile
14
Quelques détails supplémentaires

15
La norme POSIX
o POSIX : Portable Operating System Interface
o Garantit le développement d'applications portables au niveau du
code source, entre les systèmes d'exploitation conformes à la
norme :
propose la spécification d'un ensemble de fonctions permettant
de solliciter les services de base d'un système d'exploitation :
pour chaque fonction, le comportement attendu dans les
différentes circonstances susceptibles de se produire est
complètement défini
o pour le temps réel
POSIX 1003.1b (1003.4), les services couverts sont :
• ordonnancement
• signaux
• timers, horloges
• communication
16
Architecture d'un RTOS
o Pour des applications simples, un RTOS est habituellement se
limite à un noyau (kernel), mais vu la croissance de la complexité
des applications, différents modules sont ajoutés en plus du
noyau.

17
Architecture d'un RTOS : le noyau
l’ordonnanceur + le
changeur de contexte

Six types de services communs fournis par le noyau 18


Interaction avec le noyau

19
Appels systèmes
o fonctions exécutées par le noyau au nom d'une tâche
utilisateur
permettent d'accéder de façon « sûre » à des ressources privilégiées
o implique un changement de contexte d'exécution
sauvegarde du contexte d'exécution de la tâche
passage de la CPU en mode privilégié (« noyau »)
o une fois la fonction terminée
le noyau exécute un « retour d'exception »
la CPU repasse en mode « normal »
l'ordonnanceur est appelé et la tâche de plus haute priorité prend la
CPU
o dans beaucoup de processeurs embarqués
pas de mode privilégié
l'appel système est traité comme une procédure ordinaire

20
Services liés au temps
o l'ordonnancement des activités est au cœur du travail du
noyau (avec le changement de contexte)
mis en œuvre périodiquement et dès qu'une tâche se termine
(se bloque, passe à l’état suspendue, entre en attente, etc.)
o l'activation périodique de l'ordonnanceur est provoquée
par une horloge dédiée (pas celle de la CPU)
génère une interruption à chaque tick (~ milliseconde)
o à chaque interruption, le noyau
gère tous les timers (compteurs), en déclenchant
éventuellement les actions liées aux timers qui viennent
d'expirer
met à jour la liste des tâches prêtes et invoque l'ordonnanceur
pour élire la tâche prioritaire (il peut y avoir un changement de
contexte)
gère les budgets de temps d'exécution des tâches
21
Interruptions extérieures (1/2)
o le plus souvent dues à l'interaction avec du matériel
occurrences d'événements externes liés à des activités sporadiques dues à des
entrées/sorties
• capteurs, interfaces réseaux, périphériques
o temps de réponse très variables
o prise en charge par la CPU en passant par un mode spécial «
interruption »
niveaux de priorités dépendant de l'origine de l'interruption
désactivation de la prise en compte des interruptions
sauvegarde du contexte d'exécution et branchement à un point spécial de l'OS
réactivation des interruptions et exécution d'une routine dédiée (ISR)
reprise du cours normal d'exécution
o si une interruption de priorité supérieure se produit pendant l'exécution
de l'ISR, elle est prise en charge immédiatement par le système
sinon, on attend la fin du traitement de l'interruption en cours

22
Interruptions extérieures (2/2)
o en cas de partage de la même ligne d'interruptions
(fréquent sur les systèmes embarqués)
polling des dispositifs qui partagent la ligne
• le dispositif responsable de l'interruption se signale à l'OS
o le plus souvent l'ISR ne traite pas complètement
l'interruption
Avoir le temps le plus court possible dans le mode interruption ,
puisque l’ISR met en attente les interruptions de priorité
inférieure ou égale et toutes les tâches
réveil d'une tâche dédiée
• dans l'espace noyau ou utilisateur
• ordonnancée

23
Interruptions : latence
o Le RTOS désactive les interruptions avant que le CPU
exécute une section de code critique et les réactive,
une fois que la section a pris fin. Si une interruption
survient dans le système quand les interruptions sont
désactivées, sa période d’attente représente une des
plus importantes spécifications du noyau temps-réel
(Latence des interruptions)
o Latence = la durée de temps maximum où les
interruptions sont désactivées + l’intervalle de temps
nécessaire pour démarrer l’exécution de l’ISR
24
Interruptions : temps de réponse
o Interrupt response is defined as the time between
the reception of the interrupt and the start of the
user code that handles the interrupt (ISR)
o The interrupt response time accounts for all of the
overhead involved in handling an interrupt. Typically,
the processor’s context (CPU registers) is saved on
the stack before the user code is executed

25
Interruptions : temps de réponse
o Foreground/background system :
response time = Interrupt latency + Time to save the CPU’s
context
o Non-preemptive kernel :
response time = Interrupt latency + Time to save the CPU’s
context
o Preemptive kernel, a special function provided by the
kernel needs to be called to notify the kernel that an ISR
is starting. This function allows the kernel to keep track
of interrupt nesting. For µC/OS-II, this function is called
OSIntEnter() :
response time = Interrupt latency + Time to save the CPU’s
context + Execution time of the kernel ISR entry function
26
Interruptions : temps de recouvrement
o Interrupt recovery is defined as the time required for the
processor to return to the interrupted code or to a higher
priority task, in the case of a preemptive kernel
o Foreground/background system and non-preemptive kernel :
recovery time = Time to restore the CPU’s context + Time to execute the
return from interrupt instruction
o Preemptive kernel : Typically, a function provided by the kernel
is called at the end of the ISR. For µC/OS-II, this function is called
OSIntExit() and allows the kernel to determine if all interrupts
have nested. If they have nested (i.e., a return from interrupt
would return to task-level code), the kernel determines if a
higher priority task has been made ready to run as a result of
the ISR (or any other nested ISR)
recovery time = Time to determine if a higher priority task is ready + Time
to restore the CPU’s context of the highest priority task + Time to execute
the return from interrupt instruction
27
Temps de recouvrement (suite)
o Foreground/background system and non-preemptive kernel

or ISR (Or task for non-premptive kernel) or ISR

28
Temps de recouvrement (suite)
o You should note that for a preemptive kernel, the exit
function decides to return either to the interrupted task (A) or
to a higher priority task that the ISR has made ready to run (B)

Restauration
of new task
contexte is
added (call
of SwC)

29
Interruptions dans µC/OS (1/4)

30
Interruptions dans µC/OS (2/4)
OSIntEnter()
Exécute trois opérations:
o Désactive les interruptions, permettant l’accès
exclusif à la variable globale OSIntNesting,
o incrémente la variable globale OSIntNesting, qui
mémorise le nombre d’interruptions imbriquées
activées
o réactive les interruptions

31
Interruptions dans µC/OS (3/4)
OSIntExit()
Exécute deux opérations:
o Décrémente la variable globale OSIntNesting
o Si OSIntNesting arrive à 0, un re-ordonnancement va
avoir lieu pour déterminer la tâche la plus prioritaire
qui va prendre le contrôle du CPU
Si la tâche interrompue reste la plus prioritaire, OSIntExit()
retourne dans l’ISR, alors la restauration des registres aura
lieu et l’instruction de retour à partir de l’interruption est
exécutée
Si la tâche interrompue n’est plus la plus prioritaire, les
registres de la nouvelle tâche sont restaurés et l’instruction
de retour à partir de l’interruption est exécutée
32
Interruptions dans µC/OS (3/4)
OSIntCtxSw()
o This function is called from OSIntExit() when OSIntExit()
determines that a higher priority task must be executed
because of an ISR. The pseudocode for this function is :

33
Interruptions dans µC/OS (4/4) :
section critique
o OS_ENTER_CRITICAL() : désactiver les interruptions
o OS_EXIT_CRITICAL() : réactiver les interruptions
o Ces 2 fonctions sont toujours utilisés ensemble pour délimiter
une section critique du code :

34
Interruption non masquable
o Sometimes, an interrupt must be serviced as quickly as possible and
cannot afford to have the latency imposed by a kernel. In these
situations, you might be able to use the nonmaskable interrupt (NMI)
provided on most microprocessors. Because the NMI cannot be
disabled, interrupt latency, response, and recovery are minimal
Interrupt Latency = Time to execute longest instruction + Time to start
executing the NMI ISR
Interrupt Response = Interrupt latency + Time to save the CPU’s context
Interrupt Recovery = Time to restore the CPU’s context + Time to execute the
return from interrupt instruction
o Notes : (1) When you are servicing an NMI, you cannot use kernel
services to signal a task because NMIs cannot be disabled when
access critical sections of code so task can delays the end of the
critical section (2) NMI have the highest priority and interrupt nesting
is typically not allowed while servicing the NMI ISR
35
Fonction réentrante
o Peut être appelée par plus qu’une tâche sans
corruption des données ou de l’état d’un matériel
o Peut être interrompue à tout moment et après
reprend l’exécution sans perte de données
o Utilise des variables sur les registres du CPU ou sur la
pile
o Protège les variables globales par mutex

36
Exemple de fonction réentrante

o Les paramètres sont passés à travers la pile


o Plusieurs tâches pourront appeler la fonction strcpy
sans aucun problème
37
Exemple de fonction non-réentrante (1/2)

38
Exemple de fonction non-réentrante (2/2)

Tick timer ISR or other ISR

39
ETUDE DU SYSTÈME D’EXPLOITATION
TEMPS RÉEL : MICROC/OS-II

40
MicroC/OS-II
o MicroC/OS-II, conçu et mis au point par Jean J. Labrosse,
est un noyau temps réel permettant d’effectuer une
exécution de plusieurs tâches sur un microprocesseur ou
un microcontrôleur.
o Ce noyau temps réel est maintenant disponible sur un
grand nombre de processeurs, et il peut intégrer des
protocoles standard comme TCP/IP (µC/IP) pour assurer
une connectivité IP sur une liaison série. Les différentes
versions de MicroC/OS-II sont portées sur des systèmes
différents : Motorola famille 680x0, 68HC11/16, Power
PC 860, Intel 80x86, Philips XA, famille PIC, famille ARM,
etc.

41
Capacités et caractéristiques
o Ouvert, code source disponible,
o Portable, ROMable donc facilement embarqué
o Fiable et robuste,
o Fonctionnalités ajustables,
o Multitâches et préemptif (l’Ordonnanceur de ce noyau
contient seulement quatre lignes simples de code C)
o Interruptible : traitement des interruptions par les
ISRs,

42
Capacités et caractéristiques
o 64 tâches où chaque degré de priorité correspond à une seule
tâche, c'est-à-dire deux tâches ne peuvent pas avoir le même
degré de priorité,
o Héritage de priorités (en cas d’inversion de priorités)
o Changement de priorité des tâches
o Fonction d'attente de tâche,
o Occupation optimale dans la mémoire: 2 Koctets taille du
code,
o Création et gestion des sémaphores, des mutex, des mails
box, des queues de messages et des drapeaux d’événements,
o Le temps d'exécution pour la plupart des services fournis par
µC/OS-II est constant et « déterministe ».

43
Structure de MicroC/OS-II
o Le système MicroC/OS-II peut être vu comme une
bibliothèque de fonctions réparties sur des couches
logicielles.
o Cette bibliothèque est liée avec l’application à
développer. Ainsi, les services de MicroC/OS-II sont
appelés depuis l’application comme des simples
fonctions.
o Le code source de ce noyau est divisé en deux
sections : la première est indépendante du
processeur et la deuxième en est dépendante.

44
Structure de MicroC/OS-II

45
États d’une tâche microC/OS-II

46
Gestion du temps
o µC/OS-II exige qu’une interruption périodique mettre
à jour le délai d’attente des tâches en attente d’un
délai (OSTimeDly)
o Par conséquent l’ISR associée exécute alors des
opérations de comptabilité:
incrémente le compteur de «ticks »
actualise les délais des tâches en attente d’un délai : si au
moins un délai arrive à échéance (0), vérifie s’il est
nécessaire de réordonnancer les tâches

47
OS_TCB : Task Control Bloc
o Une tâche créée se voit affectée un bloc de contrôle.
C’est une structure de donnée qui maintient l’état de
la tâche en cas de préemption. Le TCB permet aussi
de récupérer l’état de la tâche quand elle redevient
active. C’est une zone en RAM.
o Le TCB contient :
La priorité de la tâche
Son état
Un pointeur vers la pile
D’autres données concernant la tâche

48
OS_TCB : Task Control Bloc

49
OS_TCB
o Le nombre maximum de tâches est spécifié par
OS_MAX_TASKS dans OS_CFG.H. Il détermine aussi le
nombre de TCBs alloués pour l’application
o On peut réduire la RAM allouée aux TCB en fixant le
nombre de tâches effectivement aux tâches de
l’application. L’OS alloue un TCB pour la tâche IDLE et un
autre pour la tâche statistique (si OS_TASK_STAT est à 1).
o A l’initialisation tous les TCB sont liés selon une liste.
o Quand une tâche est crée, l’OS_TCB qui est pointé par
OSTCBFreeList est affecté à cette tache, et est ajusté pour
pointer sur le prochain OS_TCB dans la chaine

50
OS_TCB

51
Ordonnancement des tâches
o Les tâches prêtes à l’exécution et les tâches en
attente sont organisées dans des queues d’attente
o La queue des tâches prêtes à l’exécution est
organisée en fonction de priorités, la tâche la plus
prioritaire étant toujours en tête de liste
o Cette queue est une structure de données spéciale,
appelée “bitmapped queue” (le temps d’insertion ou
de suppression d’une tâche est toujours constant)

52
La queue des tâches prêtes à rouler

53
Principe d’organisation des priorités

54
Principe d’organisation des priorités
(exemple)

55
Table de résolution des priorités

56
Trouver la tâche prête la plus
prioritaire
o Y = OSUnMapTbl[OSRdyGrp];
o X = OSUnMapTbl[OSRdyTbl[Y]];
o HighestPriority = (Y * 8) + X;
o Y (1) = OSUnMapTbl[0xF6];
o X (3) = OSUnMapTbl[0x78];
o HighestPriority = (1 * 8) + 3;
o HighestPriority = 11

57
Localiser le TCB de la tâche prête la
plus prioritaire

58
Context switch
o After the scheduler has determined that a more important
task needs to run, OS_TASK_SW() is called to perform a
context switch
o The context of a task is generally the contents of all of the CPU
registers
o The context-switch code simply needs to save the register
values of the task being preempted and load into the CPU the
values of the registers for the task to resume
o To explain the CtxSw, we suppose have a CPU with 7 registers :
A stack pointer (SP)
A program counter (PC)
A processor status word (PSW)
Four general purpose registers (R1, R2, R3, and R4)

59
Context switch :
structures when OS_TASK_SW() is called

60
Context switch :
Saving the current task’s context

61
Context switch :
Resuming the current task

62
Context switch :
Context-switch pseudocode

63
Les tâches
o MicroCOS peut gérer jusqu’à 64 tâches (2 tâches sont
réservées au système).
o Chaque tâche doit se voir assigner une priorité unique.
o En fait on peut avoir 56 tâches effectivement si l’on tient
compte des restrictions liées à l’OS, qui se réserve les 4
niveaux les plus bas et les 4 niveaux les plus hauts
o Le niveau de priorité va de 0 à OS_LOWEST_PRIO-2
compris.
o Plus le nombre associé à la priorité est faible, plus la
priorité est forte.

64
Les tâches
o MicroCOS exécute toujours la tâche de plus forte priorité
prête.
o Le niveau de priorité sert aussi d’identificateur de tâche
(pour quelques services de l’OS comme
OSTaskChangePrio() et OSTaskDel()).
o Pour qu’une tâche soit gérée par l’OS, il faut la créer en
passant des paramètres à une des deux fonctions
OSTaskCreate() ou OSTaskCreateExt() qui est une version
étendue de la première avec des fonctionnalités
supplémentaires.
o Il y a toujours une tâche présente, la tâche IDLE, si
aucune tâche ne s’exécute.

65
Création de taches (1/4)
Lors de la création d’une tâche, le noyau exécute plusieurs
opérations:
o Allouer de la mémoire RAM, dans le System Memory
Pool, pour la pile de la tâche (pour les variables locales,
les paramètres passés à la tache, le contexte du CPU et
l’adresse de retour) et le TCB de la tâche (pour stocker
des paramètres spécifiques et des paramètres de
contrôle de la tâche)
o Initialiser la pile (stocker les arguments de la tâche,
éventuellement remplir tous les octets avec un certain
symbole, afin de permettre le calcul de l’utilisation
maximale de la pile).

66
Création de taches (2/4)
o Initialiser le TCB (initialiser le SP (stack pointer),
copier les options de la tâche, etc...)
o Placer la tâche dans la queue des tâches « ready to
run ».
o La routine de création de la tâche retourne l’adresse
du TCB en mémoire (identificateur de tâche) ou un
code d’erreur, en cas d’échec.

67
Création de taches (3/4)

68
Création de tâches (4/4)
INT8U OSTaskCreateExt (void (* task) (void*pd), void *pdata, OS_STK *ptos,
INT8U prio, INT16U id, OS_STK *pbos, INT32U stk- size, void *pext, INT16U
opt)
o task = pointeur vers le code de la tâche
o pdata = pointeur vers un argument passé à la tâche quand elle commence son
exécution
o ptos = pointeur vers le sommet de la pile assignée à la tâche
o prio = priorité de la tâche
o id = identificateur de la tâche (pas encore utilisé)
o pbos = pointeur vers la base de la pile assignée à la tâche (utilisé pour vérifier
la pile)
o stk-size = taille de la pile à assigner, en octets
o pext = pointeur vers la zone de mémoire contenant les extensions utilisateur
du TCB de la tâche
o opt = options de la tâche
o Remarque : INT8U OSTaskCreate (……) possède seulement les 4 premiers
arguments
69
Astuce de conception
o Le phénomène de débordement de la pile d’une
tâche conduit à un comportement imprévisible du
système et de l’application. Pour remédier a ce
problème il faut :
estimer la taille de la pile de chaque tâche, en fonction du
nombre de variables locales, récursivité, interruptions
imbriquées, etc,
prévoir une taille initiale étendue (1.5 à 2 fois la taille
estimée)
exécuter plusieurs fois le code, dans les situations les plus
critiques, avant d’établir la taille finale de la pile de chaque
tâche.

70
Exemple de création de tâches

71
Supprimer une tâche
o La suppression d’une tâche contient deux étapes.
En premier lieu il faut effacer la tâche dans la queue des
tâches prêtes et toutes les queues d’attente, afin qu’elle ne
soit plus lancée en exécution par l’ordonnanceur.
En second lieu désaffecter le TCB et la pile de la tâche. Les
deux zones de mémoire correspondantes peuvent être
réutilisées.
o Supprimer une tâche signifie rendre la tâche inactive
(“ dormant”).
o l’ordonnanceur ne planifie plus en exécution une
tâche inactive

72
Supprimer une tâche
o Routine µC/OS-II pour supprimer la tâche de priorité
“prio”: OSTaskDel (INT8U prio)
o Routine µC/OS-II appelée par une tâche afin de
demander à une autre tâche, propriétaire d’une
ressource, de se supprimer par elle-même :
OSTaskDelReq( INT8U prio)
o La routine OSTaskDelReq rend la suppression d’une
tâche plus sécuritaire.

73
Astuce de conception (1/2)
o Il y a des cas où la suppression d’une tâche peut avoir des
conséquences catastrophiques
o La majorité des RTOS fournissent des routines qui
permettent d’éviter qu’une tâche soit supprimée
pendant qu’elle exécute une zone de code critique.
o En général, il n'y a aucune façon de savoir si la
suppression d'une tâche est sécuritaire
o Si l’on supprime une tâche qui possède l’accès exclusif à
une ressource partagée, celle-ci ne sera jamais relâchée.
o Par conséquent, une tâche ne doit pas effacer n'importe
quelle autre tâche, sauf elle-même

74
Astuce de conception (2/2)
o La récupération des ressources : en général, les
seules ressources automatiquement récupérées par
un RTOS sont le TCB et la pile de tâche
o Les tâches sont responsables de leur propre
nettoyage :
Désaffecter la mémoire
Libérer les ressources de système partagées
Fermer les fichiers qui ont été ouverts

75
Typical use of OSTaskDelReq( )

76
Code of OSTaskDelReq( )

77
Suspendre/reprendre une tâche et
Retarder une tâche (1/2)
o Parfois il est nécessaire de suspendre une tâche
(rendre la tâche incapable de s’exécuter)
o L’état « suspended » peut alors être ajouté aux états
d’attente («waiting », «pended » ou «delayed »).
o L’exécution d’une tâche qui a été suspendue peut
être reprise
o Les appels de système pour suspendre/reprendre
une tâche sont utilisés habituellement pour des buts
de débogage et de développement

78
Suspendre/reprendre une tâche et
Retarder une tâche (2/2)
o L’RTOS permet qu’une tâche soit retardée pour un nombre
spécifié de « ticks » d'horloge de système.
Opération utile pour l’exécution périodique d’une fonction ou pour
faire la surveillance cyclique (« polling ») d’un dispositif matériel (ex:
un dispositif I/O)
o Suspendre une tâche: OSTaskSuspend (INT8U prio)
o Reprendre une tâche qui a été suspendue: OSTaskResume
(INT8U prio)
o Retarder une tâche pour un nombre indiqué de « ticks »
d'horloge de système : OSTimeDly( ticks)
o Retarder une tâche pour un nombre indiqué de HMSM
(heures, minutes, secondes et millisecondes):
OSTimeDlyHMSM( int,int,int,int)

79
Tâches de système
o Les tâches de système permettent de:
configurer le système
afficher des messages de système
exécuter des différentes services spécifiques aux tâches, à une
priorité supérieure
obtenir des statistiques dynamiques (ex.: le degré d’utilisation
du CPU par l’application, en pourcentage)
o La tâche idle, tâche qui est exécutée quand aucune autre
tâche n’est prête pour l’exécution.
OS_ TaskIdle() a la priorité 63
o Dans µC, la tâche de statistique qui calcule le
pourcentage d’utilisation du CPU par seconde est
OSTaskStat(), a la priorité 62
80
Initialisation du µC/OS-II
o A requirement of µC/OS-II is that you call OSInit() before
you call any of µC/OS-II’s other services
o OSInit() initializes all µC/OS-II variables and data
structures (see OS_CORE.C)
o OSInit() creates the idle task OS_TaskIdle(), which is
always ready to run
o If OS_TASK_STAT_EN and OS_TASK_CREATE_EXT_EN(see
OS_CFG.H) are both set to 1, OSInit() also creates the
statistic task OS_TaskStat() and makes it ready to run

81
Déclaration de la pile d’une tâche
o Chaque tâche doit avoir un espace réservé dans la
mémoire
o Cet espace doit être déclaré de type OS_STK
(emplacements mémoire contigus).
o L’allocation peut être statique (à la compilation) ou
dynamique (à l’exécution).
o Déclaration statique
Static OS_STK MyTaskStack[stack_size], ou
OS_STK MyTaskStack[stack_size]
o Déclaration dynamique
Peut utiliser la fonction C malloc(), mais attention à la
fragmentation

82
Après initialisation

83
Après initialisation
o Notice that the task control blocks (OS_TCBs) of
OS_TaskIdle() and OS_TaskStat() are chained together in
a doubly linked list
o OSTCBList points to the beginning of this chain. When a
task is created, it is always placed at the beginning of the
list. In other words, OSTCBList always points to the
OS_TCB of the last task created
o Because both tasks are ready to run, their corresponding
bits in OSRdyTbl[] are set to 1.
o Also, because the bits of both tasks are on the same row
in OSRdyTbl[], only one bit in OSRdyGrp is set to 1

84
Gestion des événements
Définition des ECB (Event control blocks)

85
Gestion des ECB
o An ECB can be a semaphore, a mutex, a message
mailbox, or a message queue
o A (1) : An ISR or a task can signal an ECB
o A (2) : Only a task can wait for another task or an ISR to
signal the ECB. An ISR is not allowed to wait on an ECB
o B : Multiple tasks can wait for a task or an ISR to signal an
ECB. When the ECB is signaled, only the highest priority
task waiting on the ECB is signaled and made ready to
run
o C (4) : When an ECB is used as a semaphore, tasks can
both wait on and signal the ECB

86
Gestion des ECB
o µC/OS-II maintains the state of an ECB in a data
structure called OS_EVENT(see uCOS_II.H)
o Each semaphore, mutual exclusion semaphore,
message mailbox, and message queue is assigned an
ECB

87
Gestion des ECB

88
TCB vers ECB
o Deux opérations qui font passer un bit de 0 à 1 dans
la table OSxxxTbl et dans le vecteur OSxxxGrp:
Removing a task from the ready list (e. g. OSTimeDly,
OSTaskSuspend, OSChangePrio, etc. mais aussi
OSEventTaskWait)
Removing a task from a waiting list (e. g.
OSEventTaskReady appelé par OSSemPost, OSMutexPost,
OSMboxPost, OSQPost ou OSEventTO (TO : Time Out)
called by OSSemPend, OSMutexPend, OSMboxPend,
OSQPend)

89
Gestion des sémaphores
o Servent à synchroniser entre tâches dans le cas de
ressources partagées ou de précédence
o Il y en a deux types de sémaphores : les sémaphores
binaires (Binary Semaphore) et les sémaphores
compteurs (Counting Semaphore).
Un sémaphore binaire (Mutex) peut prendre uniquement
deux valeurs, 0 ou 1.
Un sémaphore compteur peut prendre une gamme de
valeurs basée sur sa taille. Par exemple, la valeur d’un
sémaphore compteur à 8 bits peut s’étendre de 0 à 255. Il
peut aussi être à 16 ou 32 bits.

90
Gestion des sémaphores

91
Gestion des sémaphores
o Création d’une sémaphore OSSemCreate()
OS_EVENT *OSSemCreate(INT16U cnt);
OS_EVENT *Memory_Sem; /* Semaphore pointer */
Memory_Sem = OSSemCreate(0); /* Creation of a binary semaphore initialized
to 0 */
o Information sur une sémaphore OSSemQuery()
INT8U OSSemQuery(OS_EVENT *pevent, OS_SEM_DATA
*p_sem_data);
pdata is a pointer to a data structure of type OS_SEM_DATA, which
contains the following fields :

92
Gestion des sémaphores
o Détruire une sémaphore OSSemDel()
OS_EVENT *OSSemDel(OS_EVENT *pevent, INT8U opt, INT8U
*perr);
opt specifies whether you want to delete the semaphore
only if there are no pending tasks
(OS_DEL_NO_PEND) or whether you always want to delete
the semaphore regardless of whether tasks are pending or
not (OS_DEL_ALWAYS). In this case, all pending task are
readied
Returns A NULL pointer if the semaphore is deleted or
pevent if the semaphore is not deleted. In the latter case,
you need to examine the error (*perr) code to determine
the reason.

93
Gestion des sémaphores
o Demander (W) une sémaphore :
bloquant OSSemPend()
• void OSSemPend(OS_EVENT *pevent, INT16U timeout, INT8U
*perr);
non- bloquant OSSemAccept()
• INT16U OSSemAccept(OS_EVENT *pevent);
o Libérer (S) une sémaphore OSSemPost()
INT8U OSSemPost (OS_EVENT *pevent);

94
Semaphore configuration constants in
OS_CFG.H

95
Gestion des mutex
o Mutual exclusion semaphores (mutexes) are used by
tasks to gain exclusive access to resources. Mutexes
are binary semaphores that have additional features
beyond the normal semaphores mechanism
provided by µC/OS-II
o A mutex is used by your application code to reduce
the priority inversion problem. A priority inversion
occurs when a low priority task owns a resource
needed by a high priority task

96
Gestion des mutex

97
Gestion des mutex
o Créer un mutex OSMutexCreate()
OS_EVENT *OSMutexCreate(INT8U prio, INT8U *perr);
o Information sur un mutex OSMutexQuery()
INT8U OSMutexQuery(OS_EVENT *pevent, OS_MUTEX_DATA
*p_mutex_data);
pdata is a pointer to a data structure of type OS_MUTEX_DATA,
which contains the following fields :

98
Gestion des mutex
o Détruire un mutex OSMutexDel()
OS_EVENT *OSMutexDel(OS_EVENT *pevent, INT8U opt,
INT8U *perr);
opt specifies whether you want to delete the mutex only if
there are no pending tasks (OS_DEL_NO_PEND) or whether
you always want to delete the mutex regardless of
whether tasks are pending or not (OS_DEL_ALWAYS). In this
case, all pending task are readied

99
Gestion des mutex
o Demander (W) un mutex :
bloquant OSMutexPend()
• void OSMutexPend(OS_EVENT *pevent, INT16U timeout, INT8U
*perr);
non- bloquant OSMutexAccept()
• BOOLEAN OSMutexAccept(OS_EVENT *pevent, INT8U *perr);
o Libérer (S) un mutex OSMutexPost()
INT8U OSMutexPost(OS_EVENT *pevent);

100
Mutex configuration constants in
OS_CFG.H

101
Gestion des mutex (exemple)

102
Gestion des mutex (suite exemple)

103
Gestion des mailbox
o Créer une mailbox OSMboxCreate()
OS_EVENT *OSMboxCreate(void *pmsg);

104
Gestion des mailbox
o Information sur une mailbox OSMboxQuery()
INT8U OSMboxQuery(OS_EVENT *pevent, OS_MBOX_DATA
*p_mbox_data);
pdata is a pointer to a data structure of type OS_MBOX_DATA,
which contains the following fields:

o Détruire une mailbox OSMboxDel()


OS_EVENT *OSMboxDel(OS_EVENT *pevent, INT8U opt, INT8U
*perr);
105
Gestion des mailbox

o Envoyer un message
dans une mailbox OSMboxPost()
• INT8U OSMboxPost(OS_EVENT *pevent, void *pmsg);
à toutes les taches en attente OSMboxPostOpt()
• INT8U OSMboxPostOpt(OS_EVENT *pevent, void *pmsg, INT8U opt);
Opt : specifies whether you want to send the message to the highest priority
task waiting at the mailbox (when opt is set to OS_POST_OPT_NONE) or to all
tasks waiting at the mailbox (when opt is set to S_POST_OPT_BROADCAST).
o Prendre un message dans une mailbox :
bloquant OSMboxPend()
• void *OSMboxPend(OS_EVENT *pevent, INT16U timeout, INT8U *perr);
non- bloquant OSMboxAccept()
• void *OSMboxAccept(OS_EVENT *pevent);
106
Gestion des mailbox (exemple)

N.B. If any of the tasks that receives the message have a higher priority than the
task that is posting the message, then the higher priority task is resumed, and
the sending task is suspended. In other words, a context switch occurs. 107
Gestion des mailbox (exemple)

108
Mailbox configuration constants in
OS_CFG.H

109
Gestion des queues de messages
o Créer une queue OSQCreate()
OS_EVENT *OSQCreate(void **start, INT16U size);
Start : is the base address of the messages (pointers) storage area.
A message storage area is declared as an array of pointers to voids.
Size : is the size (in number of entries) of the message storage area

110
Gestion des queues de messages
o Information sur une queue OSQQuery()
INT8U OSQQuery(OS_EVENT *pevent, OS_Q_DATA *p_q_data);
Pdata : is a pointer to a data structure of type OS_Q_DATA, which
contains the following fields :

o Détruire une queue OSQDel()


OS_EVENT *OSQDel(OS_EVENT *pevent, INT8U opt, INT8U
*perr);
o Vider une queue OSQFlush()
INT8U OSQFlush(OS_EVENT *pevent);
111
Gestion des queues de messages

o Envoyer un message
dans une queue FIFO OSQPost()
• INT8U OSQPost(OS_EVENT *pevent, void *pmsg);
dans une queue LIFO OSQPostFront()
• INT8U OSQPostFront(OS_EVENT *pevent, void *pmsg);
à toutes les taches en attente OSQPostOpt()
• INT8U OSQPostOpt(OS_EVENT *pevent, void *pmsg, INT8U opt);
o Prendre un message dans une queue :
bloquant OSQPend()
• void *OSQPend(OS_EVENT *pevent, INT16U timeout, INT8U *perr);
non- bloquant OSQAccept()
• void *OSQAccept(OS_EVENT *pevent);
112
Gestion des queues de messages (ex.)

113
Gestion des queues de messages (ex.)

114
Drapeaux d’évènements

115
Drapeaux d’évènements
o Créer un drapeau d’évènement
OS_FLAG_GRP *OSFlagCreate(OS_FLAGS flags, INT8U
*perr);
flags contains the initial value to store in the event flag
group
o Supprimer un drapeau
OS_FLAG_GRP *OSFlagDel(OS_FLAG_GRP *pgrp, INT8U
opt, INT8U *perr);
o Information sur un drapeau
OS_FLAGS OSFlagQuery(OS_FLAG_GRP *pgrp, INT8U
*perr);

116
Drapeaux d’évènements
(OSFlagCreate)

117
Drapeaux d’évènements
o Attendre un drapeau
Bloquant:
• OS_FLAGS OSFlagPend(OS_FLAG_GRP *pgrp, OS_FLAGS flags,
INT8U wait_type, INT16U timeout, INT8U *perr);
• flags is a bit pattern indicating which bit(s) (i.e., flags) you wish to
check. The bits you want are specified by setting the corresponding
bits in flags

used to have a task wait for a combination of conditions


(i.e., events or bits) to be set (or cleared) in an event flag
group. Application can wait for any condition to be set or
cleared or for all conditions to be set or cleared. If the
events that the calling task desires are not available, then
the calling task is blocked until the desired conditions are
satisfied or the specified timeout expires
118
Drapeaux d’évènements (OSFlagPend)
wait_type : specifies whether you want all bits to be set/cleared or any of the bits
to be set/cleared.
You can specify the following arguments:
o OS_FLAG_WAIT_CLR_ALL You check all bits in flags to be clear (0)
o OS_FLAG_WAIT_CLR_ANY You check any bit in flags to be clear (0)
o OS_FLAG_WAIT_SET_ALL You check all bits in flags to be set (1)
o OS_FLAG_WAIT_SET_ANY You check any bit in flags to be set (1)

You can also specify whether the flags are consumed by adding
OS_FLAG_CONSUME to the wait_type. For example, to wait for any flag in a group
and then clear the flags
that satisfy the condition, set wait_type to
OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME

Returned Value : The value of the flags in the event flag group after they are
consumed (if OS_FLAG_CONSUME is specified) or the state of the flags just before
OSFlagPend() returns. OSFlagPend() returns 0 if a timeout occurs.

119
Drapeaux d’évènements (OSFlagPend)

120
Drapeaux d’évènement
Non bloquant:
• OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, OS_FLAGS flags,
INT8U wait_type, INT8U *perr);
o Envoyer un drapeau
OS_FLAGS OSFlagPost(OS_FLAG_GRP *pgrp, OS_FLAGS
flags, INT8U opt, INT8U *perr);

121
Drapeaux d’évènement (OSFlagPost)
Flags : specifies which bits you want set or cleared. If opt is
OS_FLAG_SET, each bit that is set in flags sets the
corresponding bit in the event flag group. For example to
set bits 0, 4, and 5, you set flags to 0x31(note, bit 0 is the
least significant bit). If opt is OS_FLAG_CLR,
each bit that is set in flags will clears the corresponding bit
in the event flag group. For example to clear bits 0, 4, and 5,
you specify flags as 0x31(note, bit 0 is the least significant
bit).
Opt : indicates whether the flags are set (OS_FLAG_SET) or
cleared (OS_FLAG_CLR).
Returned Value : The new value of the event flags.

122
Drapeaux d’évènement (OSFlagPost)

123
124

Vous aimerez peut-être aussi