Changes between Version 2 and Version 3 of SujetTP6-2017


Ignore:
Timestamp:
Mar 24, 2017, 8:29:45 AM (7 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • SujetTP6-2017

    v2 v3  
    2424== Exécution ''multi-tâches'' ==
    2525
    26 Nous allons docnc voir comment il est possible de programmer des applications multi-tâches coopératives dans l'environnement Arduino sans pour autant alors les services d'un OS. Le code a été volontairement simplifié à l'extrême afin de bien comprendre le principe.
    27 
    28 Commençons par exprimer les besoins. Dans une applications pour micro-contrôleur, il est nécessaire :
    29 - d'exécuter des tâches périodiquement ;
    30 - d'exécuter des tâches lorsque des événements surviennent ;
    31 - de mesurer le temps séparant deux événements ;
    32 - de faire communiquer deux tâches (une tâche T1 s'exécute et produit des données qui sont récupérées par une tache T2) ;
    33 - etc.
     26Nous allons donc voir comment il est possible de programmer des applications multi-tâches coopératives dans l'environnement Arduino sans pour autant alors les services d'un OS. Le code a été volontairement simplifié à l'extrême afin de bien comprendre le principe. ICI, toute l'application sera dans un seul fichier et nous n'allons pas utiliser la programmation objet pour ne pas complexifier (mais nous le ferons plus tard).
    3427
    3528Chaque tâche est représentée par une fonction qui code son comportement.
     
    5245`wairFor()` peut être appelée aussi souvent que nécessaire, elle rend 1 une seule fois par période (second paramètre).
    5346Si elle n'est pas appelée pendant longtemps alors elle rend le nombre de périodes qui se sont écoulées.
    54 Elle
    5547
    5648Dans l'application suivante nous avons deux tâches périodiques `Led()` et `Mess()`.
     
    10698}}}
    10799
    108 
    109100== Utilisation de l'écran ==
    110101
     
    117108  types modèles. Vous allez choisir le bon exemple : 128x32 I2C.
    118109
    119 **Questions** :
     110**Questions**
     111- Que contient le tableau `waitForTimer[]`` ?
     112- Dans quel cas la fonction `waitFor() peut rendre 2 ?
    120113- Quel est le numéro de l'abonné I2C de l'écran ?
    121 - Modifier le programme initial pour afficher "bonjour" sur l'Oled toutes les 2 secondes sans changer le comportement de existant.
     114- Modifier le programme initial pour afficher "bonjour" sur l'Oled toutes les 2 secondes sans changer le comportement existant.
    122115
    123 == Programme demandé ==
     116== Communications inter-tâches ==
    124117
    125 Vous allez reprendre le programme ci-dessus qui fait clignoter la LED et afficher un message périodique sur l'écran Oled et le transformer de sorte à modifier son comportement par des commandes envoyé par l'utilisateur depuis le clavier du PC.
     118Lorsqu'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.
    126119
    127 Le programme est en attente d'un commande pour contrôler l'état de la LED et le message affiché sur l'écran Oled. Les commandes pourraient être :
    128 - A : met la lED en clignotement.
    129 - E : éteint la LED.
    130 - P message : change le message affiché sur l'écran.
     120Supposons 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.
     121l'écrivain T1 ne peut écrire que lorsque la boite est vide. Lorsqu'elle est vide, il y écrit et il change l'état. Inversement, le lecteur attend qu'elle soit pleine. Lorsqu'elle est pleine, il la lit et change l'état.
    131122
    132 Le langage est volontairement simple pour que l'interprétation de la commande soit simple.
    133 Commencez par les commandes de la LED et quand cela marche ajouter la commande de message.
     123Il s'agit d'une communication sans perte. Si T1 ne testait pas l'état de la boite, on pourrait avoir des pertes, c'est parfois nécessaire, si T2 n'a pas eu le temps d'utiliser la boite mais que T1 a une nouvelle valeur, il peut écraser la valeur présente.
     124{{{#!c
     125struct mailbox {
     126  enum {EMPTY, FULL} state;
     127  int val;
     128} mb0 = {.state = EMPTY};
     129
     130void T1(&mb) {
     131  if (mb->state != EMPTY) return; // attend que la mailbox soit vide
     132  mb->val = 42;
     133  mb->state = FULL;
     134}
     135
     136void T2(&mb) {
     137  if (mb->state != FULL) return; // attend que la mailbox soit pleine
     138  // usage de mb->val
     139  mb->state = EMPTY;
     140}
     141}}}
     142
     143**Questions**
     144
     145- Vous allez reprendre le programme ci-dessus qui fait clignoter la LED et afficher un message périodique sur l'écran Oled et le transformer de sorte à modifier son comportement par des commandes envoyé par l'utilisateur depuis le clavier du PC.
     146
     147- Le programme est en attente d'un commande pour contrôler l'état de la LED et le message affiché sur l'écran Oled. Les commandes pourraient être :
     148  - A : met la lED en clignotement.
     149  - E : éteint la LED.
     150  - P message : change le message affiché sur l'écran.
     151
     152  Le langage est volontairement simple pour que l'interprétation de la commande soit simple.
     153  Commencez par les commandes de la LED
     154
     155  Quand cela marche ajouter la commande de message.
     156
     157- Pour la tâche qui lit le clavier vous avez deux possibilités. Un tâche "normale" qui est ordonnancée par la fonction loop() ou une tâche dont l'exécution est déclenchée par l'arrivée d'un caractère. En effet, l'arrivée d'un caractère déclenche une interruption, il est possible de programmer une routine d'interruption ISR (Interrupt Service Routine). Faites une tâche "normale" et tenter de faire une tâche ISR.
    134158
    135159