Changes between Version 1 and Version 2 of IOC20_T04
- Timestamp:
- Feb 21, 2020, 7:33:47 AM (5 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
IOC20_T04
v1 v2 3 3 = Objectif de la séance 4 4 5 Le but de la séance est d'écrire une application multitâches Arduino utilisant plusieurs périphériques. 5 Le but de la séance est d'écrire une application multitâches Arduino utilisant plusieurs périphériques. 6 L'application finale contiendra toutes les tâches. 6 7 7 8 = Préambule … … 44 45 45 46 Il est possible de programmer des applications multi-tâches coopératives dans l'environnement Arduino sans pour autant dispose 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. 47 Pour les dessins, je vous incite à revoir le [htdocs:cours/IOC20_C04_Protocoles_filaires_base_Arduino.pdf cours] à partir du slides 31 46 48 47 49 Chaque tâche est représentée par … … 51 53 52 54 Les fonctions `loop_Tache` et `setup_Tache` peuvent avoir des variables locales mais leur état n'est pas conservé entre deux exécutions. 53 Elles peuvent aussi avoir des variables static mais ces variables ont une valeur unique même si la tâche est à plusieurs instances.55 Elles peuvent aussi avoir des variables static mais ces variables ont une valeur unique même si la tâche est à plusieurs exemplaires. 54 56 55 57 La structure contexte ressemble à : … … 63 65 64 66 65 C'est la fonction `setup_Tache()`qui va pouvoir initialiser le contexte avec des ar67 C'est la fonction `setup_Tache()`qui va pouvoir initialiser le contexte avec des paramètres. 66 68 {{{#!c 67 69 void setup_Tache(struct Tache_st *ctx, params...) { … … 104 106 {{{#!c 105 107 // -------------------------------------------------------------------------------------------------------------------- 106 // Multi-tâches cooperatives : solution basique 108 // Multi-tâches cooperatives : solution basique mais efficace :-) 107 109 // -------------------------------------------------------------------------------------------------------------------- 108 110 … … 120 122 #define MAX_WAIT_FOR_TIMER 2 121 123 unsigned int waitFor(int timer, unsigned long period){ 122 static unsigned long waitForTimer[MAX_WAIT_FOR_TIMER]; 124 static unsigned long waitForTimer[MAX_WAIT_FOR_TIMER]; // il y a autant de timers que de tâches périodiques 123 125 unsigned long newTime = micros() / period; // numéro de la période modulo 2^32 124 126 int delta = newTime - waitForTimer[timer]; // delta entre la période courante et celle enregistrée 125 if ( delta < 0 ) delta = 1 + newTime; // en cas de dépassement du nombre de périodes possibles sur 2^32127 if ( delta < 0 ) delta = 1 + newTime; // en cas de dépassement du nombre de périodes possibles sur 2^32 126 128 if ( delta ) waitForTimer[timer] = newTime; // enregistrement du nouveau numéro de période 127 129 return delta; … … 131 133 132 134 struct Led_st { 133 int timer; // numéro d e timerutilisé par WaitFor135 int timer; // numéro du timer pour cette tâche utilisé par WaitFor 134 136 unsigned long period; // periode de clignotement 135 137 int pin; // numéro de la broche sur laquelle est la LED … … 192 194 193 195 **Questions** 194 - Que contient le tableau `waitForTimer[]`` ? 196 - Que contient le tableau `waitForTimer[]` et à quoi sert-il ? 197 - Si on a deux tâches indépendantes avec la même période, pourquoi ne peut-on pas utiliser le même timer dans waitFor() ? 195 198 - Dans quel cas la fonction `waitFor()` peut rendre 2 ? 196 - Modifier le programme initial pour afficher "Salut" en plus de "bonjour" toutes les 1.5 secondes sans changer le comportement existant. 197 198 = Utilisation de l'écran 199 - Modifier le programme initial pour afficher "Salut" en plus de "bonjour" toutes les 1.5 secondes sans changer le comportement existant. Vous aurez donc "Salut" et "bonjour" qui s'affiche avec une périodicité propre à chaque message. 200 201 = Utilisation de l'écran OLED 199 202 200 203 Nous allons utiliser un écran OLED connecté en I2C, 128x32 **ssd1306** … … 212 215 **Questions** 213 216 214 - Extraire de ce code, ce qui est nécessaire pour juste afficher un compteur qui s'incrémente toutes des 1 seconde sur l'écran OLED. 217 - Extraire de ce code, ce qui est nécessaire pour juste afficher un compteur qui s'incrémente toutes des 1 seconde sur l'écran OLED. Vous devez ajouter une tâche nnommée `oled` dans votre programme en conservant celles déjà dans votre sketch (programme Arduino). L'idée, c'est d'avoir plein de tâches ensemble. 215 218 216 219 217 220 = Communications inter-tâches 218 221 219 Lorsqu'on écrit un programme multi-tâches, il est intéressant de les faire communiquer. Pour ce faire, nous allons simplement créer variables globales et les donner en arguments aux t aches communicantes.222 Lorsqu'on écrit un programme multi-tâches, il est intéressant de les faire communiquer. Pour ce faire, nous allons simplement créer variables globales et les donner en arguments aux tâches communicantes. 220 223 221 224 Supposons que nous voulions que la tâche T1 envoie un message à la tâche T2. Nous allons utiliser une boite à lettre. Le code suivant explique le principe qui est basé sur une variable d'état à 2 valeur indiquant l'état de la boite. La boite peut être vide ou pleine. … … 244 247 **Questions** 245 248 246 - Ajouter une tâche qui lit toutes les 0,5 seconde le port analogique 15 (par `analogRead()`) sur lequel se 247 trouve la photo-résistance et qui sort sa valeur dans une boite à lettre. 249 - Dans le texte précédent, quel est le nom de la boîte à lettre et comment est-elle initialisée ? 250 - Ajouter une tâche nommée `lum` qui lit toutes les 0,5 seconde le port analogique 15 (par `analogRead()`) sur lequel se 251 trouve la photo-résistance et qui sort sa valeur dans une boite à lettre. Cette boite à lettre sera connectée à la tâche `oled`. Vous afficher la valeur en pourcentage de 0% à 100% en utilisant la fonction map() 248 252 - Mofifier la tâche Led pour que la fréquence de clignotement soit inversement proportionnel à la lumière reçue 249 (moins il y a de lumière plus elle clignote vite). La tâche Led devra donc se brancher sur la boite à lettre.253 (moins il y a de lumière plus elle clignote vite). La tâche Led devra donc se brancher avec la tâche `lum` avec une nouvelle boite à lettre. Il doit y avoir deux boites sortant de `lum`, l'une vers `oled` l'autre vers `led`. 250 254 251 255 = Gestion des interruptions … … 259 263 **Question** 260 264 261 Ajouter une tâche qui arrête le clignotement de la LED si vous recevez un `s` depuis le clavier. 265 - Ajouter une tâche qui arrête le clignotement de la LED si vous recevez un `s` depuis le clavier. Vous devez ajouter une tâche ISR, et la connecter à la tâche `led` par une nouvelle boîte à lettre. 266 - Représenter le graphe de tâches final sur un dessin. C'est un graphe biparti avec des ronds pour les tâches et des rectangles pour les boites à lettres. 262 267 263 268 {{{