---
# System prepended metadata

title: TP Systèmes Temps Réel

---

# TP Systèmes Temps Réel
## Séance 1
1) Primitives pour la temporisation
    - Utilisation de `vTaskDelay()` (attente).
    - Utilisation des timers `TimerHandle_t`

2) Les timers permettent d'exploiter le système d'évenement. Pas d'attente active à l'interieur d'une tâche (`vTaskDelay()`)
3) Régulation proportionelle : 
```c=
void regulation(){
    //On suppose que la consigne et le coefficient proportionnel K sont définis
    
    int mesure = InputReadX();
    int erreur = consigne - mesure;
    int cmd = K*erreur;
    OutputWriteX(cmd);
}
```

4) On peut utiliser un timer :
```c=
int periode = 100;
TimerHandle_t htimer1=xTimerCreate("Timer 1",periode,pdTRUE,NULL,regulation);
xTimerStart(htimer1,0); // appel de regulation() toutes les 100 ms
```
5) Si gain trop élevé, le système peut ne jamais converger vers la consigne

6) À chaque boucle : OutputWriteX() + InputReadX(). Il y a 10 appels de la boucle par seconde à 10Hz donc il y a **10** `In` et **20** `Out`
7) `Id='I'`
8) `xQueueReceive()`
9) `xTicksToWait` est un timeout (temps maximum à attendre). Important si l'on ne veut pas que la tâche attende indéfiniment
    - Unité: nombre de ticks (dépend de la fréquence de tick).
    - `pdMS_TO_TICKS()`: conversion ms <=> nombre de ticks
10) Retour de la fonction :
    - pdPASS: si les données de la queue de message ont été lu avec succès
    - errQUEUE_EMPTY: si la queue de message est vide


## Séance 2
1) Sémaphore (synchronisation hors noyau) et Queue de Message (communication du noyau)
2)
3) Event Bits (or flags) and Event Groups ?
4) xEventGroupSetBits(), xEventGroupClearBits(), xEventGroupWaitBits(), xEventGroupSync()
5) Elle permet une communication de service à service de manière asynchrone, c'est-à-dire que le message n'attend pas de réponse immédiate. Les messages sont stockés dans la file d'attente jusqu'à ce qu'ils soient traités ce qui entraine leur suppression.
6) 
```c
void task_write_can(){
    CanFrame com;
    while(1){
        xQueueReceive(CanTx, &com, portMAX_DELAY);
        while(!CanTxReady())
            vTaskDelay(1);
        CanTxSendFrame(com);
    }
}

void task_read_can(){
    CanFrame com;
    while(1){
        if(CanRxFrameReady()){
            CanRxReadFrame(&com);
            xQueueSend(CanRx, &com, portMAX_DELAY);
            vTaskDelay(1);
        }

    }
}
```

7) La tâche s’occupant de la tourelle ne peut alors plus faire l’hypothèse que le message prélevé dans la queue de messages CanRx est forcément la position demandée 'R'. Cela peut être la réponse à une requête émise par une autre tâche ! ('U').

8) Oui mais le bus est bloqué pendant l'intégralité d'une requête ce qui limite les performances globales de l'application.

9) (En mode Course, cf Annexe 2) Appel de ColorCaptRead() qui retourne une valeur 16 bits, checker la valeur du 16-ième bit


## Séance 3
1) $d = l\times cos(\frac{\pi}{2} - \alpha)$
2) $l = \frac{5}{cos(90 - 45)} = 7.071$
3) Placer la voiture à droite de la route et calculer la distance $d$ avec la formule
4) Sémaphore
5) Non mais possibilité de prendre un message sans l'enlever de la queue `xQueuePeek`
6) Ces primitives ont la particularité de ne pas être bloquante (pas de timeout à définir). Cette propriété est garantie par le fait que ces primitives doivent être utilisée exclusivement dans les ISR
7) Tâche de tri qui notifie les autres tâches via `xEventGroupSetBits` et via des `t_periph` selon le type de message reçu 
8) Mettre la routine de tri dans une ISR, appelé dès qu'il y a un nouveau message dans `CanRx`
9) `t_periph.maj` > 1
10)
    - Lire ColorCaptRead(), le bit 8 vaut 1 si la piste à change
    - Envoyer une commande `'M'`
    - Récupérer la réponse et lire les bits 7-0 (numéro de la piste)
    
11) `ColorCaptRead()`