Changes between Version 1 and Version 2 of IOC20_T04


Ignore:
Timestamp:
Feb 21, 2020, 7:33:47 AM (5 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • IOC20_T04

    v1 v2  
    33= Objectif de la séance
    44
    5 Le but de la séance est d'écrire une application multitâches Arduino utilisant plusieurs périphériques.
     5Le but de la séance est d'écrire une application multitâches Arduino utilisant plusieurs périphériques.
     6L'application finale contiendra toutes les tâches.
    67
    78= Préambule
     
    4445
    4546Il 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.
     47Pour les dessins, je vous incite à revoir le [htdocs:cours/IOC20_C04_Protocoles_filaires_base_Arduino.pdf cours] à partir du slides 31
    4648
    4749Chaque tâche est représentée par
     
    5153
    5254Les 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.
     55Elles peuvent aussi avoir des variables static mais ces variables ont une valeur unique même si la tâche est à plusieurs exemplaires.
    5456
    5557La structure contexte ressemble à :
     
    6365
    6466
    65 C'est la fonction `setup_Tache()`qui va pouvoir initialiser le contexte avec des ar
     67C'est la fonction `setup_Tache()`qui va pouvoir initialiser le contexte avec des paramètres.
    6668{{{#!c
    6769void setup_Tache(struct Tache_st *ctx, params...) {
     
    104106{{{#!c
    105107// --------------------------------------------------------------------------------------------------------------------
    106 // Multi-tâches cooperatives : solution basique
     108// Multi-tâches cooperatives : solution basique mais efficace :-)
    107109// --------------------------------------------------------------------------------------------------------------------
    108110
     
    120122#define MAX_WAIT_FOR_TIMER 2
    121123unsigned 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
    123125  unsigned long newTime = micros() / period;              // numéro de la période modulo 2^32
    124126  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^32
     127  if ( delta < 0 ) delta = 1 + newTime;                   // en cas de dépassement du nombre de périodes possibles sur 2^32
    126128  if ( delta ) waitForTimer[timer] = newTime;             // enregistrement du nouveau numéro de période
    127129  return delta;
     
    131133
    132134struct Led_st {
    133   int timer;                                              // numéro de timer utilisé par WaitFor
     135  int timer;                                              // numéro du timer pour cette tâche utilisé par WaitFor
    134136  unsigned long period;                                   // periode de clignotement
    135137  int pin;                                                // numéro de la broche sur laquelle est la LED
     
    192194
    193195**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() ?
    195198- 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
    199202
    200203Nous allons utiliser un écran OLED connecté en I2C, 128x32 **ssd1306**
     
    212215**Questions**
    213216
    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.
    215218
    216219
    217220= Communications inter-tâches
    218221
    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 taches communicantes.
     222Lorsqu'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.
    220223
    221224Supposons 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.
     
    244247**Questions**
    245248
    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()
    248252- 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`.
    250254
    251255= Gestion des interruptions
     
    259263**Question**
    260264
    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.
    262267
    263268{{{