Xenomai sur APF28

Beaucoup de ceux qui ont travaillé sur microcontrôleur et qui passent sur des systèmes Linux pour l’embarqué sont surpris de tomber sur un système qui n’est pas temps réel.
Alors que l’on était habitué à gérer l’ordonnancement de nos tâches à la main avec un petit scheduler maison, sous Linux il faut se débattre avec les priorités et les réglages de tick d’horloge. Et malgré cela on sait que l’on restera dans du temps réel «mou».

Et oui, Linux n’est pas un système temps réel, on arrive à obtenir de bon résultats avec les dernières versions du kernel mais ça reste du «temps-réel mou».

Pour avoir un système réellement temps réel une technique consiste à s’adjoindre les services d’un deuxième micro-noyau qui lui est temps réel et qui considère Linux comme une tâche subalterne. C’est l’intérêt de xenomai (prononcez Xénomaille 😉 ) qui utilise adeos comme noyau temps réel.

Chez Armadeus les noyaux fournis par défauts pour les cartes ne sont pas directement prévu pour xenomai. Mais après discussion sur le canal IRC du projet et quelques recherches sur le wiki on peut réussir à s’en sortir avec une APF28.

Voici donc un petit tuto de la marche à suivre pour installer Xenomai sur une APF28, j’ai choisi un noyau 3.4.6 de Linux car je savais que quelqu’un l’avait déjà fait avec, mais il faudrait peut-être voir pour un 3.8 qui fonctionne mieux visiblement.

Tout d’abord il faut télécharger le trunk armadeus comme expliqué ici.

$ git clone git://git.code.sf.net/p/armadeus/code apf28

Puis configurer notre «tree» pour une APF28.

$ cd apf28
$ make apf28_defconfig

Un fois que le menu de configuration s'affiche il faut modifier la configuration comme suit:


 Toolchain  --->
     Kernel Headers (Linux 2.6 (manually specified version))  --->
     (3.4.6) linux version
 ...
 Kernel  --->
     Kernel version (Custom version)  --->
         (3.4.6) Kernel version
 
     Linux Kernel Extensions  --->
         [*] Adeos/Xenomai Real-time patch
         (http://download.gna.org/adeos/patches/v3.x/arm/older) Adeos patch URL
         (ipipe-core-3.4.6-arm-4.patch) Path for Adeos patch file
 ...
 System configuration  --->
     (ttyAMA0) Port to run a getty (login prompt) on
 ...

 Package Selection for the target --->
    Real-Time --->
        [*] Xenomai Userspace
...

Ne pas oublier de virer la looongue liste de patchs relatifs au vieux noyau 2.6.x. Le plus simple pour cela est d'éditer directement le fichier .config de buildroot (buildroot/.config) et ne mettre la valeur suivante pour les patch :

 BR2_LINUX_KERNEL_PATCH="../patches/linux/$(BR2_LINUX_KERNEL_VERSION)"

Ainsi que les patches se trouvant dans le package xenomai du buildroot armadeus, qui sont eux aussi spécifiques au vieux noyau officiel:

$ cd buildroot/package/xenomai/
$ rm adeos-00-compatibility_with_armadeus.patch adeos-01-adeos-prevent_system_freeze_on_mxc_with_gpio_generated_interrupts.patch

Il faut de plus modifier busybox :

 $ make busybox-menuconfig

Avec les options suivantes :

Shells  --->
        Choose your default shell (ash)  --->
    --- ash
    ---   Ash Shell Options
          ...
          [*]   Builtin getopt to parse positional parameters 

Puis lancer le make général.

$ make

Si cette erreur survient :

make[1]: /opt/projects/armadeus/apf28_xenomai/buildroot/output/build/xenomai-2.6.2.1/scripts/prepare-kernel.sh : commande introuvable

Il faut forcer la compilation du paquet xénomai en lançant un make dédié:

$ make xenomai

Puis relancer le make général:

$ make

Tout doit s'être déroulé correctement, il suffit maintenant de mettre son APF28 à jour, sous U-Boot ça donne un truc du genre :

BIOS> run update_all

Vu que nous sommes sur un noyau Linux récent les développeur se sont amusés à changer les nom du tty de la console principale, il faut donc le dire à U-Boot sinon on risque de ne pas voir Linux booter :

$ setenv console console=ttyAMA0,115200n8
$ setenv consoledev ttyAMA0

Et là on peut tenter un boot ... jusqu’à tomber sur cette erreur dans Linux :

UBIFS error (pid 1): ubifs_get_sb: cannot open "ubi0:rootfs", error -19
VFS: Cannot open root device "ubi0:rootfs" or unknown-block(0,0)
Please append a correct "root=" boot option; here are the available partitions:
1f00            3072 mtdblock0 (driver?)
1f01             512 mtdblock1 (driver?)
1f02             512 mtdblock2 (driver?)
1f03             512 mtdblock3 (driver?)
1f04             512 mtdblock4 (driver?)
1f05            8192 mtdblock5 (driver?)
1f06          248832 mtdblock6 (driver?)
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
Backtrace:
[] (dump_backtrace+0x0/0x110) from [] (dump_stack+0x18/0x1c)
 r6:00008000 r5:c7fad000 r4:c04f2be0 r3:00000002
[] (dump_stack+0x0/0x1c) from [] (panic+0x74/0xf0)
[] (panic+0x0/0xf0) from [] (mount_block_root+0x1c8/0x208)
 r3:00000002 r2:00000001 r1:c7c27f78 r0:c043f6e4
[] (mount_block_root+0x0/0x208) from [] (prepare_namespace+0x94/0x1cc)
[] (prepare_namespace+0x0/0x1cc) from [] (kernel_init+0x128/0x170)
 r5:c0027b84 r4:c04f1d40
[] (kernel_init+0x0/0x170) from [] (do_exit+0x0/0x6dc)
 r5:c00089d4 r4:00000000

Car le nom du driver de NAND a lui aussi changé ! Or ce paramètre est transmis par U-Boot au kernel au moment du boot. Nous allons donc devoir modifier U-Boot pour que Linux démarre correctement et réussisse à charger le rootfs.
L'essentiel de la configuration de U-Boot se trouve dans le header suivant :

buildroot/target/device/armadeus/apf28/apf28-u-boot-2013.04.h 

À la ligne 153 mettre la valeur suivante :

#define CONFIG_MTDMAP			"gpmi-nand"

Puis reconstruire U-Boot avec les commandes suivantes:

$ make uboot-dirclean
$ make uboot

Et enfin reflasher U-Boot sur son APF28:

BIOS> run update_uboot

Un fois tout cela fait on peut booter Linux correctement et avoir Xénomai qui démarre:

$ dmesg | grep Xeno

Par contre il y a encore un problème avec le xeno-test.

$ xeno-test

Mais on me souffle qu'il est plus facile de passer sur un kernel 3.8 avec le trunk du projet Xénomai pour résoudre ce problème ...

Je vais donc retourner discuter sur le canal irc pour me mettre à la page. Suite au prochain épisode...

Ce contenu a été publié dans embarqué, informatique, kernel. Vous pouvez le mettre en favoris avec ce permalien.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *