Changes between Version 24 and Version 25 of IOC_T06
- Timestamp:
- Mar 19, 2026, 10:13:43 PM (7 months ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
IOC_T06
v24 v25 115 115 116 116 Chaque tâche est représentée par 117 - une fonction ` loop_Tache()` qui code son comportement qui sera appelée dans la fonction `loop()`.118 - une seconde fonction ` setup_Tache()` qui initialise les ressources de la tâche (périphériques) et l'état interne.119 - une structure contenant l'état interne et le contexte d'exécution représenté par une variable globale sous forme d'une structure `Tache_t`. Cette structure est passée en argument de la tâche des fonctions ` setup_Tache()` et `loop_Tache()`.120 121 Les fonctions ` loop_Tache()` et `setup_Tache()` peuvent avoir des variables locales mais leur état n'est pas conservé entre deux instances d'exécutions.122 Elles peuvent aussi avoir des variables static mais ces variables ont une valeur unique même si la tâche est en plusieurs exemplaires et que donc elle utilise la même fonction ` loop_Tache()`. Les variables static ne sont pas conseillées parce qu'elles ne peuvent être initialisées dans la fonction `setup_Tache()`. Expliquez pourquoi dans le CR pour vérifier que vous avez compris.117 - une fonction `step_Tache()` qui code son comportement qui sera appelée dans la fonction `loop()`. 118 - une seconde fonction `init_Tache()` qui initialise les ressources de la tâche (périphériques) et l'état interne. 119 - une structure contenant l'état interne et le contexte d'exécution représenté par une variable globale sous forme d'une structure `Tache_t`. Cette structure est passée en argument de la tâche des fonctions `init_Tache()` et `step_Tache()`. 120 121 Les fonctions `step_Tache()` et `init_Tache()` peuvent avoir des variables locales mais leur état n'est pas conservé entre deux instances d'exécutions. 122 Elles peuvent aussi avoir des variables static mais ces variables ont une valeur unique même si la tâche est en plusieurs exemplaires et que donc elle utilise la même fonction `step_Tache()`. Les variables static ne sont pas conseillées parce qu'elles ne peuvent être initialisées dans la fonction `init_Tache()`. Expliquez pourquoi dans le CR pour vérifier que vous avez compris. 123 123 124 124 La structure contexte ressemble à : … … 132 132 133 133 134 C'est la fonction ` setup_Tache()`qui initialise le contexte avec des paramètres.135 {{{#!c 136 void setup_Tache(struct Tache_s *ctx, params...) {134 C'est la fonction `init_Tache()`qui initialise le contexte avec des paramètres. 135 {{{#!c 136 void init_Tache(struct Tache_s *ctx, params...) { 137 137 // Initialisation du contexte} 138 138 ctx->etat = etat_initial; // reçu dans les paramètres … … 141 141 }}} 142 142 143 La fonction `loop()` demande donc l'exécution des fonctions ` loop_Tache()` à tour de rôle.143 La fonction `loop()` demande donc l'exécution des fonctions `step_Tache()` à tour de rôle. 144 144 Les tâches n'ont pas le droit de conserver le processeur, sinon cela crée un blocage du système (une famine pour les autres tâches). 145 145 Cela signifie qu'il est interdit de faire des boucles d'attente d'un événement. … … 149 149 150 150 {{{#!c 151 void loop_Tache(tache_t *ctx, connectors....) {151 void step_Tache(tache_t *ctx, connectors....) { 152 152 // test de la condition d'exécution, si absent on SORT 153 153 if (evement_attendu_absent) return; … … 195 195 // -------------------------------------------------------------------------------------------------------------------- 196 196 #define MAX_WAIT_FOR_TIMER 2 197 unsigned int waitFor(int timer, unsigned long period){ 198 static unsigned long waitForTimer[MAX_WAIT_FOR_TIMER]; // il y a autant de timers que de tâches périodiques 199 unsigned long newTime = micros() / period; // numéro de la période modulo 2^32 200 int delta = newTime - waitForTimer[timer]; // delta entre la période courante et celle enregistrée 201 if ( delta < 0 ) delta = 1 + newTime; // en cas de dépassement du nombre de périodes possibles sur 2^32 202 if ( delta ) waitForTimer[timer] = newTime; // enregistrement du nouveau numéro de période 203 return delta; 197 unsigned long waitFor(int timer, unsigned long period) { 198 static unsigned long last_period[MAX_WAIT_FOR_TIMER]; // il y a autant de timers que de tâches 199 unsigned long current = micros() / period; // numéro de période 200 unsigned long delta = current - last_period[timer]; // gère le wrap-around 201 if (delta) last_period[timer] = current; // mise à jour si déclenchement 202 return delta; // nombre de periode depuis le dernier appel 204 203 } 205 204 … … 213 212 }; 214 213 215 void setup_Led( struct Led_s * ctx, int timer, unsigned long period, byte pin) {214 void init_Led( struct Led_s * ctx, int timer, unsigned long period, byte pin) { 216 215 ctx->timer = timer; 217 216 ctx->period = period; … … 222 221 } 223 222 224 void loop_Led( struct Led_s * ctx) {223 void step_Led( struct Led_s * ctx) { 225 224 if (!waitFor(ctx->timer, ctx->period)) return; // sort s'il y a moins d'une période écoulée 226 225 digitalWrite(ctx->pin,ctx->etat); // ecriture … … 232 231 struct Mess_s { 233 232 int timer; // numéro de timer utilisé par WaitFor 234 unsigned long period; // periode d'affichage233 unsigned long period; // periode d'affichage 235 234 char mess[20]; 236 235 } ; 237 236 238 void setup_Mess( struct Mess_s * ctx, int timer, unsigned long period, const char * mess) {237 void init_Mess( struct Mess_s * ctx, int timer, unsigned long period, const char * mess) { 239 238 ctx->timer = timer; 240 239 ctx->period = period; … … 243 242 } 244 243 245 void loop_Mess(struct Mess_s *ctx) {244 void step_Mess(struct Mess_s *ctx) { 246 245 if (!(waitFor(ctx->timer,ctx->period))) return; // sort s'il y a moins d'une période écoulée 247 246 Serial.println(ctx->mess); // affichage du message 248 247 } 249 248 250 //--------- Déclaration des tâches249 //--------- Déclaration des contexte de tâches 251 250 252 251 struct Led_s Led1; … … 256 255 257 256 void setup() { 258 setup_Led(&Led1, 0, 100000, LED_BUILTIN);// Led est exécutée toutes les 100ms259 setup_Mess(&Mess1, 1, 1000000, "bonjour"); // Mess est exécutée toutes les secondes257 init_Led(&Led1, 0, 100000, LED_BUILTIN); // Led est exécutée toutes les 100ms 258 init_Mess(&Mess1, 1, 1000000, "bonjour"); // Mess est exécutée toutes les secondes 260 259 } 261 260 262 261 void loop() { 263 loop_Led(&Led1);264 loop_Mess(&Mess1);262 step_Led(&Led1); 263 step_Mess(&Mess1); 265 264 } 266 265 … … 298 297 > En conséquence, vous devez modifier une ligne et en ajouter une : 299 298 > * au début du fichier modifier (4 → 16) : `#define OLED_RESET 16 // Reset pin...`` 300 > * Dans la fonction setup() ou setup_oled() (au début avant le begin de oled) : `Wire.begin(4, 15); // pins SDA , SCL`299 > * Dans la fonction setup() ou init_oled() (au début avant le begin de oled) : `Wire.begin(4, 15); // pins SDA , SCL` 301 300 > En outre l'adresse de l'OLED sur le bus I2C est 0x3C (vers la ligne 60) du programme de test. 302 301 … … 328 327 struct mailbox_s mb = {.state = EMPTY}; 329 328 330 void loop_T1(... mailbox_t * mb ...) {329 void step_T1(... mailbox_t * mb ...) { 331 330 if (mb->state != EMPTY) return; // attend que la mailbox soit vide 332 331 mb->val = 42; … … 334 333 } 335 334 336 void loop_T2(... mailbox_t * mb ...) {335 void step_T2(... mailbox_t * mb ...) { 337 336 if (mb->state != FULL) return; // attend que la mailbox soit pleine 338 337 // usage de mb->val … … 357 356 Ici, il faut créer une fonction `SerialEvent()` qui sera invoqué lors de la réception d'un caractère par le port série. 358 357 359 Dans ce système, la fonction ISR sera comme une fonction loop_Tache.358 Dans ce système, la fonction ISR sera comme une fonction step_Tache. 360 359 361 360 **Question**
