Table of Contents
Introduction : Le rôle des systèmes d'exploitation en temps réel dans la conception intégrée
Un système d'exploitation en temps réel (RTOS) fournit le cadre pour répondre à ces exigences sans forcer les développeurs à construire une logique de programmation à partir de zéro. Parmi les options disponibles, FreeRTOS se distingue comme un noyau léger et open-source qui est devenu le choix de facto pour les microcontrôleurs (MCU) et les petits processeurs. Son empreinte minimale, sa portabilité étendue et son riche ensemble de fonctionnalités permettent aux ingénieurs de créer des applications efficaces, fiables et évolutives tout en maintenant les coûts matériels à bas.
Cet article s'étend sur le guide original de FreeRTOS, plongeant plus profondément dans son architecture, sa configuration, sa gestion des tâches, ses mécanismes de synchronisation et ses capacités avancées. D'ici là, vous aurez une compréhension approfondie de la façon de tirer parti de FreeRTOS pour le développement de logiciels embarqués de qualité de production.
Qu'est-ce que FreeRTOS?
FreeRTOS est un noyau de système d'exploitation en temps réel, conçu spécialement pour les systèmes embarqués. Il a été créé par Richard Barry et est maintenant maintenu sous le parapluie de FreeRTOS de Amazon Web Services (AWS), assurant un support et un alignement continus avec les écosystèmes d'Internet des objets (IoT). Le noyau fournit multitâche préventive, communication intertâche, primitifs de synchronisation et minuteurs logiciels, tout en ne nécessitant que quelques kilooctets de RAM.
Les attributs clés qui font FreeRTOS si largement adopté sont notamment:
- Open source sous licence MIT:[ Aucun droit de licence, la disponibilité complète du code source et l'utilisation permissive dans les produits commerciaux.
- Portabilité: Ports officiels pour des dizaines d'architectures MCU (ARM Cortex-M, RISC-V, AVR, PIC, etc.) et des chaînes d'outils (GCC, IAR, Keil, LLVM).
- Impression minimale: Le noyau peut fonctionner dans aussi peu que 4 KB de ROM et 1 KB de RAM, ce qui le rend adapté pour les appareils sensibles aux coûts.
- Comportement déterministe : Le calendrier des frais généraux est constant et indépendant du nombre de tâches, assurant un calendrier prévisible.
- Soutien actif de la communauté et du commerce :[ Documentation, forums et services professionnels de l'équipe FreeRTOS et de ses partenaires.
FreeRTOS est souvent la première rencontre d'ingénieurs RTOS, et ses concepts se retrouvent directement dans des systèmes plus complexes, ce qui en fait une excellente plateforme d'apprentissage ainsi qu'une fondation prête à la production.
Concepts de base et objets en noyau
Avant de plonger dans des étapes pratiques, il est essentiel de comprendre les éléments fondamentaux que FreeRTOS fournit.
Tâches
Les tâches sont des threads d'exécution indépendants qui partagent le temps du CPU selon un agendar préemptif basé sur la priorité. Chaque tâche a sa propre pile et son propre contexte. FreeRTOS prend en charge un nombre illimité de tâches (limité uniquement par la mémoire disponible).
Demandes
Les files d'attente FreeRTOS sont FIFO ou LIFO (ce dernier via ) et peuvent contenir des éléments de données de taille fixe. Les opérations de file d'attente sont conçues pour être efficaces et sans interruption lorsqu'elles sont utilisées avec les variantes correctes de l'API.
Sémaphores et Mutex
FreeRTOS propose des sémaphores binaires, des sémaphores de comptage et des mutexes. Les sémaphores binaires agissent comme des drapeaux simples utilisés pour signaler ou synchroniser les tâches (par exemple, notification d'interruption).
Chronomètres logiciels
Le noyau fournit des minuteurs logiciels qui exécutent une fonction de rappel quand une période s'écoule. Les minuteurs peuvent être un seul coup (feu une fois) ou un rechargement automatique. Ils exécutent dans une tâche de service de minuterie dédiée, de sorte que leurs gestionnaires doivent être courts et non-bloquants.
Groupes d'événements
Les groupes d'événements permettent d'attendre une combinaison de plusieurs bits (événements) à définir. Ils simplifient les scénarios où une action dépend de plusieurs conditions asynchrones, telles que les lectures de capteurs et une touche utilisateur.
Commencer par FreeRTOS
Adopter FreeRTOS nécessite d'évaluer votre matériel cible, d'obtenir la source du noyau, et de le configurer pour correspondre aux contraintes de votre application.
Choisir un Microcontrôleur Compatible
Les ports FreeRTOS existent pour presque toutes les familles MCU populaires. Confirmez que votre appareil choisi a suffisamment de RAM et flash pour le noyau plus vos tâches. Par exemple, un ARM Cortex-M0+ avec 16 KB RAM peut exécuter confortablement quelques tâches, tandis qu'un Cortex-M4 avec 256 KB RAM supporte beaucoup.
Téléchargement et intégration du noyau
Le dernier code source FreeRTOS est disponible sur le site officiel FreeRTOS ou via GitHub. La distribution comprend le noyau (), les fichiers de couches portables () et les projets de démonstration. Pour un démarrage efficace, copiez le et le répertoire portable approprié dans votre arborescence de projet.
Configuration : Le fichier
Tout le comportement du noyau est contrôlé par . Il est essentiel de bien définir ces paramètres pour les performances et la stabilité. Les macros de configuration clés comprennent :
- :[ Set to 1 pour l'horaire préemptif (typique pour les applications en temps réel). Set to 0 pour l'horaire coopératif.
- :[ La fréquence réelle de l'horloge du processeur (utilisée par le noyau pour le timing correct).
- :[ La fréquence du système tiques interruption minuterie. Les valeurs communes sont 100 Hz (10 ms tic) ou 1000 Hz (1 ms tic).
- :[ Quantité totale de RAM disponible pour l'attribution de mémoire dynamique (utilisée par .
- :[ La taille de la pile (en mots) pour la tâche inactive et la valeur par défaut pour les nouvelles tâches si elle n'est pas spécifiée.
- :[ Longueur maximale des noms de tâches lisibles par l'homme (aide à déboger).
- :[ Réglé à 1 pour les compteurs de tiques 16 bits (save RAM mais limite la valeur maximale de tiques à 65535 – non recommandé pour les systèmes à longue durée ou à taux de tiques élevé).
En outre, choisissez un système de gestion du tas par et . Le noyau comprend cinq implémentations de tas (heap 1 à heap 5) avec des compromis différents dans la fragmentation, la vitesse d'attribution et le déterminisme. La plupart des applications utilisent (premier ajustement avec coalescence) ou (multiples régions de mémoire non contiguë).
Création de tâches et gestion du cycle de vie
La création de tâches est simple, mais les détails du dimensionnement de la pile, les priorités et les transitions d'état affectent profondément la fiabilité du système.
Utilisation
Une tâche est créée en définissant une fonction qui ne retourne jamais (une boucle est typique) et en appelant :
TaskHandle_t xHandle;
xTaskCreate(
vTaskFunction, // Task function pointer
"MyTask", // Name for debugging
configMINIMAL_STACK_SIZE, // Stack size in words
NULL, // Parameters passed to task
2, // Priority (higher number = higher priority)
&xHandle // Optional task handle
);
La fonction doit initialiser les périphériques nécessaires et entrer ensuite dans sa boucle infinie, effectuer son travail, dormir ou attendre des événements.
Priorités de la tâche et calendrier
FreeRTOS supporte les priorités de 0 (plus bas) à (plus élevé). La tâche sans interruption est exécutée à la priorité 0. Le programmeur préventif exécutera toujours la tâche la plus prioritaire prête. Si deux tâches partagent la même priorité, elles slicent le temps (ronde-robin) avec une durée égale à une période de tic. Évitez de donner aux tâches non critiques la même priorité que les tâches critiques; sinon, le slice peut introduire des jitters dans les tâches hautement prioritaires.
États parties
Chaque tâche existe dans l'un de ces états :
- Running:[ La tâche est actuellement exécutée (une seule tâche par cœur du processeur).
- Ready: La tâche est en mesure de fonctionner mais une tâche prioritaire ou prioritaire est actuellement exécutée.
- Blocked: La tâche est d'attendre un événement (timeout, message de file d'attente, semaphore, etc.). Elle ne consomme pas de temps CPU.
- Suspendu: La tâche est retirée de la liste des échéanciers prêts, généralement via . Elle ne peut être reprise explicitement.
Le blocage est le principal mécanisme d'utilisation efficace du CPU : au lieu de procéder à un sondage, une tâche attend simplement une condition, permettant aux tâches moins prioritaires de fonctionner.
Taille de la pile et protection contre les dépassements
Une des sources les plus courantes de bugs FreeRTOS est le débordement de pile. Le noyau fournit deux vérifications optionnelles : . Lorsqu'il est activé, il peut détecter les débordements au moment du changement de contexte. Toujours allouer des tailles de pile généreuses pendant le développement et utiliser la fonction pour voir l'espace libre minimum de pile. Augmenter la pile au besoin avant la libération.
L'allocation statique (en utilisant ) offre plus de contrôle en vous permettant de fournir vous-même le tampon de la pile, ce qui évite la fragmentation du tas et permet de placer dans des régions de mémoire spécifiques (p. ex. mémoire étroitement couplée pour des tâches en temps réel).
Synchronisation et communication intertâches
Les tâches ne fonctionnent que rarement isolément, elles doivent coordonner et échanger des données. FreeRTOS fournit plusieurs mécanismes, chacun adapté à des modèles particuliers.
Demandes de renseignements pour la transmission de données
Utilisez des files d'attente pour envoyer des données d'une tâche (ou interrompre) à une autre. La file d'attente stocke un nombre fixe d'éléments d'une taille donnée. Par exemple, une tâche de lecture de capteur peut envoyer des échantillons à une tâche de journalisation. L'API est simple :
- – envoyer l'élément d'une tâche (blocer si plein).
- – recevoir l'article (blocer si vide).
- Version sûre de l'ISR: et .
Toujours vérifier les valeurs de retour; une file d'attente peut être pleine ou l'appel peut s'éteindre. Dans les RSI, un retour ou indique si un changement de contexte est nécessaire.
Les sémaphores binaires comme des signaux simples
Par exemple, une interruption GPIO peut ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Mutexes avec héritage prioritaire
Lorsque plusieurs tâches accèdent à une ressource partagée (par exemple, une UART ou une structure de données), utilisez un mutex au lieu d'un sémaphore binaire. Mutexes inclut un mécanisme d'héritage prioritaire qui élève temporairement la priorité de la tâche tenant le verrou à la plus haute priorité de toute tâche d'attente. Cela empêche les tâches de priorité moyenne de bloquer indéfiniment une tâche de haute priorité (inversion prioritaire).
Compter les sémaphores pour la gestion des ressources
Par exemple, un bassin de cinq canaux DMA peut être géré avec un sémaphore de comptage initialisé à 5. Une tâche -Tâche prend un sémaphore pour acquérir un canal et -Gives -Tâches quand elle est faite.
Groupes d'événements pour la synchronisation multi-conditions
Si une tâche doit attendre que plusieurs événements indépendants se soient produits, les groupes d'événements sont plus efficaces que plusieurs sémaphores. Les bits sont définis par tâches ou RSI, et la tâche d'attente peut spécifier un masque de bits et si tout ou partie doit être défini. L'API comprend , , et leurs homologues de RSI.
Gestion des interruptions : traitement différé
L'un des modèles les plus importants de FreeRTOS est de garder les RSI extrêmement courts. Au lieu d'effectuer un traitement complexe à l'intérieur d'une interruption, utilisez l'approche suivante:
- À l'intérieur de la RSI, recueillir des données minimales et signaler une tâche (par sémaphore, file d'attente ou notification de tâche).
- Débloquer la tâche, qui fonctionne à une priorité normale pour effectuer le levage lourd.
- Utilisez les versions --FromISR--- des appels de l'API FreeRTOS (, , etc.) et vérifiez le paramètre . Si la tâche débloquée a une priorité plus élevée que la tâche interrompue, un commutateur contextuel est demandé.
Ce traitement d'interruption différé (également appelé gestionnaire de ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Meilleures pratiques pour les applications FreeRTOS de production
Au-delà de l'utilisation de base, plusieurs pratiques séparent un système stable d'un système fragile.
Gestion de la mémoire
Choisissez l'implémentation de tas qui correspond à votre modèle d'allocation. heap 4 est généralement un bon défaut car elle fusionne des blocs libres adjacents. Si votre application crée et supprime fréquemment des tâches ou des files d'attente, évitez heap 2 (pas de counseling) car elle conduit à la fragmentation.
Surveiller l'utilisation du tas en utilisant et . Veiller à ce que soit suffisamment grand pour permettre l'attribution des montants les plus élevés.
Stratégie d'attribution des priorités
Attribuer des priorités en fonction de la date limite et de la criticité de chaque tâche.
- Priorité élevée:[ Boucles de commande critiques dans le temps (p. ex., PID moteur, traitement audio).
- Priorité moyenne:[ Acquisition périodique de données avec des exigences de latence modérée.
- Faible priorité:[ Tâches de fond, mises à jour de l'interface utilisateur, enregistrement.
Évitez d'avoir plusieurs tâches avec la même priorité si elles ont toutes besoin de délais fermes, parce que le délai de délivrance peut introduire l'injustice. Utilisez le blocage pour permettre à des tâches moins prioritaires de fonctionner lorsque des tâches prioritaires sont en attente.
Optimisation de la puissance: Idle sans ardeur
De nombreux dispositifs embarqués sont alimentés par batterie. FreeRTOS prend en charge un mode ralenti sans tic-tac qui arrête l'interruption périodique de la tic lorsque le système est au ralenti et toutes les tâches sont bloquées pour une durée connue. Le MCU peut alors entrer dans un état de sommeil profond. Ceci est configuré en configurant à 1 et en fournissant les macros et . Le résultat peut réduire la consommation d'énergie de plusieurs ordres de grandeur dans les applications axées sur les événements.
Débogue et profilage
FreeRTOS comprend une fonction statistique de l'exécution (facile et ) qui fournit des pourcentages d'exécution des tâches. Cela aide à identifier les porcs et les étalons du CPU. De plus, les fonctions et produisent des résumés lisibles par l'homme dans un tampon de caractères.
Pour une analyse plus approfondie, intégrer FreeRTOS+Trace (maintenant partie du testeur de périphérique AWS IoT). Cet outil enregistre les événements du noyau (switchs de contexte, opérations de file d'attente, entrées ISR) et les affiche dans une chronologie, inestimable pour diagnostiquer les problèmes de chronométrage et les inversions prioritaires.
Caractéristiques avancées
Notifications de tâches
Les notifications de tâches offrent une alternative légère aux sémaphores et aux files d'attente pour la simple signalisation. Chaque tâche a une valeur de notification de 32 bits intégrée et un nombre de notifications en attente. L'envoi d'une notification (via ou ) peut débloquer la tâche de réception avec zéro frais généraux d'un objet noyau séparé. Ceci est plus rapide et utilise moins de RAM que les sémaphores.
Buffers et tampons de message
Introduit dans FreeRTOS V10.0.0, les tampons de flux permettent de passer des données de longueur variable entre les tâches ou entre un ISR et une tâche sans file d'attente de taille fixe. Un tampon de message est un tampon de flux qui préserve également les limites des messages. Ces paramètres sont utiles pour les situations où la taille des données n'est pas connue au préalable, comme les piles de réseau ou les analyseurs de commandes.
Co‐Routines (Légacy)
FreeRTOS comprend également des co-routines, qui sont des tâches sans pile qui partagent une seule pile. Elles sont rarement utilisées dans les applications modernes parce qu'elles compliquent le débogage et ne possèdent pas toutes les caractéristiques des tâches. Il est recommandé d'utiliser des tâches standard à moins que vous ne soyez sévèrement contraint à RAM (p. ex., MCU 8 bits).
Conclusion
FreeRTOS fournit une base solide et bien documentée pour construire des applications intégrées efficaces. Son support pour le multitâche préventive, les primitives de synchronisation riche, et les fonctionnalités avancées comme les notifications de ralenti et de tâches sans cic, le rend adapté à tout, des simples nœuds de capteur aux passerelles complexes IoT. En comprenant les paramètres de configuration du noyau, en suivant les meilleures pratiques pour la gestion de la mémoire et l'attribution des priorités, et en tirant parti des outils de débogage, vous pouvez développer des systèmes fiables en temps réel qui maximisent les performances matérielles tout en maintenant la réactivité.
Pour plus d'informations, consultez le manuel de référence FreeRTOS et explorez les applications de démonstration incluses dans l'arbre source. De nombreux fournisseurs de silicium, tels que STMicroelectronics[ et NXP[, fournissent des guides d'intégration spécifiques aux microcontrôleurs.