Vous êtes sur la page 1sur 7

II2 – Informatique embarquée

Mise en œuvre d’un système


d’exploitation temps réel :
FreeRTOS – Ordonnancement
Anthony Juton – février 2023

Ce deuxième TP amène à mettre en œuvre l’ordonnancement de plusieurs tâches.


Commencer par tester l’ensemble de la chaîne de développement à l’aide du programme de
base fourni sur moodle pour le TP1. Attention à sauvegarder régulièrement votre code .c par
ailleurs, le configurateur CubeMx supprimait parfois les fichiers sources du projet, dans les
anciennes versions...
FreeRTOS propose une documentation complète :
https://www.freertos.org/features.html
www.freertos.org/fr-content-src/uploads/2018/07/FreeRTOS_Reference_Manual_V10.0.0.pdf
Pour commencer un nouveau projet à partir du projet de base, depuis le volet Project Explorer,
copier le projet puis coller le projet. Vérifier ensuite le fichier .ioc qui doit avoir le même nom que
le projet. Supprimer le dossier debug. Compiler.

1. FreeRTOS

Dans CubeMX, onglet Middleware, activer FreeRTOS.


Dans Advanced Settings, activer USE_NEWLIB_REENTRANT.

Mise en œuvre d’un système d’exploitation temps réel : FreeRTOS – Les tâches 1/8
II2 – Informatique embarquée

1.1. Création des tâches


Une tâche est une instance d’une fonction, de type void, à qui est attribuée une priorité et sa
propre pile. La fonction est lancée par l’ordonnanceur et le plus souvent elle ne se termine pas
(par exemple elle possède une boucle while(1) ) et rend la main au système d’exploitation
régulièrement. La tâche de fond, nommé idle ici, de priorité la plus faible, ne rend jamais la
main. Elle est interrompue dès qu’une tâche doit s’exécuter.
Lors de la création, il faut attribuer une priorité à chaque tâche, entre 1 et 32 par défaut. La
tâche de fond (IDLE) a une priorité 0.
Le configurateur intégré CubeMx, menu FreeRTOS, permet de créer les tâches :

Les tâches sont définies dans le fichier freertos.c.

Il est possible de supprimer la tâche par défaut ou de la remplacer par un nom plus approprié.

Créer 3 tâches : 2 prioritaires pour faire clignoter des leds et une moins prioritaire pour
l’affichage de l’heure.

Mise en œuvre d’un système d’exploitation temps réel : FreeRTOS – Les tâches 2/8
II2 – Informatique embarquée

Générer le code.

Q1. Que trouve-t-on dans le fichier /Core/Inc/FreeRTOSConfig.h ?


Q2. Remarquer la structure des fichiers de FreeRTOS (dans le dossier Middleware > Third_Party).
Indiquer dans quel fichier est l’ordonnanceur.
Q3. Quelle est la ligne du main qui lance l’ordonnanceur. Que se passe-t-il pour les lignes qui
suivent ?

Q4. Quel est le code généré par CubeMx en lien avec la création des tâches, notamment dans
freertos.c.

On trouve notamment le code des fonctions :


void fonction_tache_led2(void const * argument)
{
/* USER CODE BEGIN fonction_tache_led2 */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END fonction_tache_led2 */
}

Q5. Que signifie for(;;) ? Par quoi peut-on le remplacer ?


Q6. Chercher la définition de osDelay() (click droit → Open Declaration et bien ouvrir le .c et non
le .h). Que signifie cmsis_os ? (Google, Qwant et DuckduckGo sont vos amis…). A quelle fonction
FreeRTOS la fonction osDelay fait-elle appel ? Quel est l’intérêt de cette fonction ?

1.2. Mise en sommeil d’une tâche


Une fois créée par l’ordonnanceur, la tâche est dans l’un des états suivants :
• Exécutée (Running) : la tâche utilise le CPU pour s’exécuter,
• Prête (Ready) : la tâche attend que l’ordonnanceur lui donne la main,
• Bloquée : la tâche attend un événement extérieur (attente d’un message par exemple)
ou temporel (un délai). Il peut y avoir un timeout au bout duquel la tâche repasse en
mode ready, même en l’absence de l’événement attendu.
• Suspendue : c’est un état proche de l’état bloqué, la tâche y entre si la suspension a été
demandée explicitement (vTaskSuspend()).

Mise en œuvre d’un système d’exploitation temps réel : FreeRTOS – Les tâches 3/8
II2 – Informatique embarquée

Illustration 1: les différents états d'une tâche

1.3. exercice 1
Créer une tâche se lançant chaque 100 millisecondes pour changer l’état de led1
Créer une tâche se lançant chaque 500 millisecondes pour changer l’état de la led2.
Pour rester plus proche de FreeRTOS, les tâches se mettent en veille grâce à la fonction
vTaskDelay() directement, sans utiliser osDelay().

Une fois le programme en exécution, il est possible d’afficher des fenêtres d’observation de
FreeRTOS : Windows > Show View > Others > FreeRTOS Task List

Figure 1: Activation de l'outil


d'observation de FreeRTOS

Mise en œuvre d’un système d’exploitation temps réel : FreeRTOS – Les tâches 4/8
II2 – Informatique embarquée

Figure 2: FreeRTOS Task List : outil d'observation de l'état des tâches

Q7. Compiler, exécuter. Placer des points d’arrêt.


• Mettre en pause, indiquer et expliquer l’état de chacune des tâches.
• Indiquer dans le compte-rendu la localisation et la taille de la pile de chacune des tâches.
• Les clignotements de leds restent-ils synchronisés ?

1.4. Exercice 2
Créer une tâche se lançant chaque 10 millisecondes pour afficher l’heure issue de HTC_get_time.
L’affichage de l’heure utilise 2 structures :
char text[32];
RTC_TimeTypeDef time;
RTC_DateTypeDef date;
Il est nécessaire de lire la date, pour que l’heure soit mise à jour.
HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);
sprintf(text, "%2u:%02u:%02u", time.Hours, time.Minutes, time.Seconds);

Q8. A l’aide de l’oscilloscope, vérifier si les contraintes temporelles sont bien respectées.

2. Ordonnancement des tâches

On s’intéresse dans ce programme à des tâches indépendantes. L’utilisation de l’écran se fait via
une mémoire intermédiaire, les fonctions LCD_Display peuvent donc être considérées
indépendantes si elles écrivent dans des espaces différents de l’écran. Les tâches utilisant
l’afficheur doivent avoir une pile de 1024 octets au minimum.

2.1. L’attente jusqu’à une date vTaskDelayUntil


Q9. A l’aide de la documentation FreeRTOS, expliquer la différence entre :
vTaskDelay() : https://www.freertos.org/a00127.html
vTaskDelayUntil() : https://www.freertos.org/vtaskdelayuntil.html

Dans les paramètres de FreeRTOS, dans CubeMX, onglet Include parameters, activer la
fonctionnalité vTaskDelayUntil :

Mise en œuvre d’un système d’exploitation temps réel : FreeRTOS – Les tâches 5/8
II2 – Informatique embarquée

Figure 3: Activation de la fonctionnalité vTaskDelayUntil

A l’aide de la documentation FreeRTOS, modifier les tâches led pour utiliser vTaskDelayUntil.

2.2. Exercice 3 – 4 tâches, occupation importante du processeur.


Pour créer des tâches un peu plus gourmandes en ressources, on demande un peu de calcul au
processeur.
Ajouter la bibliothèque math.h dans la zone USER du main : #include "math.h"
Créer dans le main quatre variables pour la mesure du temps et 3 variables pour les calculs :
RTC_TimeTypeDef time1, time2;
RTC_DateTypeDef date1, date2;
uint32_t i,millisecond1,millisecond2,value;
Ajouter dans la section USER CODE 2 (initialisations) le code suivant :
HAL_RTC_GetTime(&hrtc, &time1, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &date1, RTC_FORMAT_BIN);
millisecond1 = (time1.SecondFraction-time1.SubSeconds)*1000/(time1.SecondFraction+1);
for (i=1;i<1000;i++)
value = (value + (int)sqrt(millisecond1*652.3))%100;
HAL_RTC_GetTime(&hrtc, &time2, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &date2, RTC_FORMAT_BIN);
millisecond2 = (time2.SecondFraction-time2.SubSeconds)*1000/(time2.SecondFraction+1);
sprintf(text,"avant:%02u:%03u apres:%02u:%03u", time1.Seconds, (unsigned int)millisecond1,
time2.Seconds, (unsigned int)millisecond2);
BSP_LCD_DisplayStringAt(260,24,(uint8_t*) text,LEFT_MODE);

Q10. Indiquer dans le compte-rendu ce que fait ce code.


Q11. Indiquer la durée du code. Si besoin, un point d’arrêt bien placé permet de voir l’affichage
de la durée du code de calcul même si il est écrasé par la suite.

Garder les 2 tâches Leds mais avec une période de 500 ms.
Modifier la tâche affichage de l’heure pour la faire durer 40 ms (en ajoutant du calcul), avec
toujours une période de 100 millisecondes pour afficher l’heure issue de HTC_get_time à droite
de l’écran. Allumer une led au début de la boucle et l’éteindre avant la mise en sommeil.

Mise en œuvre d’un système d’exploitation temps réel : FreeRTOS – Les tâches 6/8
II2 – Informatique embarquée

Créer une tâche de durée 25 ms (en ajoutant du calcul) se lançant chaque 80 millisecondes pour
afficher l’heure issue de HTC_get_time à gauche de l’écran. Allumer une led au début de la
boucle et l’éteindre avant la mise en sommeil.

Q12. Quel est l’usage total du processeur ?


Q13. Proposer une répartition des priorités suivant l’algorithme Rate Monotonic. La condition de
Liu et Layland est-elle vérifiée ?
Attention, on rappelle que pour afficher l’heure, il faut lire l’heure et la date.
Pour garder la périodicité, il faut utiliser les mise en sommeil vTaskDelayUntil pour les tâches.
• Compiler et exécuter.
• Mettre en pause, indiquer et expliquer l’état de chacune des tâches.
• Les clignotements de leds restent-ils synchronisés ?
Tester pour les tâches Leds les deux mise en sommeil : vTaskDelay et vTaskDelayUntil.

2.3. Exercice 4 – 4 tâches, occupation très importante du


processeur.
Refaire le même exercice avec un temps de calcul de 45 ms pour la tâche de période 100 ms et
35 ms pour la tâche de période 80 ms. A partir de quelle charge processeur l’ordonnancement
n’est plus assuré ?

3. Partage de ressources

On décide désormais d’afficher avec une couleur différente les temps de chaque tâche.
La tâche d’affichage 1 dure 4 ms environ, avec une période de 100 ms.
La tâche d’affichage 2 n’a plus de calculs et une période de 7 ms.
Q14. Que constate-t-on ? Expliquer les raisons du problème.
Pour résoudre ce problème, il est possible d’utiliser un MUTEX ou sémaphore binaire (mutex)
pour bloquer l’usage de la ressource. CubeMx assiste à la création du MUTEX. Le guide de
FreeRTOS donne des éléments sur son usage. ( https://www.freertos.org/CreateMutex.html )
Ajouter un mutex pour protéger la partie du code concernant l’afficheur lcd.
Q15. Le problème est-il résolu ? Pourquoi ?
Q16. Mettre un point d’arrêt dans la section protégée de la tâche de moindre priorité. Que
constate-t-on ?

4. Bibliographie

Mastering the FreeRTOS™Real Time Kernel sur le site https://freertos.org/

UM1907, User manual, Discovery kit for STM32F7 Series with STM32F746NG MCU sur le site
ST.com

Mise en œuvre d’un système d’exploitation temps réel : FreeRTOS – Les tâches 7/8

Vous aimerez peut-être aussi