Linux Embedded

Le blog des technologies libres et embarquées

PREEMPT-RT sur Raspberry Pi

La carte Rasperry Pi (ou RPI) connait un grand succès dans la communauté Linux. Elle est considérée comme l'une des meilleures innovations Linux de l'année 2012. Malgré quelques défauts sur lesquels nous pourront revenir ultérieurement, dont certains sont évoqués par Denis Bodor dans le numéro de janvier 2013 de GNU/Linux magazine, cette carte est très intéressante dans le cadre du test, "bricolage" ou éducation.
Plusieurs articles ont été publiés, y compris dans la communauté francophone par le biais de mon camarade Christophe Blaess. Dans un de ses articles, Christophe évoque l'utilisation de l'extension temps réel Xenomai sur la Raspberry Pi.
Le présent article décrit la mise en place et le test de PREEMPT-RT sans revenir sur la procédure d'installation d'une distribution Linux pour RPI, considérée comme acquise. Le numéro de décembre 2012 de GNU/Linux magazine propose des articles dans ce sens.

L'extension PREEMPT-RT est une  solution alternative à Xenomai. Elle est plus simple à mettre en oeuvre car l'installation se limite à l'application d'un patch au noyau Linux alors que Xenomai nécessite l'installation de bibliothèques de développement dédiées. PREEMPT-RT nécessite cependant un noyau "mainline" ou du moins proche de ce dernier. A première vue la RPI n'est pas forcément un bon candidat puisque les choix techniques sont assez "bas de gamme" (pas de bootloader, carte SD, USB, ...) et peu compatibles avec des contraintes temps réel. Outre les problèmes matériels, le noyau Linux fourni n'est pas officiellement maintenu par l'équipe Linux et il existe deux versions du noyau pour RPI, ici et la (version "officielle").
Qui ne tente rien n'a rien, il est relativement aisé d'appliquer le patch PREEMPT-RT à la version courante (3.6.x) du noyau Linux pour RPI.

$ export ARCH=arm
$ export CROSS_COMPILE=arm-none-linux-gnueabi-
$ git clone git://github.com/raspberrypi/linux.git
$ cd linux
$ bunzip2 -c <path>/patch-3.6.11-rt25.patch.bz2 | patch -p1
$ make bcmrpi_cutdown_defconfig

Il reste à vérifier que l'option de préemption complète Fully Preemptible Kernel (RT) est bien activée dans le menu Kernel features>Preemption Model de la configuration du noyau et l'on peut alors produire un noyau par la commande :

$ make zImage

Le fonctionnement de ce noyau nécessite l'ajout de l'option sdhci-bcm2708.enable_llm=0. Cette option désactive le mode low latency du pilote de la carte SD (merci à Romain Naour pour cette trouvaille !). Nous pouvons alors réaliser un test basé sur les outils cyclictest et hackbench fournis avec PREEMPT-RT. Le principe est de démarrer des tâches temps réel avec cyclictest puis de charger le système avec hackbench. Le dernière colonne représente le jitter maximum constaté, soit quelques dizaines de µs pour une tâche périodique à 1 ms.

# cyclictest -p 99 -t 5 -n -q
T: 0 ( 67) P:99 I:1000 C: 4120 Min: 14 Act: 23 Avg: 23 Max: 55
T: 1 ( 68) P:98 I:1500 C: 2747 Min: 14 Act: 22 Avg: 32 Max: 83
T: 2 ( 69) P:97 I:2000 C: 2177 Min: 15 Act: 21 Avg: 22 Max: 53
T: 3 ( 70) P:96 I:2500 C: 1741 Min: 15 Act: 27 Avg: 24 Max: 60
T: 4 ( 71) P:95 I:3000 C: 1451 Min: 15 Act: 25 Avg: 21 Max: 55

Si l'on charge le système en créant 800 tâches sur un noyau standard, on remarque une très forte augmentation du jitter, qui devient plus de deux fois égal à la période de la tâche.

# hackbench -p -g 20
Running in process mode with 20 groups using 40 file descriptors each (== 800 tasks)
Each sender will pass 100 messages of 100 bytes
Time: 18.455

# fg
cyclictest -p 99 -t 5 -n -q
T: 0 ( 73) P:99 I:1000 C: 22392 Min: 15 Act: 28 Avg: 28 Max: 2042
T: 1 ( 74) P:98 I:1500 C: 14928 Min: 16 Act: 20 Avg: 32 Max: 1616
T: 2 ( 75) P:97 I:2000 C: 11196 Min: 16 Act: 115 Avg: 38 Max: 1376
T: 3 ( 76) P:96 I:2500 C: 8957 Min: 16 Act: 37 Avg: 37 Max: 1718
T: 4 ( 77) P:95 I:3000 C: 7464 Min: 17 Act: 38 Avg: 36 Max: 1523

Dans le cas du noyau PREEMPT-RT, la variation est beaucoup plus faible même si les résultats ne sont pas extraordinaires, certainement à cause de la qualité (moyenne) du noyau de la RPI.

T: 0 ( 81) P:99 I:1000 C: 28485 Min: 14 Act: 21 Avg: 26 Max: 77
T: 1 ( 82) P:98 I:1500 C: 18990 Min: 14 Act: 24 Avg: 28 Max: 88
T: 2 ( 83) P:97 I:2000 C: 14243 Min: 15 Act: 41 Avg: 32 Max: 156
T: 3 ( 84) P:96 I:2500 C: 11394 Min: 15 Act: 28 Avg: 36 Max: 165
T: 4 ( 85) P:95 I:3000 C: 9495 Min: 15 Act: 28 Avg: 35 Max: 79

    • le 29 janvier 2013 à 10:48

      Merci bien pour l'article intéressant! Et s'il vous plait excusez-moi pour mon français mauvais.

      J'ai essayé à suivre votre description. L'application de patch 3.6.11-rt25, l'activation de 'Fully Preemptible Kernel (RT) ', la compilation et l'installation du kernel noveau ont bien fonctionné. L’option sdhci-bcm2708.enable_llm=0 était ajouté en /boot/cmdline.txt. Malheureusement, mes tests avec cyclic_test ont affichés un jitter beaucoup mauvais en comparaison avec votre jitter mesures.

      Est-ce que vous avez une idée ce que j'ai fait faussement?

      Merci bien!

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.