Introduction

Comme nous utilisons FreeRTOS, vous le verrez fréquemment mentionné dans ce document. Cependant, les concepts sont applicables à tous les systèmes d'exploitation temps réel commerciaux.

Si vous trouvez des erreurs ou avez des questions, envoyez un message dans Firmware #onboarding sur Discord.

Qu'est-ce qu'un RTOS ?

Un système d'exploitation en temps réel (RTOS) est un logiciel capable de faire fonctionner des applications de manière très fiable et dans des délais critiques.

RTOS vs GPOS

Examinons la différence entre un système d'exploitation en temps réel (comme FreeRTOS) et un système d'exploitation polyvalent (comme Windows).

La principale différence est le temps de réponse. Dans un RTOS, les programmes doivent s'exécuter en respectant des contraintes de temps critiques. Imaginons par exemple qu'il faille contrôler l'orientation d'un satellite sur la base des données fournies par un capteur. Si les calculs sont effectués trop tard, le résultat peut être catastrophique, même si les calculs sont finalement effectués. À l'inverse, imaginons que l'on doive éditer une feuille de calcul dans Microsoft Excel. S'il y a une réponse tardive, mais que la feuille est éditée avec succès, il n'y a pas beaucoup de dégâts.

En résumé, un RTOS est responsable de la gestion des ressources matérielles et de l'exécution des applications (tout comme un GPOS), mais il est également capable d'exécuter des applications de manière très fiable et avec un timing très précis.


Tâches

Tâche : Les tâches sont des unités de travail discrètes qui peuvent être exécutées indépendamment au sein d'un système logiciel et qui peuvent être exécutées simultanément avec d'autres tâches. Lorsqu'une tâche particulière est prête à être exécutée et qu'elle est sélectionnée par le planificateur (nous parlerons du planificateur plus tard), la fonction de rappel de la tâche est appelée. Il est à noter que cette fonction de rappel comporte généralement une boucle infinie, mais pas toujours. Chaque tâche est partiellement isolée des autres, chaque tâche ayant sa propre pile (regardez cette vidéo si vous ne connaissez pas la pile : https://www.youtube.com/watch?v=PL31I-Xge5s&list=PLFnDc5Kpka6XulaKLQgvtvWr7caaUVHzs&index=38). Sur certains systèmes, dont FreeRTOS, les tâches sont également appelées threads.

Processus : Un processus est une instance d'un programme. Par exemple, disons que vous avez écrit un programme qui s'exécute sous Windows. Chaque fois que vous exécutez ce programme, vous démarrez un processus. Vous pouvez exécuter plusieurs instances de ce programme, ce qui crée plusieurs processus. Cependant, sur un système à un seul cœur (comme le nôtre), vous ne pouvez exécuter qu'un seul processus à la fois.

Vous pouvez exécuter plusieurs tâches dans un seul processus. Le RTOS gère le passage d'une tâche à l'autre d'une manière qui donne l'impression que plusieurs tâches s'exécutent en même temps. En réalité, à tout moment, une seule tâche est en cours d'exécution (en supposant qu'il s'agisse d'un processeur à un seul cœur).

Le graphique ci-dessous peut aider à visualiser ce phénomène. Note : L'ordre dans lequel les tâches s'exécutent dépend de l'algorithme d'ordonnancement utilisé (discuté dans la section Ordonnancement ).

Untitled

Un exemple de deux tâches sous FreeRTOS est présenté ci-dessous. Dans la fonction principale, nous créons les tâches. Cela indique à FreeRTOS que ces tâches existent et quelle fonction implémente chaque tâche. Maintenant, quand FreeRTOS veut exécuter la tâche A, il exécute simplement la fonction taskA.

Ensuite, nous lançons l'ordonnanceur. FreeRTOS s'occupera alors de passer d'une tâche à l'autre.

// Assume required headers are already included

// Declare task handles
TaskHandle_t xHandleA = NULL;
TaskHandle_t xHandleB = NULL;

// Define the task stack size in words
#define STACK_SIZE 256

/* Task to be created. */
void taskA(void * pvParameters)
{
		/* Task code goes here. */
}

/* Task to be created. */
void taskB(void * pvParameters)
{
		/* Task code goes here. */
}

/* Function that creates a task(s). */
int main(void)
{
		BaseType_t xReturnedA, xReturnedB;

    /* Create the task, storing the handle. */
    xReturnedA = xTaskCreate(
                    taskA,            /* Function that implements the task. */
                    "NAMEA",          /* Text name for the task. */
                   STACK_SIZE,       /* Stack size in words, not bytes. */
                    ( void * ) 1,     /* Parameter passed into the task. */
                    tskIDLE_PRIORITY, /* Priority at which the task is created. */
                    &xHandleA );      /* Used to pass out the created task's handle. */

    xReturnedB = xTaskCreate(
                    taskB, 
                    "NAMEB",       
                    STACK_SIZE,      
                    ( void * ) 1,   
                    tskIDLE_PRIORITY,
                    &xHandleB );

    if( xReturnedA == pdPASS && xReturnedB == pdPASS ) {
        /* The tasks were created successfully, so start the scheduler */
				vTaskStartScheduler()    
		}
		/* If the tasks were created successfully, this line is never reached */
		while (1);  /* Enter an infinite loop */
		return 0;
}