Mise en œuvre de l exclusion mutuelle dans µc/os-ii Mise en œuvre des mécanismes permettant l exclusion mutuelle à l aide des services de µc/os-ii vendredi 19 janvier 2001 1
Blocage des interruptions Méthode radicale de verrouillage du CPU empêche tout changement de tâche pas de service possible pour les interruptions (pas d ISR appelé) Macros OS_ENTER_CRITICAL() et OS_EXIT_CRITICAL() toujours appelés par paire appels empilables (méthodes 2 et 3) ou non (méthode 1) selon la configuration du noyau 2
Verrouillage logiciel Le verrouillage logiciel est possible avec µc/os-ii en utilisant une variable globale contrôlant l accès à la ressource Le test et le positionnement de la variable doit se faire en bloquant les interruptions Prendre soin d autoriser les interruptions pendant l attente active si la ressource n est pas libre prendre garde à la durée d autorisation des interruptions dans la boucle d attente active 3
Verrouillage du CPU µc/os-ii dispose de services permettant le verrouillage du CPU OSSchedLock() bloque la distribution du CPU OSSchedUnlock() autorise à nouveau la distribution du CPU À utiliser si la ressource n est pas partagée avec une fonction de service d interruption (ISR) 4
Sémaphores Caractéristiques des sémaphores dans µc/os-ii généralisés avec compteur de 16 bits les tâches dans la file d attente sont placés dans l ordre des priorités décroissantes l héritage de priorité n est pas upporté Services associés aux sémaphores initialisation (CREATE) attente (PEND) signalisation (POST) 5
Création d un sémaphore OS_EVENT *OSSemCreate (INT16U cnt) OS_EVENT est le pointeur vers le sémaphore créé cnt est la valeur initiale du compteur associé au sémaphore 6
Attente d un sémaphore void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) Un timeout en coups d horloge système (Clock Tick) permet à la tâche de reprendre son exécution si le sémaphore n a pas été obtenu après un certain temps attention vérifier au retour que le sémaphore a bien été obtenu avant d accéder à la ressource Un code d erreur est retourné par ce service OS_NO_ERR, OS_TIMEOUT, OS_ERR_EVENT_TYPE OS_ERR_PEND_ISR, OS_ERR_PEVENT_NULL 7
Acquisition d un sémaphore L acquisition d un sémaphore est une variante de l attente; ce service permet d obtenir un sémaphore en évitant à la tâche d être suspendue si le sémaphore n est pas disponible INT16U OSSemAccept (OS_EVENT *pevent) La valeur du compteur associé au sémaphore est retournée > 0 le sémaphore a été obtenu valeur du compteur retournée avant le décrément = 0 le sémaphore n est pas disponible 8
Signalisation d un sémaphore INT8U OSSemPost (OS_EVENT *pevent) Si des tâches sont en attente devant le sémaphore la plus prioritaire est débloquée un changement de tâche est effectué si celle-ci est plus prioritaire que la tâche courante Un code d erreur est retourné par ce service OS_NO_ERR, OS_SEM_OVF, OS_ERR_EVENT_TYPE, OS_ERR_PEVENT_NULL 9
Exemple d utilisation d un sémaphore Utilisation d un sémaphore pour contrôler l accès à la fonction random qui est non-réentrante (Exemple #1) Décalaration du sémaphore OS_EVENT *RandomSem; Création du sémaphore RandomSem = OSSemCreate(1); Utilisation du sémaphore OSSemPend(RandomSem, 0, &err); x = random(80); y = random(16); OSSemPost(RandomSem); 10
Problème de l inversion de priorité Situation une tâche A de priorité plus élevée cherche à acquérir un sémaphore détenu par une tâche de priorité B plus basse; ceci dans le but d accéder à une ressource non-partageable une tâche C de priorité intermédiaire monopolise le CPU empêchant ainsi la tâche B de libérer le sémaphore et de permettre à la tâche A d accéder à la ressource 11
Inversion de priorité Tâche A priorité élevée Tâche C priorité moyenne Tâche B priorité basse B fait l acquisition du sémaphore A devient active A attend le sémaphore C devient active B est à nouveau active B est à nouveau active A obtient le sémaphore B libère le sémaphore 12
Solution par héritage de priorité Règle la priorité d une tâche qui détient un sémaphore est élevée à la priorité la plus haute des tâches en attente devant ce sémaphore (si celle-ci est supérieure à sa propre priorité) 13
Héritage de priorité Tâche A priorité élevée A attend le sémaphore A obtient le sémaphore A devient active C devient active Tâche C priorité moyenne Tâche B priorité basse B fait l acquisition du sémaphore La priorité de la tâche B est élevée au niveau de celle de la tâche A B est à nouveau active B libère le sémaphore 14
Héritage de priorité dans µc/os-ii Les sémaphores dans µc/os-ii ne supportent pas l héritage de priorité Dans µc/os-ii il ne peut y avoir qu une seule tâche par niveau de priorité attention dans µc/os-ii plus la valeur numérique de la priorité est grande plus la priorité de la tâche est faible Il n est donc pas possible d élever la priorité d une tâche détenant un sémaphore au niveau de priorité d une autre tâche 15
Mutexes La version 2.04 de µc/os-ii introduit les services de «Mutexes» (Mutual Exclusion Semaphores) Un Mutex est un sémaphore binaire supportant l héritage de priorité Le Mutex sera donc dédié au contrôle de l accès à des ressources non partageable les sémaphores étant encore utilisés pour mettre en œuvre des mécanismes de synchronisation 16
Solution au problème des tâches uniques par niveau de priorité Pour élever la priorité des tâches détenant un Mutex une priorité dite «d héritage» est associée à celui-ci (Priority Inheritance Priority (PIP)) Une tâche détenant le Mutex va voir sa priorité élevée au niveau de la priorité d héritage si sa propre priorité est plus faible que celle d une tâche tentant d acquérir le Mutex 17
Services associés aux Mutexes 18
19
20
21
22
23
Exemple d utilisation d un Mutex 24
Structure de l exemple (1) Initialisation de µc/os-ii (2) Création d un Mutex avec une priorité d héritage égale à 9 (3) Création de 3 tâches une de priorité égale à 10 (la plus prioritaire) une de priorité égale à 15 une de priorité égale à 20 (la moins prioritaire) (4) Démarrage de µc/os-ii 25
Structure des tâches 26
Fonctionnement de l exemple La tâche de priorité 20 fait l acquisition du Mutex La tâche de priorité 10 tente d acquérir le Mutex; il est détenu par la tâche de priorité 20, sa priorité est élevée à 9, la priorité d héritage; la tâche de priorité 10 est placée en attente devant le Mutex La tâche de priorité 15 devient éligible au CPU; elle ne l obtient pas car la tâche de 20 est maintenant à la priorité 9 La tâche de priorité 20 termine son travail avec la ressource, libère le Mutex et la tâche de priorité 10 en fait l acquisition et devient active 27