23 0 2MB
LOGO
Cours OS Embarqué 2ème Ingénieur GSI
Chapitre II : Gestion des taches et ordonnancement 1
Caractéristiques de FreeRTOS Temps réel, Multitâche Pas de HAL (gestion des périphériques) Pour les microcontrôleurs, il est porté sur 33 architectures Arm, PIC Atmel, X86, MSP430, 805, superH, MicroBlaze
Ordonnancement Round-Roubin avec priorité Très faible empreinte 4 à 10Ko OpenSource 2
Les objets d’un RTOS
Les objets programmables La tâche (ou le thread ou processus léger) Les routines d’interruption, l’alarme
Objet de communication Le sémaphore • Synchronisation • Exclusion mutuelle
3
LOGO
Les tâches
Mono tâche / Multitâche Mono tâche
Multitâche
5
Une tache ? Une tâche est un fil d'exécution ● Une tâche est représentée par une structure contenant : – Un identifiant – Une référence vers son code – Une priorité – Un état : ● Prête ● Bloquée ● En cours ● ...
– Un contexte • valeurs des registres • compteur de programme • pile 6
État d'une tâche : ● prête – mémoire allouées
● bloquée – en attente d'une ressource ou d'un événement
● suspendue – en mémoire mais ne sera pas ordonnancée
● en-cours – Choisie par l'ordonnanceur pour s'exécuter
● Morte – Plus de mémoire allouée 7
État d'une tâche : ● prête – mémoire allouées
● bloquée – en attente d'une ressource ou d'un événement
● suspendue – en mémoire mais ne sera pas ordonnancée
● en-cours – Choisie par l'ordonnanceur pour s'exécuter
● Morte – Plus de mémoire allouée 8
État d'une tâche : ● prête – mémoire allouées
● bloquée – en attente d'une ressource ou d'un événement
● suspendue – en mémoire mais ne sera pas ordonnancée
● en-cours – Choisie par l'ordonnanceur pour s'exécuter
● Morte – Plus de mémoire allouée 9
État d'une tâche : ● prête – mémoire allouées
● bloquée – en attente d'une ressource ou d'un événement
● suspendue – en mémoire mais ne sera pas ordonnancée
● en-cours – Choisie par l'ordonnanceur pour s'exécuter
● Morte – Plus de mémoire allouée 10
État d'une tâche : ● prête – mémoire allouées
● bloquée – en attente d'une ressource ou d'un événement
● suspendue – en mémoire mais ne sera pas ordonnancée
● en-cours – Choisie par l'ordonnanceur pour s'exécuter
● Morte – Plus de mémoire allouée 11
État d'une tâche : ● prête – mémoire allouées
● bloquée – en attente d'une ressource ou d'un événement
● suspendue – en mémoire mais ne sera pas ordonnancée
● en-cours – Choisie par l'ordonnanceur pour s'exécuter
● Morte – Plus de mémoire allouée
Morte
12
FreeRTOS : Tâches Dans FreeRTOS les threads sont appelés « Tâches » Les Tâches partagent le même espace mémoire
Les tâches sont des fonctions C qui respectent le prototype : void ATaskFunction( void *pvParameters );
Toute tâche est en soit un petit programme (avec normalement une boucle infinie) La fin d’une tâche doit être déclarée explicitement : pas de return; 13
FreeRTOS : Tâches
void ATaskFunction( void *pvParameters ) { /* Les variables sont declarées comme dans les fonctions normales, toute instance de la tâche a sa propre copie de la variable*/ int iVariableExample = 0; /* A task will normally be implemented as in infinite loop. */ for( ;; ) { /* The code to implement the task functionality will go here. */ } /* Should the task implementation ever break out of the above loop then the task must be deleted before reaching the end of this function. The NULL parameter passed to the vTaskDelete() function indicates that the task to be deleted is the calling (this) task. */ vTaskDelete( NULL ); }
14
FreeRTOS : Tâches Une application peut être constituée de plusieurs Tâches Une seule tâche s’exécute à la fois (cas 1 seul CPU) Les tâches ont deux états possibles : running et not running (c’est une simplification) Quand la tâche est dans l’état running, le micro exécute son code Quand la tâche est dans l’état non running, la tâche est dormante
15
FreeRTOS : Création de Tâches API de FreeRTOS xTaskCreate() : portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask ); 16
FreeRTOS : Création de Tâches Paramètres de la fonction xTaskCreate Paramètre
Description
pvTaskCode
C’est le nom de la fonction C qui implémente la Tâche (c’est un pointeur sur fonction)
pcName
Chaine de caractère descriptive (juste pour aider au debug)
usStackDepth
Chaque tâche a sa propre pile, usStackDepth permet d’indiquer au kernel la taille de la pile à allouer à la tache. (en mots pas en byte)
pvParameters
Paramètre à passer à la tâche de type ( void* ).
uxPriority
Définit la priorité de la tâche de 0 à (configMAX_PRIORITIES – 1). 0 est la priorité la moins élevée
pxCreatedTask
Permet de récupérer un handle pour la tâche, utile pour agir sur la tâche (changer priorité, suppression de la tâche, …) Peut être NULL.
Returned value
Deux valeurs de retour possible : 1. pdTRUE : Tâche crée avec succès 2. errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY Si pas assez de mémoire.
17
FreeRTOS : Création de Tâches
xTaskCreate( vTask1, /* Pointer to the function that implements the task. */ "Task 1",/* Text name for the task. This is to facilitate debugging only. */ 1000, /* Stack depth - most small microcontrollers will use much less stack than this. */ NULL, /* We are not using the task parameter. */ 1, /* This task will run at priority 1. */ NULL ); /* We are not going to use the task handle. */
18
TP N°0 avec FreeRTOS: Création de Tâches
TP1 : Faisons clignoter des LEDs, mais cette fois avec FreeRTOS 1. Compiler et exécuter le projet 2. Ajouter une seconde Led (Rouge) qui clignote avec la même fréquence que la LED Bleu 3. Modifier la Fréquence de clignotement de la LED Rouge : 250ms 4. Modifier la Fréquence de clignotement de la LED Rouge : 300ms 5. Modifier la Fréquence de clignotement de la LED Rouge : 258ms
19
LOGO
L’ordonnancement
Tâches de l’ordonnanceur L’ordonnanceur est le composant de l’OS qui détermine l’ordre et la durée des tâches qui s’exécutent sur le CPU. L’ordonnanceur dicte l’état dans lequel doivent se trouver les tâches. Il charge et décharge le bloc de contrôle de la tâche (descripteur de processus ou task_struct dans le cas de Linux). 21
L’ordonnancement Passer d’un processus à un autre est coûteux 1.Sauvegarde de l’état du processus 2.Chargement du nouvel état (registres, mémoire…) 3.Démarrage du nouveau processus 4.Invalidation probable du cache mémoire
Les processus alternent souvent des phases de calcul avec des phases d’E/S Si phases de calcul très importantes : CPU-Bound Si E/S : I/O-Bound 22
Ordonnancement (quelques définitions) Ordonnancement: détermine l’ordre et le « timing » avec lesquels les tâches doivent s’exécuter. Dispatching: le dispatcheur commence et arrête une tâche. Chaque OS implémente une fonction d’ordonnancement qui n’est pas une tâche en soit. Mais une fonction appelée à plusieurs endroits du noyau: Fin de routine d’interruption Lorsque les tâches sont mises en sommeil Lorsque les tâches sont prêtes à s’exécuter.
L’ordonnancement, crée une perte de temps: plus l’algorithme est complexe, moins il est bon de l’implémenter. 23
Quand ordonnancer ? Les décisions d’ordonnancement sont prises dans plusieurs circonstances: Fin d’un processus En trouver un autre Si aucun, un processus spécial est exécuté (idle ou Processus inactif du système)
Quand un processus devient bloqué Attente d’une E/S ou d’une condition Peut influer sur le prochain à exécuter
Interruption E/S Si indique fin de traitement, réordonnancer le processus qui attendait
Ordonnancement non préemptif Un processus est choisi et détient le CPU jusqu’à ce qu’il bloque ou se termine
Ordonnancement préemptif Un processus n’a le CPU que pour une durée donnée (timeslice) 24
Ordonnancement: 2 catégories d’algorithme Non préemptif: Sélectionne un processus, puis le laisse s’exécuter jusqu’à ce qu’il bloque (soit sur une E/S, soit en attente d’un autre processus) où qu’il libère volontairement le processeur. Même s’il s’exécute pendant des heures, il ne sera pas suspendu de force. Aucune décision d’ordonnancement n’intervient pendant les interruptions de l’horloge. Préemptif: Sélectionne un processus et le laisse s’exécuter pendant un délai déterminé. Si le processus est toujours en cours à l’issue de ce délai, il est suspendu et le « schedular » sélectionne un autre processus à exécuter. 25
Algorithme d’ordonnancement : Politique FCFS / exécution jusqu’à terminaison First Come First Served (premier arrivé, premier servi). Ordonnancement utilisé pour les batchs Approche non préemptive: Pas de file d’attente de tâches bloquées
Temps de réponse lent Surtout s’il existe des tâches longues Dans ce cas: pb d’équité (les tâches courtes attendent plus que les tâches longues)
Famine: impossible. 26
Algorithme d’ordonnancement : Le plus court d’abord (SPN/Shortest Process Next) On suppose que le temps d’exécution est connu à l’avance (dur dur !). La tâche la plus courte de l’ensemble des processus s’exécute en premier. Temps de réponse plus rapide que le précédent Famine possible Temps de calcul (de l’ordonnanceur) important: pour savoir quel processus doit s’exécuter 27
Algorithme d’ordonnancement : Tourniquet/FIFO/Round Robin File d’attente FIFO stocke les processus prêts. Exécution indépendante de la charge de travail et de l’interactivité. Quantum de temps égal pour tous Durée maximale durant laquelle il peut s’exécuter S’il atteint son quantum, il est préempté S’il est bloqué avant, un autre processus est lancé
Famine: impossible Quantum de temps: Trop grand: trop d’attente par processus Trop petit: temps de changement de contexte relativement important (en pourcentage). En général, entre 10 et 50ms
28
Ordonnancement sous FreeRTOS Ordonnanceur préemptif Round-Robin avec priorité => L’ordonnanceur donne toujours la main à la tâche qui a la plus grande priorité, si elles sont plusieurs l’algorithme RR s’applique. FreeRTOS permet aussi d’utiliser une autre méthode d’ordonnancement : ordonnancement coopératif (non préemptif). Dans ce mode d'ordonnancement, un changement de contexte d’exécution a lieu uniquement si la tâche en exécution permet explicitement à une autre tâche de s’exécuter (en appelant un Yield() par exemple) ou alors en entrant dans un état de blocage 29
FreeRTOS : Ordonnancement Revenons au TP1 : On a vu dans le TP1 deux tâches de même priorité qui s’exécutent en même temps (pas vraiment en même temps)
30
FreeRTOS : TP0 suite Modifions la priorité d’une des tâches que ce passe il ?
31
FreeRTOS : la famine Dans FreeRTOS, la tâche de plus haute priorité prête à s'exécuter sera toujours sélectionnée par l'ordonnanceur. Ceci peut amener à une situation de famine. En effet, si la tâche de plus haute priorité n'est jamais interrompue, toutes les tâches ayant une priorité inférieure ne s’exécuteront jamais.
32
FreeRTOS : Revenons aux états des tâches
=
33
FreeRTOS : revenons au état des tâches Etat « Blocked » Une tache en attente d’un évènement est dans état « Blocked » qui est un sous état de l’état « Not Running ». Une tâche entre dans l’état Blocked pour attendre deux types d’évènement : 1. 2.
Evènement Temporel (time related) : exemple délais Evènement de Synchronisation : cet évènement peut être déclenché par une autre tache ou une interruption Par exemple, une tâche peut attende l’arrive d’une donnée à travers une queue (file de communication), ou le déblocage d’une sémaphore ou mutexe Il est possible de bloquer une tâche sur un évènement de synchronisation avec timeout ( donc les deux types d’évènement simultanément), Par exemple une tache attend une donnée dans une queue avec un timeout de 10ms : si les données arrivent avant 10ms, la tâche est directement débloquée, sinon à la fin des 10ms est débloqué sans que les données n’arrivent 34
FreeRTOS : revenons au état des tâches Etat « Suspended » « Suspended » est aussi un sous état de « Not Running ». Une tâche dans l’état Suspended n’est pas disponible pour l’ordonnanceur. Le seul moyen pour qu’une tache entre dans cet état est l’appel explicite de la fonction de l’API vTaskSuspend() Le seule moyen pour qu’une tache sorte de cet état est l’appel explicite de la fonction de l’API vTaskResume() ou xTaskResumeFromISR() Etat « Ready » Les Tâches qui sont dans l’état « Not Running » mais qui sont ni dans l’état Blocked ni Suspended sont dans l’état Ready. Elles sont éligibles à être en exécution , mais ne sont pas actuellement dans l’état « Running ». 35
FreeRTOS : Fonctions de délais void vTaskDelay( portTickType xTicksToDelay ); La fonction vTaskDelay() place la fonction appelante dans l’état Blocked pour un nombre fixe de ticks . Lorsque la fonction est dans l’état blocked elle ne consomme pas de ressource CPU.
36
FreeRTOS : Fonctions de délais Paramètres de la fonction vTaskDelay Paramètre
Description
xTicksToDelay
C’est le nombre de tick pendant lequel la tâche appelante doit rester dans l’état Blocked avant de passer à l’état Ready. Par exemple, si une tâche appelle vTaskDelay( 100 ) alors que le compteur de tick est à 10 000, alors elle reste dans l’état Blocked jusqu’à ce que le compteur de tick arrive à 10,100. La constante portTICK_RATE_MS peut être utilisée pour convertir les en ticks. vTaskDelay( millisecondes 250 / portTICK_RATE_MS ); //Délai de 250 ms
37
FreeRTOS : Fonctions de délais vTaskDelayUntil (portTickType * pxPreviousWakeTime, portTickType xTimeIncrement) vTaskDelayUntil() est similaire à la fonction vTaskDelay(). Dans le cas vTaskDelay() le seul paramètre est le nombre de tick pendant lequel la tâche reste dans l’état bloked depuis l’appel de cette dernière. Dans le cas de vTaskDelayUntil() le nombre de tick est décompté depuis la date passée dans le paramètre pxPreviousWakeTime Elle est utilisée essentiellement pour implémenter une tâche périodique 38
FreeRTOS : Fonctions de délais Paramètres de la fonction vTaskDelayUntil Paramètre
Description
pxPreviousWak Ce paramètre défini la date depuis la quelle le décompte commence. Ce paramètre est automatiquement mis à jours avec la valeur du compteur tick eTime à l’instant où la fonction est lancée
xTicksToDelay
C’est le nombre de tick pendant lequel la tâche appelante doit rester dans l’état Blocked avant de passer à l’état Ready depuis la date pxPreviousWakeTime. Par exemple, si une tâche appele vTaskDelayUntil (&pxPreviousWakeTime, 100 ) alors que le compteur de tick est à 10 000, et “date” contient 5 000 alors elle reste dans l’état Blocked jusqu’à ce que le compteur de tick arrive à 5,100.
pxPreviousWakeTime prendra alors la valeur 10 000
39
FreeRTOS : Fonctions de délais Pour éviter toute ambigüité, on initialise ce paramètre avec la valeur actuelle du compteur de tick: xLastWakeTime = xTaskGetTickCount(); for( ;; ) { vPrintString( pcTaskName ); vTaskDelayUntil( &xLastWakeTime, ( 250 / portTICK_RATE_MS ) ); }
Le passage par adresse de ce paramètre permet sa mise à jour dans la boucle. 40
FreeRTOS Modifions l’exemple de TP0 avec la fonction vTaskDelay Que ce passera il ?
41
FreeRTOS : TP0 Modifions l’exemple de TP0 avec la fonction vTaskDelay Que ce passera il ?
42
FreeRTOS : TP1 &TP2 • Plusieurs instances de la même tâche 1. Compiler et exécuter le projet 2. TP1: Ajouter une seconde Led (Rouge) qui clignote avec la même fréquence que la LED Bleu en utilisant une seule fonction 3. TP2: Modifier la Fréquence de clignotement de la LED Rouge
43