
Avez-vous déjà eu besoin de garantir des temps de réponse déterministes sur un Raspberry Pi ?
Que ce soit pour de la robotique, du contrôle industriel ou de la communication EtherCAT, un kernel temps réel est souvent indispensable. Dans cet article, je vous guide pas à pas pour installer un kernel RT_PREEMPT sur Raspberry Pi 4 et je vous propose un tutoriel C++ complet et pédagogique pour apprendre à programmer en temps réel.
Pourquoi le temps réel sur Raspberry Pi ?
Le Raspberry Pi 4 est une plateforme puissante et abordable, mais son kernel Linux standard n’offre aucune garantie de latence. Sous charge, une simple tâche périodique peut subir des retards de plusieurs millisecondes - inacceptable pour certaines applications :
- Robotique : Contrôle de servomoteurs avec période de 1 ms
- EtherCAT : Communication industrielle temps réel
- Audio professionnel : Traitement avec latence ultra-faible
- Acquisition de données : Échantillonnage à fréquence fixe
Le problème illustré
Voici ce qui se passe quand vous exécutez une tâche périodique de 1 ms sur un kernel standard sous charge :
| Métrique | Kernel Standard | Kernel RT |
|---|---|---|
| Latence min | ~10 µs | ~10 µs |
| Latence max | 2-5 ms | < 50 µs |
| Latence moyenne | ~150 µs | ~15 µs |
| Prévisibilité | Aucune | Garantie |
La différence est flagrante : le kernel RT réduit la latence maximale d’un facteur 50 à 100.
Qu’est-ce que RT_PREEMPT ?
RT_PREEMPT est un patch pour le kernel Linux qui le transforme en système temps réel “soft”. Il apporte :
- Préemption complète : Presque tout le code kernel devient préemptible
- Interruptions threadées : Les gestionnaires d’interruption s’exécutent comme des threads ordonnançables
- Priorités temps réel : Les threads SCHED_FIFO/RR préemptent tout le reste
- Horloges haute résolution : Timers précis à la microseconde
Depuis Ubuntu 24.04, le kernel RT est disponible directement dans les dépôts officiels pour Raspberry Pi !
Installation du Kernel RT
J’ai créé un script qui automatise toute la configuration. Voici ce qu’il fait :
1. Installation du package kernel RT
1 | sudo apt install linux-raspi-realtime |
2. Configuration des paramètres de boot
Le script ajoute ces paramètres essentiels dans /boot/firmware/cmdline.txt :
1 | isolcpus=2,3 rcu_nocbs=2,3 nohz_full=2,3 preempt=full |
Explication :
isolcpus=2,3: Isole les CPUs 2 et 3 du scheduler généralrcu_nocbs=2,3: Déplace les callbacks RCU hors de ces CPUsnohz_full=2,3: Désactive les ticks timer quand un seul thread tournepreempt=full: Active la préemption complète
3. Configuration des limites utilisateur
Dans /etc/security/limits.conf :
1 | * soft rtprio 99 |
4. Optimisations système
- CPU governor en “performance”
- Swap désactivé
- Optimisations réseau
Installation rapide
1 | # Télécharger le projet |
Tutoriel pratique en C++
Pour apprendre à utiliser les APIs temps réel, j’ai créé rt_tuto : un tutoriel C++ simple et commenté. Il s’agit d’un programme pédagogique, pas d’un outil de mesure de performance (pour cela, utilisez cyclictest).
Structure du tutoriel
Le programme suit une progression pédagogique en 3 étapes :
| ÉTAPE 1 : Configuration Temps Réel |
|---|
| 1️⃣ mlockall() - Verrouillage mémoire |
| 2️⃣ sched_setscheduler() - SCHED_FIFO priorité 80 |
| 3️⃣ pthread_setaffinity_np() - CPU isolé 2 |
↓
| ÉTAPE 2 : Exécution Boucle Périodique |
|---|
| • clock_nanosleep(TIMER_ABSTIME) - Réveil précis |
| • Mesure de latence à chaque cycle |
| • 1000 itérations de 1 ms (~1 seconde) |
↓
| ÉTAPE 3 : Analyse des Résultats |
|---|
| • Statistiques : min/max/moyenne/écart-type |
| • Histogramme visuel des latences |
| • Recommandations personnalisées |
Les trois piliers du temps réel en C++
Voici les techniques clés utilisées dans le programme :
1. Verrouillage mémoire avec mlockall()
1 | /** |
2. Configuration SCHED_FIFO
1 | /** |
3. Affinage CPU (CPU Pinning)
1 | /** |
La boucle périodique
Le coeur du test est une boucle qui doit se réveiller exactement toutes les 1000 µs :
1 | struct timespec next_period; |
Points importants :
- CLOCK_MONOTONIC : Horloge qui ne saute jamais (contrairement à CLOCK_REALTIME)
- TIMER_ABSTIME : Réveil à un instant absolu, pas relatif
- Calcul de la prochaine période : Gestion propre du débordement des nanosecondes
Résultats
Tests avec cyclictest
Voici les résultats obtenus sur un Raspberry Pi 4 (4 GB) avec Ubuntu 24.04.1 LTS, après configuration du kernel temps réel :
Configuration de test :
- CPU isolé : 2 (via
isolcpus=2,3) - Priorité : SCHED_FIFO 80
- Période : 1 ms
- Durée : 10 000 itérations (~10 secondes)
Commande :
1 | sudo cyclictest -t1 -p 80 -a 2 -m -i 1000 -l 10000 -q |
Résultats :
| Métrique | Valeur |
|---|---|
| Latence minimale | 18 µs |
| Latence moyenne | 23 µs |
| Latence maximale | 29 µs |
Analyse de la distribution :
L’histogramme révèle une stabilité exceptionnelle :
- 84% des mesures entre 23-24 µs (seulement 1 µs d’écart)
- 100% des latences < 36 µs
- Aucune latence au-delà de 40 µs
1 | Histogramme (extrait) : |
Analyse
Avec une latence maximale de 29 µs, le Raspberry Pi 4 atteint un niveau de performance temps réel remarquable :
✅ Excellent pour le temps réel strict (< 50 µs requis)
✅ Distribution très serrée : 84% des mesures concentrées sur 1 µs d’écart
✅ Déterminisme garanti : Aucune latence imprévisible
Ces résultats valident que la configuration est parfaite pour des applications exigeantes :
- Contrôle moteur avec période de 1 ms
- Communication EtherCAT (cycles typiques de 250 µs à 1 ms)
- Acquisition de données synchronisées
- Robotique temps réel
Cross-compilation depuis WSL2
Pour accélérer le développement, j’utilise la cross-compilation depuis WSL2. C’est 5 à 10 fois plus rapide que de compiler sur le Pi.
Installation de la toolchain
1 | # Dans WSL2 Ubuntu |
Compilation
1 | # Avec le script fourni |
Déploiement et exécution
1 | # Copier sur le Pi |
Conclusion
Avec le kernel RT_PREEMPT et une configuration appropriée, le Raspberry Pi 4 devient capable de tâches temps réel avec des latences garanties sous les 100 µs. Les trois éléments clés sont :
- Kernel RT avec paramètres d’isolation CPU
- SCHED_FIFO avec priorité élevée
- mlockall() pour éviter les page faults
Le tutoriel complet en C++ (rt_tuto.cpp) est disponible sur GitHub : https://github.com/jeremydierx/rpi_rt_test
Le code est abondamment commenté et explique chaque API en détail. N’hésitez pas à l’utiliser comme base pour apprendre et développer vos propres projets temps réel !
Tests de stress avec cyclictest
Pour des tests de performance approfondis et stress tests, l’outil de référence est cyclictest (partie du package rt-tests) :
1 | # Installation |
Options importantes :
-t1: 1 thread de test-p 80: Priorité SCHED_FIFO 80-a 2: Épingler sur CPU 2 (isolé)-m: Verrouiller la mémoire-i 1000: Intervalle de 1000 µs (1 ms)-l: Nombre d’itérations-q: Mode silencieux (affiche seulement les résultats finaux)
Ressources
- Linux Foundation - Real-Time Linux
- RT PREEMPT Wiki
- POSIX Real-Time Extensions
- Dépôt GitHub du projet
Jérémy @ Code Alchimie