Aller au contenu

Les systèmes multi-tâches

Les avantages d’un système d’exploitation multi-tâches

Les inconvénients relevés dans la section précédente nécessitent, dans certains cas du moins, la réalisation d’un programme en utilisant une approche multi-tâches. Cela est en particulier vrai lorsqu’il est nécessaire de réagir à des événements externes de manière prompte. Lorsqu’un programme atteint une certaine complexité, il est également préférable d’adopter une approche modulaire et multi-tâches permettant de réaliser plus aisément des modifications et les tests des différents composants d’une application.

Cela n’est donc souvent pas approprié de réaliser une application d’une certaine complexité selon le principe de l’ordonnancement manuel et sans utiliser les capacités multi-tâches fournies par un RTOS. Il est souvent préférable de modéliser une application en tâches pouvant être exécutées de manière concurrente et pouvant communiquer entre elles. Une application ainsi développée sera souvent plus efficace et plus robuste. Elle sera également plus facile à tester et à modifier.

Les avantages d’un noyau multi-tâches avec un ordonnanceur (scheduler) peuvent être résumés dans les points suivants:

  • La possibilité de développer des applications multi-tâches permet de mieux répondre aux contraintes temporelles des tâches événementielles d’un système temps-réel.
  • Sans un ordonnanceur, toutes les tâches doivent être exécutées par le même thread. Elles peuvent être exécutées de manière cyclique avec un ordre statique. Cette approche est possible pour les systèmes très simples, mais devient vite problématique.
  • Il est également possible dans certains cas de programmer toutes les tâches à l’aide du mécanisme d’interruption. A nouveau, cette approche devient rapidement difficile à gérer pour les systèmes plus complexes.

La programmation multi-tâches à l’aide d’un RTOS

Le niveau d’abstraction fourni par tous les RTOS est celui permettant de créer des entités d’exécution sous la forme de tâches ou de threads. Ces noyaux offrent de nombreux avantages:

  • Les tâches peuvent être modularisées et testées séparément.
  • Les tâches peuvent être ajoutées et modifiées de manière robuste.
  • La synchronisation entre les tâches (souvent requises) est rendue facile grâce aux mécanismes de synchronisation mis à disposition par le RTOS.
  • L’ordonnancement des tâches devient beaucoup plus aisé avec l’utilisation d’un ordonnanceur ou scheduler. De nombreux RTOS mettent à disposition des ordonnanceurs qui combinent la préemption et le partage de temps. Cela permet de programmer des applications avec des tâches de priorité différentes, en permettant aux tâches importantes d’être exécutées en priorité.

Dans un système multi-tâches, une tâche est une entité d’exécution indépendante, avec son propre stack. Chaque tâche est ainsi exécutée dans son propre contexte (variables locales sur le stack, registres du CPU). Ces entités d’exécution partagent souvent des ressources communes et doivent donc se synchroniser pour accéder à ces ressources et échanger des données. Un exemple classique est une tâche qui collecte des données de capteurs et une tâche qui affiche ces données sur un écran. Un RTOS doit donc fournir les capacités d’abstraction suivantes:

  • Un concept de thread permettant d’exécuter une tâche de manière indépendante.
  • Des primitives de synchronisation comme les mutex, les semaphore et les queue.
  • Un ordonnanceur ou scheduler dont la mission est de passer d’une tâche à l’autre en effectuant les changements de contexte associés.

Les algorithmes d’ordonnancement

Dans un système d’exploitation, le rôle d’un ordonnanceur ou scheduler est de gérer le partage du temps de calcul, en sélectionnant la tâche à exécuter parmi les tâches prêtes à être exécutées. Le système lui-même peut être coopératif ou préemptif. Dans un système coopératif ou non préemptif, les activités elles-mêmes sont en charge de céder la main à une autre tâche, de façon explicite (yield) ou implicite (attente de ressource). Dans un système préemptif, l’activité en cours d’exécution peut être interrompue par le système selon différentes stratégies. Comme Mbed OS et la plupart des RTOS sont des systèmes préemptifs, nous n’allons considérer que ce type de système dans ce cours.

L’ordonnanceur d’un RTOS a pour mission d’effectuer les changements de contexte entre les tâches, en sauvegardant le contexte de la tâche en cours et en restaurant le contexte de la nouvelle tâche à exécuter. Ces changements de tâches sont opérés selon différents algorithmes d’ordonnancement. Il existe de nombreux algorithmes et dans le contexte de ce cours, nous nous limitons à décrire deux algorithmes que Mbed OS met en œuvre dans son scheduler:

  • l’ordonnancement round-robin (appelé tourniquet en français)
  • l’ordonnancement par priorité.

L’ordonnancement round-robin

Un ordonnanceur round-robin attribue un temps fixe (souvent appelé Quantum ou Q) à chaque tâche. On peut imager le fonctionnement d’un tel ordonnanceur en plaçant les tâches dans une queue circulaire. La première tâche dans la queue est exécutée pour la durée du Quantum, puis elle est stoppée et placée à la fin de la queue. La prochaine tâche dans la queue est exécutée et le processus d’ordonnancement se poursuit ainsi.

Les avantages d’un ordonnancement round-robin sont:

  • Une telle stratégie est relativement facile à réaliser.
  • Chaque tâche obtient la même part des ressources CPU.
  • Le temps moyen afin qu’une tâche puisse être traitée est facilement calculable.

Le problème essentiel de ce type d’ordonnanceur pour les systèmes temps-réel est que l’attribution la même part des ressources CPU à chaque tâche n’est souvent pas adéquat. Dans un système temps réel, il est important que certaines tâches puissent être terminées sans que le système préempte la tâche en faveur d’une tâche moins importante. Il faut également noter qu’en fonction de la valeur de Q, l’overhead induit par le changement de contexte lors d’un changement de tâche peut également représenter un inconvénient important de ce genre d’ordonnanceur.

Afin de minimiser les inconvénients du round-robin et de mieux répondre aux besoins d’un système temps-réel, Mbed OS combine une approche round-robin avec un ordonnancement par priorité.

L’ordonnancement par priorité

Afin de pouvoir traiter les tâches différemment en fonction de leur importance, la plupart des RTOS réalise un ordonnancement par priorité. Quand un tel ordonnancement est réalisé sur un système préemptif, une tâche de plus haute priorité devenant prête à l’exécution pourra interrompre l’exécution d’une tâche de plus basse priorité. Il faut noter que lorsqu’un ordonnancement par priorité est combiné avec un ordonnancement round-roubin, les tâches de même priorité sont exécutées selon le mécanisme round-robin.

L’ordonnanceur de Mbed OS

Mbed OS réalise un système préemptif avec un ordonnanceur qui combine les algorithmes round-robin et par priorité. L’ordonnanceur utilisé est en fait celui du RTOS RTX, qui est un OS développé par ARM pour la famille des processeurs Cortex-M. Plus de détails sur cet ordonnanceur sont donnés sous RTX5 Scheduler.

Dans la section suivante, nous présentons les différents outils mis à disposition par Mbed OS afin de pouvoir programmer des applications multi-tâches aisément.