37 | | == Tâches standards |
38 | | |
39 | | Il est possible de programmer des applications multi-tâches coopératives dans l'environnement Arduino sans pour autant disposer des services d'un OS. Le principe a été volontairement simplifié à l'extrême. Ici, toute l'application sera dans un seul fichier et nous n'allons pas utiliser la programmation objet pour ne pas complexifier, mais pour une application plus ambitieuse, ce serait souhaitable pour une meilleure maintenance. |
40 | | |
41 | | Une application est composée de plusieurs tâches. Chaque tâche peut être répliquée en plusieurs instances et chaque tâche est exécutée à tour de rôle en temps partagé. |
42 | | * Une ''instance de tâche'' est une des copies d'une tâche |
| 37 | == Principe |
| 38 | |
| 39 | Il est possible de programmer des applications multi-tâches coopératives dans l'environnement Arduino sans pour autant disposer des services d'un OS. Le principe a été volontairement simplifié à l'extrême. Ici, toute l'application sera dans un seul fichier. |
| 40 | Nous n'allons pas utiliser la programmation objet pour ne pas complexifier, mais ce serait possible pour une application plus ambitieuse pour une meilleure maintenance. |
| 41 | |
| 42 | Une application est composée de plusieurs tâches. Chaque tâche peut être répliquée plusieurs fois dans l'application et chaque réplica de tâche est exécutée à tour de rôle en temps partagé. |
| 43 | Les (réplica de) tâches communiquent entre elles par l'intermédiaire de variables globales. |
| 44 | |
| 45 | Les ISR (Interrupt Service Routine) qui sont des fonctions exécutées lors de la survenue d'interruption sont considérée comme des tâches. |
| 46 | |
| 47 | == Tâches |
53 | | * une seconde fonction `setup_Tache()` qui initialise les ressources de la tâche (périphériques) et l'état interne. |
54 | | |
55 | | Chaque tâche dispose de trois types de variables internes |
| 59 | La fonction `loop()` demande donc l'exécution des fonctions `loop_Tache()` à tour de rôle. |
| 60 | Les tâches n'ont pas le droit de conserver le processeur sinon cela crée un blocage du système. |
| 61 | Cela signifie qu'il est interdit de faire des boucles d'attente d'un événement. |
| 62 | |
| 63 | La fonction loop() est en fait un ordonnanceur de tâche suivant un algorithme FIFO statique. |
| 64 | |
| 65 | La fonction loop() ignore si la tâche est en mesure d'avancer. Les tâches sont toujours "prêtes". |
| 66 | C'est chaque tâche qui doit vérifier si elle peut avancer, par exemple si les données |
| 67 | attendues sont disponible ou si assez de temps c'est écoulé depuis la dernière instance d'exécution. |
| 68 | Si oui elle avance, sinon elle sort immédiatement et la tâche suivante dans la liste est exécutée. |
| 69 | |
| 70 | * une seconde fonction `setup_Tache()` qui initialise les ressources matérielles assignées de la tâche (périphériques) et l'état interne (voir plus loin). |
| 71 | {{{#!c |
| 72 | setup() { |
| 73 | setup_tache1(args...); // setup du 1er réplica de la tâche 1 |
| 74 | setup_tache1(args...); // setup du 2nd réplica de la tache 1 |
| 75 | setup_tache2(args...); // setup de l'unique réplica de la tâche 2 |
| 76 | } |
| 77 | }}} |
| 78 | |
| 79 | Chaque tâche (sous-entendu réplica de tâche) dispose de trois types de variables internes |
85 | | La fonction `loop()` demande donc l'exécution des fonctions `loop_Tache()` à tour de rôle. |
86 | | Les tâches n'ont pas le droit de conserver le processeur sinon cela crée un blocage du système. |
87 | | Cela signifie qu'il est interdit de faire des boucles d'attente d'un événement. |
88 | | `connectors` sont des pointeurs vers des variables globales utilisées pour la communications inter-tâches. |
89 | | La structure générale d'une tâche est la suivante : |
90 | | |
| 110 | == Communication entre tâches |
| 111 | |
| 112 | Les tâches communiquent entre elles par des variables globales de l'application. |
| 113 | Chaque tâche reçoit en argument les pointeurs vers les variables qu'elle utilise pour communiquer. |
| 114 | Ces pointeurs sont nommés connecteurs (ou ports). |
| 115 | |
| 116 | La structure forme de la fonction loop d'une tâche est donc : |