Bare-metal, RTOS et Linux embarqué¶
Choisir le mauvais modèle d'exécution est l'une des décisions les plus coûteuses à corriger en cours de projet — bare-metal, RTOS et Linux embarqué répondent à des besoins fondamentalement différents.
Bare-metal : la super loop¶
Le bare-metal est le modèle le plus simple : le firmware s'exécute directement sur le matériel, sans aucune couche d'abstraction OS. Le code démarre au reset et tourne dans une boucle infinie appelée super loop.
Structure d'un firmware bare-metal¶
int main(void) {
HAL_Init(); // Initialisation périphériques
SystemClock_Config(); // Configuration horloge
GPIO_Init(); // Initialisation GPIO
UART_Init(); // Initialisation UART
while (1) { // Super loop
read_sensor();
process_data();
transmit_if_needed();
enter_sleep(); // Réveil sur interruption
}
}
Les interruptions matérielles (ISR) permettent de réagir aux événements asynchrones sans avoir à les scruter dans la boucle principale. C'est un modèle événementiel minimal.
Quand choisir le bare-metal¶
Le bare-metal est optimal dans quatre situations précises :
-
Ressources extrêmement limitées : MCU avec moins de 8 Ko de Flash et 1 Ko de RAM (ATtiny, Cortex-M0 entrée de gamme). Un RTOS impose un overhead de 4–16 Ko Flash et 512 B à 4 Ko RAM minimum.
-
Tâche unique et séquentielle : un capteur qui mesure, compresse et transmet périodiquement n'a pas besoin de multitâche.
-
Déterminisme absolu : sans scheduler RTOS, la latence des ISR est parfaitement prévisible et calculable statiquement.
-
Audit de sécurité et certification : le code bare-metal sans OS est plus facile à analyser formellement (IEC 61508 SIL 3/4, DO-178C).
Limites du bare-metal¶
La super loop devient ingérable dès que la complexité augmente : une tâche longue bloque toutes les autres, la gestion des temporisations avec des flags booléens devient un cauchemar de maintenance, et il est impossible de donner des priorités réelles aux traitements concurrents.
RTOS : ordonnancement déterministe des tâches¶
Un RTOS (Real-Time Operating System) ajoute un scheduler qui alterne l'exécution entre plusieurs tâches de manière déterministe. Chaque tâche a sa propre pile d'exécution et une priorité.
Concepts fondamentaux¶
stateDiagram-v2
[*] --> Ready : Création tâche
Ready --> Running : Scheduler sélectionne
Running --> Ready : Préemption (tâche haute prio prête)\nou quantum expiré
Running --> Blocked : Attente événement\n(sémaphore, queue, délai)
Blocked --> Ready : Événement reçu\nou timeout expiré
Running --> Suspended : vTaskSuspend()
Suspended --> Ready : vTaskResume()
Running --> [*] : vTaskDelete() L'ordonnancement préemptif à priorités fixes est le modèle standard en IoT industriel : la tâche de plus haute priorité prête à s'exécuter prend toujours le CPU. Le scheduler intervient à chaque tick système (typiquement 1 ms) et à chaque événement de synchronisation.
FreeRTOS¶
FreeRTOS est le RTOS le plus déployé dans l'industrie IoT, maintenu par Amazon AWS. Ses caractéristiques clés :
- Empreinte minimale : ~4–6 Ko Flash, ~512 B RAM (noyau seul)
- Scheduler : préemptif à priorités fixes, round-robin optionnel pour tâches de même priorité
- Primitives : tasks, queues, semaphores, mutexes, event groups, stream buffers
- Portabilité : +35 architectures supportées (Cortex-M0 à M7, RISC-V, Xtensa, AVR)
- Licence : MIT depuis 2018
// Exemple FreeRTOS : deux tâches concurrentes
void task_sensor(void *pvParameters) {
TickType_t xLastWakeTime = xTaskGetTickCount();
while (1) {
float temp = read_temperature();
xQueueSend(xDataQueue, &temp, 0);
vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(1000)); // 1 Hz
}
}
void task_transmit(void *pvParameters) {
float data;
while (1) {
if (xQueueReceive(xDataQueue, &data, portMAX_DELAY) == pdPASS) {
mqtt_publish("sensors/temp", data);
}
}
}
Zephyr RTOS¶
Zephyr est le challenger open-source de FreeRTOS, maintenu par la Linux Foundation avec des contributeurs comme Intel, Nordic, NXP et ST. Sa philosophie est différente :
- Modèle de build : basé sur CMake + Kconfig (comme le kernel Linux)
- Device Tree : description matérielle séparée du code (comme Linux)
- Sécurité : TrustZone, stack canaries, ASLR, MPU par tâche
- Écosystème : bibliothèques intégrées (Bluetooth LE, Wi-Fi, Matter, Thread, LwM2M)
- Empreinte : ~8–32 Ko Flash selon la configuration
Zephyr est le choix privilégié pour les projets nécessitant Bluetooth LE certifié (nRF52/nRF53), Matter ou Thread — Nordic et Espressif y ont investi massivement.
Tableau comparatif FreeRTOS vs Zephyr vs ThreadX vs RTEMS¶
| Critère | FreeRTOS | Zephyr | Azure RTOS (ThreadX) | RTEMS |
|---|---|---|---|---|
| Licence | MIT | Apache 2.0 | MIT | BSD/GPL |
| Empreinte Flash (noyau) | 4–6 Ko | 8–32 Ko | 5–10 Ko | ~20–50 Ko |
| Empreinte RAM (noyau) | 512 B–2 Ko | 2–8 Ko | 2–4 Ko | 2–5 Ko |
| Architectures | +35 | +400 boards | +35 | +15 |
| Certification IEC 61508 | Non (SafeRTOS ✓) | Non | SIL 4 (certifiable) | Oui |
| BLE intégré | Non (add-on) | Oui (natif) | Non | Non |
| Device Tree | Non | Oui | Non | Non |
| Courbe apprentissage | Douce | Modérée | Modérée | Élevée |
| Support industriel | AWS, communauté | Linux Foundation | Microsoft | ESA, NASA |
Linux embarqué : quand la puissance le permet¶
Linux embarqué (ou Linux sur SBC/SoM) devient pertinent dès que le projet requiert :
- Une connectivité réseau complexe (TLS 1.3, HTTPS client/serveur)
- Des mises à jour OTA avec rollback (swupdate, RAUC)
- Des conteneurs (Docker, Podman) pour l'isolation d'applications
- Des protocoles industriels complexes (OPC-UA stack, Node-RED, Python)
- Une interface homme-machine (Qt, Wayland, Chromium)
Yocto Project¶
Yocto est l'environnement de build de référence pour les distributions Linux embarqué personnalisées. Il génère une image complète (bootloader + kernel + rootfs) à partir de recettes (bitbake recipes).
meta-poky/ # Base Yocto
meta-openembedded/ # Couche communauté (packages étendus)
meta-myproduct/ # Votre couche personnalisée
recipes-core/
images/
myproduct-image.bb # Définition de votre image
recipes-bsp/
u-boot/
u-boot_%.bbappend # Modifications bootloader
Une image Yocto minimale pour IoT peut tenir dans 32 Mo (kernel + initramfs) avec musl libc. Une image avec Python 3, Node-RED et les certificats TLS dépasse facilement 200 Mo.
Buildroot¶
Buildroot est l'alternative plus simple à Yocto : configuration via menuconfig, build plus rapide, moins flexible mais beaucoup plus accessible.
| Critère | Yocto | Buildroot |
|---|---|---|
| Philosophie | Distribution complète | Système minimal |
| Temps de build initial | 2–6 heures | 30 min–2 heures |
| Courbe d'apprentissage | Élevée (2–4 semaines) | Modérée (1–3 jours) |
| Flexibilité | Très élevée | Bonne |
| Mises à jour partielles | Oui (sstate-cache) | Rebuild complet |
| OTA intégré | RAUC, swupdate (layers) | RAUC, swupdate |
| Usage industriel | Automotive, telecom, IoT | IoT, gateway, routeurs |
Arbre de décision : quel modèle d'exécution ?¶
flowchart TD
A[Nouveau firmware] --> B{Flash disponible ?}
B -- "< 32 Ko" --> C[Bare-metal\nSuper loop + ISR\nPas de RTOS possible]
B -- "> 32 Ko" --> D{Plusieurs tâches\nconcurrentes ?}
D -- Non --> E{Déterminisme\nstrict requis ?}
E -- Oui --> C
E -- Non --> C2[Bare-metal\nPlus simple, moins de bugs]
D -- Oui --> F{Linux requis ?\nMVM / conteneurs / Python}
F -- Oui --> G{RAM disponible ?}
G -- "< 64 Mo" --> H[Linux minimal\nBuildroot\nmusl / BusyBox]
G -- "> 64 Mo" --> I[Linux complet\nYocto / Debian\nPlein écosystème]
F -- Non --> J{Certification\nIEC 61508 ?}
J -- Oui --> K[RTOS certifié\nSafeRTOS / ThreadX\nRTEMS]
J -- Non --> L{Bluetooth LE\nou Matter/Thread ?}
L -- Oui --> M[Zephyr RTOS\nEcosystème radio intégré]
L -- Non --> N[FreeRTOS\nSimple, mature, AWS support] Ce qu'il faut retenir¶
- Le bare-metal est optimal pour les contraintes mémoire extrêmes, les tâches uniques ou les exigences de certification formelle — sa simplicité est une force, pas une faiblesse.
- FreeRTOS reste le choix par défaut pour la majorité des projets IoT : empreinte minimale, écosystème vaste, licence MIT.
- Zephyr s'impose dès que Bluetooth LE certifié, Matter ou Thread est requis, avec un modèle de build moderne (Kconfig + Device Tree).
- Linux embarqué n'est justifié que quand la puissance de calcul et la RAM sont disponibles (Cortex-A, > 64 Mo RAM) — son overhead et sa complexité sont réels.
- Le choix du modèle d'exécution doit être fait avant le choix du MCU : certains MCU sont trop petits pour un RTOS, d'autres trop puissants pour rester en bare-metal.
Chapitre suivant : FPGA et logique reconfigurable — quand le silicium doit être aussi flexible que le logiciel.