98 | | Dans une application multiple |
| 98 | Dans la pratique, les tâches des applications communiquent entre elles. Nous pouvons le faire ici en passant par des variables globales dont les adresses sont passées en paramètres des tâches. Ce dernier point est important, il faut absolument que les variables globales ne soient pas directement utilisées par les fonctions de tâches mais toujours passées explicitement en paramètre ceci afin de faciliter la mise au point ET permettre d'avoir plusieurs instances de la même tâche. |
| 99 | |
| 100 | Dans l'exemple qui suit, nous avons ajouter une tâche GetKbd qui lit un message au clavier et le place dans un buffer nommé mess. |
| 101 | C'est la tâche Mess qui fera l'affichage. |
| 102 | Les deux tâches se synchronisent en utilisant une case mémoire nommée full dont la valeur peut prendre deux états: |
| 103 | - 0 = le buffer ne contient pas de message, le buffer appartient à GetKbd qui le remplit à chaque nouveau caractère |
| 104 | - 1 = le buffer contient un message, le buffer appatient à Mess qui le lit et l'affiche |
| 105 | |
| 106 | La case full est mise à 1 par GetKbd et mise à 0 par Mess. |
| 107 | |
| 108 | Il y a une autre communication entre GetKbd et Led que je vous laisse analyser |
| 109 | |
| 110 | {{{#!c |
| 111 | // unsigned int waitFor(timer, period) |
| 112 | // Timer pour taches périodique |
| 113 | // arguments : |
| 114 | // - timer : numéro de timer entre 0 et MAX_WAIT_FOR_TIMER-1 |
| 115 | // - period : période souhaitée |
| 116 | // retour : |
| 117 | // - nombre de période écoulée depuis le dernier appel |
| 118 | // |
| 119 | #define MAX_WAIT_FOR_TIMER 16 |
| 120 | unsigned int waitFor(int timer, unsigned long period){ |
| 121 | static unsigned long waitForTimer[MAX_WAIT_FOR_TIMER]; |
| 122 | unsigned long newTime = micros() / period; |
| 123 | int delta = newTime - waitForTimer[timer]; |
| 124 | if ( delta < 0 ) delta += 1 + (0xFFFFFFFF / period); |
| 125 | if ( delta ) waitForTimer[timer] = newTime; |
| 126 | return delta; |
| 127 | } |
| 128 | |
| 129 | // Variables globales pour la communication inter-taches |
| 130 | char mess[32]; |
| 131 | byte full; |
| 132 | byte onled = 1; |
| 133 | |
| 134 | void Led (int timer, long period, byte led, byte *on) { |
| 135 | static int val = 0; |
| 136 | if (!waitFor(timer,period)) return; // sort s'il y a moins d'une période écoulée |
| 137 | if (*on == 0) { |
| 138 | val = 0; |
| 139 | } |
| 140 | digitalWrite(13,val); |
| 141 | val = 1 - val; |
| 142 | } |
| 143 | |
| 144 | void Mess (byte *full, char * mess) { |
| 145 | if (! (*full) ) return; |
| 146 | *full = 0; |
| 147 | Serial.println(mess); |
| 148 | } |
| 149 | |
| 150 | void setup () { |
| 151 | pinMode(13,OUTPUT); |
| 152 | Serial.begin(115200); |
| 153 | } |
| 154 | |
| 155 | void GetKbd (byte *full, char * mess, byte len, byte *on) { |
| 156 | static byte index = 0; |
| 157 | if (!Serial.available()) return; |
| 158 | char c = Serial.read(); |
| 159 | mess[index++] = c; |
| 160 | if (c == '\n') { |
| 161 | mess[index-1] = 0; |
| 162 | index = 0; |
| 163 | *full = 1; |
| 164 | *on = (strcmp(mess,"on")==0) ? 1 |
| 165 | : (strcmp(mess,"off")==0) ? 0 |
| 166 | : *on; |
| 167 | |
| 168 | } else if (index == len) { |
| 169 | index--; |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | void loop() { |
| 174 | Led (0,100000,13, &onled); // Led est exécutée toutes les 100ms |
| 175 | Mess (&full, mess); // mess est un buffer d'echange avec getkbd et full une bascule de synchro |
| 176 | GetKbd (&full, mess, sizeof(mess), &onled); |
| 177 | } |
| 178 | }}} |
| 179 | |