Raspberry Pi – Interruptions GPIO avec RTDM

Publié par cpb
Fév 15 2013

IRQ GPIO Raspberry-Pi RTDMDans un article précédent, j’indiquais que le support des interruptions déclenchées par les ports GPIO du Raspberry Pi n’était pas encore satisfaisant sous Xenomai en utilisant un driver RTDM. Depuis quelques semaines  Paul Corner travaille sur le sujet, et il a finalement résolu le problème mercredi dernier. Comme nous le soupçonnions, il y avait un conflit entre le gestionnaire d’interruptions de Xenomai et celui de Linux (qui restait anormalement installé).

Les patches de Paul n’ont pas encore été intégrés dans Xenomai (mais je suppose qu’ils le seront dans les jours à venir). En attendant, voici comment obtenir de meilleurs résultats que précédemment.

Xenomai 2.6.2.1 avec Linux 3.5.7

Récupérons les sources mainline de Linux 3.5.7 et la dernière version de Xenomai.

[~]$ cd ~/Projets/
[Projets]$ mkdir Xenomai-RPI
[Projets]$ cd Xenomai-RPI/
[Xenomai-RPI]$ wget http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.5.7.tar.bz2
--2013-02-15 09:47:09--  http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.5.7.tar.bz2
Résolution de www.kernel.org (www.kernel.org)... 149.20.4.69, 149.20.20.133
Connexion vers www.kernel.org (www.kernel.org)|149.20.4.69|:80... connecté.
requête HTTP transmise, en attente de la réponse... 200 OK
Longueur: 80996724 (77M) [application/x-bzip2]
Sauvegarde en : «linux-3.5.7.tar.bz2»

100%[=================================================>] 80 996 724  1,29M/s   ds 69s     

2013-02-15 09:48:18 (1,12 MB/s) - «linux-3.5.7.tar.bz2» sauvegardé [80996724/80996724]

[Xenomai-RPI]$ wget http://download.gna.org/xenomai/stable/xenomai-2.6.2.1.tar.bz2
--2013-02-15 09:50:15--  http://download.gna.org/xenomai/stable/xenomai-2.6.2.1.tar.bz2
Résolution de download.gna.org (download.gna.org)... 78.40.125.79
Connexion vers download.gna.org (download.gna.org)|78.40.125.79|:80... connecté.
requête HTTP transmise, en attente de la réponse... 200 OK
Longueur: 22647120 (22M) [application/x-bzip2]
Sauvegarde en : «xenomai-2.6.2.1.tar.bz2»

100%[=================================================>] 22 647 120  1,31M/s   ds 17s     

2013-02-15 09:50:32 (1,31 MB/s) - «xenomai-2.6.2.1.tar.bz2» sauvegardé [22647120/22647120]

[Xenomai-RPI]$

Décompressons et préparons les sources de Linux en utilisant le patch correspondant dans ceux proposés par Xenomai.

[Xenomai-RPI]$ tar xjf linux-3.5.7.tar.bz2 
[Xenomai-RPI]$ tar xjf xenomai-2.6.2.1.tar.bz2 
[Xenomai-RPI]$ xenomai-2.6.2.1/scripts/prepare-kernel.sh --linux=./linux-3.5.7 --arch=arm --adeos=xenomai-2.6.2.1/ksrc/arch/arm/patches/ipipe-core-3.5.7-arm-3.patch 
patching file arch/arm/Kconfig
patching file arch/arm/boot/compressed/decompress.c
patching file arch/arm/boot/compressed/head.S
patching file arch/arm/boot/compressed/string.c
patching file arch/arm/common/gic.c
[...]
patching file mm/mmap.c
patching file mm/mmu_context.c
patching file mm/mprotect.c
patching file mm/vmalloc.c
[Xenomai-RPI]$

Appliquons les patches de Paul Corner. En attendant qu’ils soient intégrés dans Xenomai, je vous en propose une copie sur ce site.

[Xenomai-RPI]$ wget https://www.blaess.fr/christophe/files/article-2013-02-15/Paul\'s-patches.tar.bz2
--2013-02-15 09:57:25--  https://www.blaess.fr/christophe/files/article-2013-02-15/Paul's-patches.tar.bz2
Résolution de www.blaess.fr (www.blaess.fr)... 213.186.33.17
Connexion vers www.blaess.fr (www.blaess.fr)|213.186.33.17|:80... connecté.
requête HTTP transmise, en attente de la réponse... 200 OK
Longueur: 456155 (445K) [application/x-bzip2]
Sauvegarde en : «Paul's-patches.tar.bz2»

100%[=================================================>] 456 155     1,01M/s   ds 0,4s    

2013-02-15 09:57:26 (1,01 MB/s) - «Paul's-patches.tar.bz2» sauvegardé [456155/456155]

[Xenomai-RPI]$ tar xjf Paul\'s-patches.tar.bz2 
[Xenomai-RPI]$ ls "Paul's patches/"
0001-Raspberry-Pi-bcm2835-bcm2708-support-added.patch
0002-Use-correct-module_param-data-type-in-lirc_rpi.c.patch
0003-Default-config.-Minimal-set-of-modules-enabled-along.patch
0004-Switch-to-using-a-chained-interrupt-handler-for-GPIO.patch
[Xenomai-RPI]$

Quatre patches, donc, à appliquer successivement sur le noyau Linux déjà modifié pour Xenomai. Le premier ajoute le support pour le Raspberry Pi.

[linux-3.5.7]$ patch -p1 < ../Paul\'s\ patches/0001* 
patching file Documentation/kernel-parameters.txt
patching file arch/arm/Kconfig
patching file arch/arm/Kconfig.debug
patching file arch/arm/Makefile
Hunk #2 FAILED at 310.
1 out of 2 hunks FAILED -- saving rejects to file arch/arm/Makefile.rej
[...]
patching file drivers/Makefile
Reversed (or previously applied) patch detected!  Assume -R? [n] (Entrée)
Apply anyway? [n] (Entrée)
Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file drivers/Makefile.rej
patching file drivers/base/dma-mapping.c
patching file drivers/char/Kconfig
patching file drivers/char/Makefile
patching file drivers/char/broadcom/Kconfig
[...]
patching file include/linux/sizes.h
patching file include/linux/vmalloc.h
patching file init/Kconfig
Reversed (or previously applied) patch detected!  Assume -R? [n] (Entrée)
Apply anyway? [n] (Entrée)
Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file init/Kconfig.rej
patching file kernel/Makefile
Reversed (or previously applied) patch detected!  Assume -R? [n] (Entrée)
Apply anyway? [n] (Entrée)
Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file kernel/Makefile.rej
patching file kernel/module.c
patching file mm/vmalloc.c
patching file sound/arm/Kconfig
patching file sound/arm/Makefile
patching file sound/arm/bcm2835-ctl.c
[...]
[linux-3.5.7]$

Comme on peut le voir il y a quelques rejets, il s’agit de problèmes bénins, et l’on peut sans risque presser simplement Entrée lorsque patch nous interroge sur la conduite à tenir.

Le second patch permet d’éliminer un avertissement à la compilation et le troisième offre une configuration par défaut pour le Raspberry Pi. Ces deux patches ne sont pas obligatoires.

[linux-3.5.7]$ patch -p1 < ../Paul\'s\ patches/0002* 
patching file drivers/staging/media/lirc/lirc_rpi.c
[linux-3.5.7]$ patch -p1 < ../Paul\'s\ patches/0003* 
patching file arch/arm/configs/bcmrpi_defconfig
[linux-3.5.7]$

Enfin le quatrième patch est celui qui corrige l’erreur dans le gestionnaire d’interruption GPIO qui nous posait tant de soucis jusqu’à présent.

[linux-3.5.7]$ patch -p1 < ../Paul\'s\ patches/0004* 
patching file arch/arm/mach-bcm2708/armctrl.c
patching file arch/arm/mach-bcm2708/bcm2708_gpio.c
[linux-3.5.7]$

Les quatre patches étant appliqués nous pouvons compiler le noyau – par exemple en utilisant la configuration par défaut créée par Paul.

[linux-3.5.7]$ make ARCH=arm help
Cleaning targets:
  clean		  - Remove most generated files but keep the config and
                    enough build support to build external modules
  mrproper	  - Remove all generated files + config + various backup files
  distclean	  - mrproper + remove editor backup and patch files
[...]
  at91x40_defconfig        - Build for at91x40
  badge4_defconfig         - Build for badge4
  bcmring_defconfig        - Build for bcmring
  bcmrpi_defconfig         - Build for bcmrpi
  bonito_defconfig         - Build for bonito
  cam60_defconfig          - Build for cam60
[...]
Execute "make" or "make all" to build all targets marked with [*] 
For further info see the ./README file
[linux-3.5.7]$ make ARCH=arm bcmrpi_defconfig
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  SHIPPED scripts/kconfig/zconf.tab.c
  SHIPPED scripts/kconfig/zconf.lex.c
  SHIPPED scripts/kconfig/zconf.hash.c
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#
[linux-3.5.7]$

Personnellement, je préfère un fichier de configuration personnalisé légèrement différent (j’utilise une console série et pas d’écran vidéo, mon système de fichiers est formaté en ext2 et pas en ext4, etc.)

[linux-3.5.7]$ wget https://www.blaess.fr/christophe/files/article-2013-02-15/config-linux-3.5.7-xenomai
--2013-02-15 10:52:24--  https://www.blaess.fr/christophe/files/article-2013-02-15/config-linux-3.5.7-xenomai
Résolution de www.blaess.fr (www.blaess.fr)... 213.186.33.17
Connexion vers www.blaess.fr (www.blaess.fr)|213.186.33.17|:80... connecté.
requête HTTP transmise, en attente de la réponse... 200 OK
Longueur: 58181 (57K) [text/plain]
Sauvegarde en : «config-linux-3.5.7-xenomai»

100%[=================================================>] 58 181      --.-K/s   ds 0,09s   

2013-02-15 10:52:24 (634 KB/s) - «config-linux-3.5.7-xenomai» sauvegardé [58181/58181]

[linux-3.5.7]$ mv config-linux-3.5.7-xenomai .config
[linux-3.5.7]$ make ARCH=arm menuconfig

On peut vérifier quelques options puis quitter avant de compiler le kernel.

[linux-3.5.7]$ make ARCH=arm CROSS_COMPILE=/usr/local/cross/rpi/bin/arm-linux- -j 4
scripts/kconfig/conf --silentoldconfig Kconfig
WRAP arch/arm/include/generated/asm/auxvec.h
WRAP arch/arm/include/generated/asm/bitsperlong.h
WRAP arch/arm/include/generated/asm/cputime.h
WRAP arch/arm/include/generated/asm/errno.h
[...]
LD [M] lib/zlib_deflate/zlib_deflate.ko
LD [M] lib/zlib_inflate/zlib_inflate.ko
LD [M] net/core/pktgen.ko
LD [M] net/key/af_key.ko
[linux-3.5.7]$

Évidemment la compilation suppose la présence d’une cross-toolchain à l’emplacement indiqué dans la variable CROSS_COMPILE.

Le noyau se trouve dans arch/arm/boot/zImage, je le transfère sur le Raspberry Pi (qui est déjà allumé) en le renommant en kernel.img.

[linux-3.5.7]$ scp arch/arm/boot/zImage root@192.168.5.28:/boot/kernel.img
root@192.168.5.28's password: 
zImage                                                   100% 2553KB   2.5MB/s   00:01    
[linux-3.5.7]$

Les modules du noyau peuvent être regroupés ainsi :

[linux-3.5.7]$ make ARCH=arm INSTALL_MOD_PATH=./modules-rpi modules_install
  INSTALL crypto/aes_generic.ko
  INSTALL crypto/arc4.ko
  INSTALL crypto/authenc.ko
[...]
  INSTALL net/core/pktgen.ko
  INSTALL net/key/af_key.ko
  DEPMOD  3.5.7-core
[linux-3.5.7]$ cd modules-rpi/
[modules-rpi]$ ls
lib
[modules-rpi]$ tar cjf modules-rpi.tar.bz2 lib/
[modules-rpi]$

Je transfère l’archive sur le Raspberry Pi et je la décompresse à la racine du système de fichiers.

[modules-rpi]$ scp modules-rpi.tar.bz2 root@192.168.5.28:/
root@192.168.5.28's password: 
modules-rpi.tar.bz2                                    100%  898KB 897.7KB/s   00:00    
[modules-rpi]$ ssh root@192.168.5.28
root@192.168.5.28's password: 
root@R-Pi [/root]# cd /
root@R-Pi [/]# tar xjf modules-rpi.tar.bz2 
root@R-Pi [/]# reboot
Connection to 192.168.5.28 closed by remote host.
Connection to 192.168.5.28 closed.
[modules-rpi]$ cd ..
[linux-3.5.7]$
Compilons maintenant les composants de l'espace utilisateur de Xenomai. [linux-3.5.7]$ cd ../xenomai-2.6.2.1/
[xenomai-2.6.2.1]$ PATH=$PATH:/usr/local/cross/rpi/bin/
[xenomai-2.6.2.1]$ ./configure --host=arm-linux CFLAGS='-march=armv6' LDFLAGS='-march=armv6'
configure: WARNING: if you wanted to set the --build type, don't use --host.
If a cross compiler is detected then cross compile mode will be used
checking build system type... i686-pc-linux-gnu
checking host system type... arm-unknown-linux-gnu
[...]
config.status: linking ./include/asm-arm to src/include/asm/xenomai
config.status: linking ./include/asm-generic to src/include/asm-generic/xenomai
config.status: executing depfiles commands
config.status: executing libtool commands
[xenomai-2.6.2.1]$ make
Making all in src make[1]: entrant dans le répertoire « /home/cpb/Projets/Xenomai-RPI/xenomai-2.6.2.1/src » 
Making all in include make[2]: entrant dans le répertoire « /home/cpb/Projets/Xenomai-RPI/xenomai-2.6.2.1/src/include »
[...]
make[1]: Rien à faire pour « all-am ».
make[1]: quittant le répertoire « /home/cpb/Projets/Xenomai-RPI/xenomai-2.6.2.1 »
[xenomai-2.6.2.1]$ make DESTDIR=$(pwd)/RPI install
Making install in src
make[1]: entrant dans le répertoire « /home/cpb/Projets/Xenomai-RPI/xenomai-2.6.2.1/src »
Making install in include
make[2]: entrant dans le répertoire « /home/cpb/Projets/Xenomai-RPI/xenomai-2.6.2.1 »
[...]
sudo found (sudo is sudo), testing it...
[sudo] password for cpb:
sudo is working.
make[2]: Rien à faire pour « install-data-am ».
make[2]: quittant le répertoire « /home/cpb/Projets/Xenomai-RPI/xenomai-2.6.2.1 »
make[1]: quittant le répertoire « /home/cpb/Projets/Xenomai-RPI/xenomai-2.6.2.1 »
[xenomai-2.6.2.1]$

On peut transférer les éléments utiles sur le Raspberry Pi. Dans cet article ils ne nous serviront pas car nous écrirons uniquement un module kernel avec RTDM.

[xenomai-2.6.2.1]$ cd RPI/
[RPI]$ tar cjf xenomai-rpi.tar.bz2 usr/xenomai/bin/ usr/xenomai/sbin/ usr/xenomai/lib/
[RPI]$ scp xenomai-rpi.tar.bz2 root@192.168.5.28:/ 
root@192.168.5.28's password: 
xenomai-rpi.tar.bz2                                      100%  330KB 329.8KB/s   00:01    
[RPI]$ ssh root@192.168.5.28
root@192.168.5.28's password: 
root@R-Pi [/root]# cd /
root@R-Pi [/]# tar xjf xenomai-rpi.tar.bz2 
root@R-Pi [/]# exit
Connection to 192.168.5.28 closed.
[RPI]$

Module RTDM

Nous pouvons réutiliser le module irq-gpio-rtdm.c de l’article du 26 janvier dernier avec quelques légères modifications.

irq-gpio-rtdm.c
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/module.h>

#include <rtdm/rtdm_driver.h>

// GPIO IN 23 -> Broche 16
#define GPIO_IN  23
// GPIO OUT 22 -> Broche 15
#define GPIO_OUT 22

static rtdm_irq_t irq_rtdm;

static int handler_interruption(rtdm_irq_t * irq)
{
    static int value = 0;
    gpio_set_value(GPIO_OUT, value);
    value = 1 - value;
    return RTDM_IRQ_HANDLED;
}

static int __init exemple_init (void)
{
    int err;

    int numero_interruption = gpio_to_irq(GPIO_IN);

    if ((err = gpio_request(GPIO_IN, THIS_MODULE->name)) != 0) {
        return err;
    }
    if ((err = gpio_direction_input(GPIO_IN)) != 0) {
        gpio_free(GPIO_IN);
        return err;
    }
    if ((err = gpio_request(GPIO_OUT, THIS_MODULE->name)) != 0) {
        gpio_free(GPIO_IN);
        return err;
    }
    if ((err = gpio_direction_output(GPIO_OUT, 1)) != 0) {
        gpio_free(GPIO_OUT);
        gpio_free(GPIO_IN);
        return err;
    }

    irq_set_irq_type(numero_interruption,  IRQF_TRIGGER_RISING);

    if ((err = rtdm_irq_request(& irq_rtdm, 
                     numero_interruption, handler_interruption, 
                     RTDM_IRQTYPE_EDGE,
                     THIS_MODULE->name, NULL)) != 0) {
        gpio_free(GPIO_OUT);
        gpio_free(GPIO_IN);
        return err;
    }
    return 0; 
}

static void __exit exemple_exit (void)
{
    rtdm_irq_free(& irq_rtdm);
    gpio_free(GPIO_OUT);
    gpio_free(GPIO_IN);
}

module_init(exemple_init);
module_exit(exemple_exit);
MODULE_LICENSE("GPL");

Le fichier Makefile est le suivant, il vous faudra ajuster les portions soulignées des chemins pour correspondre au répertoire que vous avez utilisé pour l’ensemble de ces tests.

Makefile
EXTRA_CFLAGS := -I /home/cpb/Projets/Xenomai-RPI/xenomai-2.6.2.1/RPI/usr/xenomai/include/

ifneq (${KERNELRELEASE},)
    obj-m += irq-gpio-rtdm.o
else
    ARCH ?= arm
    CROSS_COMPILE ?= /usr/local/cross/rpi/bin/arm-linux-
    KERNEL_DIR = /home/cpb/Projets/Xenomai-RPI/linux-3.5.7
    MODULE_DIR := $(shell pwd)
    CFLAGS := -Wall -g 

.PHONY: all
all:: modules

.PHONY: modules
modules:
    ${MAKE} ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} -C ${KERNEL_DIR} SUBDIRS=${MODULE_DIR}  modules

XENOCONFIG=/home/cpb/Projets/Xenomai-RPI/xenomai-2.6.2.1/RPI/usr/xenomai/bin/xeno-config

.PHONY: clean
clean::
    rm -f  *.o  .*.o  .*.o.* *.ko  .*.ko  *.mod.* .*.mod.* .*.cmd *~
    rm -f Module.symvers Module.markers modules.order 
    rm -rf .tmp_versions
endif

Résultats

Les résultats sont très concluants. Avec des observations à l’oscilloscope, on voit que la latence typique pour la réponse à une interruption GPIO est comprise entre 3 et 5 micro-secondes comme en témoigne la capture ci-dessous.
IRQ GPIO Raspberry-Pi RTDM
Je ne connais pas encore la latence maximale, mais à première vue avec un système bien chargé elle ne semble pas dépasser la quinzaine de micro-secondes. Je ferai des mesures plus précises dans les jours à venir.

Conclusion

La maintenance des patches Xenomai pour le Raspberry Pi est compliquée par le fait qu’il n’y a pas encore de support mainline pour cette carte. Certaines rumeurs parlent d’une intégration dans le kernel Linux 3.10, mais rien n’est sûr encore. En attendant, savoir qu’il existe des patches externes permettant d’obtenir des résultats très acceptables en terme de temps réel est plutôt rassurant même si la mise en œuvre est légèrement plus compliquée que pour d’autres plates-formes.

17 Réponses

  1. Olivier dit :

    Bonjour Christophe,

    Dans le cadre d’un projet de robotique, j’ai des codeurs incrémentaux de 5000 impulsions/tours qui me permettent de déterminer la position de mon robot dans son environnement.

    De manière optimale ce robot doit pouvoir atteindre les 0,8m/s donc plus de 20000 impulsions par seconde d’après mes calculs.

    Actuellement, j’utilise un microcontroleur (PSOC 3 de chez Cypress) avec un bloc numérique dédié (une implémentation VHDL si je ne me trompe pas) pour compter les impulsions.

    – Je me demandais si une RPI avec Linux (avec ou sans Xenomaï) pouvait supporter une telle charge en interruption sur ces GPIO?

    – L’APIC ne risque t’il pas d’être débordé?

    -N’y aurait t’il pas des pertes d’interruptions ou un retard de comptage dû à la latence liée à l’appel du handler d’interruption?

    Merci d’avance

    • cpb dit :

      Bonjour,

      Je ne suis pas sûr que l’architecture du Raspberry Pi soit optimale pour ce genre de pilotage, toutefois il me semble qu’il doit pouvoir répondre à ces critères sans problèmes. Avec un gestionnaire d’interruption sous Xenomai – utilisant l’API RTDM – comme celui présenté dans cet article, j’ai mesuré une latence maximale (après 24 heures de fonctionnement sous très haute charge CPU et IRQ) de 41 micro-secondes donc sensiblement inférieure au 50 microsecondes de vos contraintes de comptage. Je vais prolonger mes mesures et affiner la présentation des résultats et je posterai ici le compte-rendu, sûrement dans la semaine.

      J’ai fait également des mesures en déclenchant des interruptions toutes les 10 microsecondes, le système suit sans souci et ne semble pas souffrir de sa charge en IRQ. Toutefois en ce cas, il y a évidemment des occurrences où il rate des interruptions.

      Voici une capture avec ce déclenchement d’interruptions à 100kHZ.

      Déclenchement à 100kHz

      Attention toutefois, le Raspberry Pi n’est pas vraiment adapté à une mise en œuvre en environnement industriel (température, fluctuation d’alimentation, perturbations électro-magnétiques) et je le réserverai plutôt au domaine expérimental.

  2. tahoang dit :

    Hi, thank you for your post.
    Could you please upload your zImage file (ext4 rootfs) ? I have tried many times to compile this kernel. The compile is ok, but i can’t get ./latency to run with it. It always show that « rtheap is missing ». I have used the command « mknod /dev/rtheap c 10 254 » to create rtheap and then try ./latency again but i get another error : « Xenomai: native skin or CONFIG_XENO_OPT_PERVASIVE disabled. ». AFAIK, this cause of the configuration file .config used to compile the kernel. But i have compiled this kernel by using your .config file and also the bcmrpi_defconfig. Both don’t work for me. I have tried to compile the 3.2.27 kernel with xenomai. It works like a charm. But with this 3.5.7 kernel, i can’t get it work.
    Thank in advance for your help.

    P/s: Sorry for my bad english.

    • cpb dit :

      I think that you have compiled the Xenomai native API as a module so you need to do « modprobe xeno_native » or « insmod <PATH-TO-THE-MODULE>/xeno-native.ko » before running latency.

      Here’s the zImage file.

  3. tahoang dit :

    Thank you very much! I can get it run now

  4. Bonsoir Christophe,
    Quand je lance la commande de compilation j’obtiens la suivante erreur:

    make[1]: Entering directory `../../Xenomai-RPI/linux-3.5.7′
    CC [M] ../../Programs/irq-gpio-rtdm/irq-gpio-rtdm.o
    ../../Programs/irq-gpio-rtdm/irq-gpio-rtdm.c:1:8: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘<’ token
    make[2]: *** [../../Programs/irq-gpio-rtdm/irq-gpio-rtdm.o] Error 1
    make[1]: *** [_module_/../../Programs/irq-gpio-rtdm] Error 2
    make[1]: Leaving directory `../../Xenomai-RPI/linux-3.5.7'
    make: *** [modules] Error 2

    J'ai controllé les path et ils sont corrects. S'agit-il d'un problème de syntaxe?
    Merci pour ce tutorial,
    G.B.

    • C’était bien un problème de syntaxe. Lors du chargement du module j’obtiens le message:
      Error: could not insert module irq-gpio-rtdm.ko: Unknown symbol in module

      En controllant les messages du noyau j’ai noté qu’il y avait un problème avec la fonction rtdm_irq_request.

      root@dopamine:/home/userk/Development/Modules# dmesg | tail -2
      [ 74.558155] irq_gpio_rtdm: Unknown symbol rtdm_irq_request (err 0)
      [ 74.558214] irq_gpio_rtdm: Unknown symbol xnintr_detach (err 0)

      Dans la liste des modules chargés, Xenomai l’était pas present. Finalement le module fonctionne après avoir chargé « xeno_native » et « xeno_irqbench ».

      root@dopamine:/home/userk/Development/Modules# modprobe xeno_native
      root@dopamine:/home/userk/Development/Modules# modprobe xeno_irqbench
      root@dopamine:/home/userk/Development/Modules# insmod irq-gpio-rtdm.ko
      [ 2247.116109] Xenomai: starting RTDM services.
      [ 2248.998491] Module gpio correctly loaded!

  5. David dit :

    Does anyone know if the patch has been integrated?

    • cpb dit :

      Xenomai 2.6.3 fully supports the Raspberry Pi.

      The specific patches are located in xenomai-2.6.3/ksrc/arch/arm/patches/raspberry/

      Take a look at the xenomai-2.6.3/ksrc/arch/arm/patches/README file for explanation.

  6. Daivy Merlijs dit :

    Bonjour Christophe,
    J’aimerai utiliser l’API de Xenomai pour connaître l’IRQ d’une GPIO (je fais ça sur Beaglebone Black) ; suis-je obligé de passer par un module pour connaître cette information? J’aimerai plutôt avoir un code en C qui ne fait que m’afficher la valeur de l’IRQ.
    J’utilise Eclipse et je suis sur Mint. Cependant, lors de la compilation, j’obtiens l’erreur suivante :

    In file included from /usr/src/linux-3.8.13-Daivy/include/linux/kernel.h:6:0,
    from /usr/src/linux-3.8.13-Daivy/include/linux/gpio.h:79,
    from ../Test_RTDM.c:14:
    /usr/src/linux-3.8.13-Daivy/include/linux/linkage.h:5:25: fatal error: asm/linkage.h: Aucun fichier ou dossier de ce type
    #include

    J’ai lu sur le net qu’il fallait préciser l’architecture , donc ajouter le dossier « /arch/arm/include » de mon Kernel dans le path d’Eclipse, si je comprends bien. Cependant, même en faisant ça, j’ai énormément d’erreur, du genre (je ne poste pas tout le code) :
    ^
    /usr/src/linux-3.8.13-Daivy/include/linux/gpio.h:85:1: warning: empty declaration [enabled by default]
    struct gpio_chip;
    ^
    /usr/src/linux-3.8.13-Daivy/include/linux/gpio.h:88:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
    {
    ^
    /usr/src/linux-3.8.13-Daivy/include/linux/gpio.h:93:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
    {
    ^
    /usr/src/linux-3.8.13-Daivy/include/linux/gpio.h:99:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
    {
    ^
    /usr/src/linux-3.8.13-Daivy/include/linux/gpio.h:105:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
    {
    ^

    Auriez-vous une idée du problème ?

    • cpb dit :

      Bonjour,

      Il n’est pas conseillé d’utiliser directement les fichiers d’entête du noyau dans une application utilisateur, il vaut mieux utiliser uniquement les fichiers dans /usr/include/.... C’est pour cela que vous avez une cascade d’erreurs à la compilation.

      Qu’entendez-vous par « afficher la valeur de l’IRQ » ?

      • Lire l’état de la broche d’entrée ? Dans ce cas, il suffit d’accéder à l’entrée GPIO et de la lire directement comme dans cet article.
      • Être notifié lors du déclenchement d’une interruption ? Le plus simple, dans l’espace utilisateur est d’attendre avec select() comme indiqué dans cet article.

      Bon courage 😉

      • Daivy Merlijs dit :

        Bonjour,
        Merci de votre réponse. J’ai trouvé mon problème en cherchant un peu et maintenant tout marche parfaitement, votre tutoriel m’a été d’une grande aide. En fait, quand je disais « connaître la valeur de l’IRQ » (ce n’était vraiment pas très clair, j’en suis désolé) c’était en effet simplement lire l’état de la broche d’entrée lors de l’interruption, comme vous l’indiquer dans votre réponse à mon commentaire. Petite question cependant : je suppose qu’il vaut mieux dans ce cas là utiliser l’API User de RTDM (rt_dev_open, rt_dev_read etc) au lieu des traditionnel open/read de votre article? Encore merci mille fois.

  7. Arnaud Gibault dit :

    Bonjour et merci pour ce site formidable (et les livres qui ne le sont pas moins),

    Je me demandais si vous pensiez faire un article avec la nouvelle version de Xenomai et le Raspberry Pi?

    • cpb dit :

      Oui, j’y pense, mais je manque cruellement de temps pour m’occuper de mon blog. Je vais quand même essayer de m’y consacrer un peu plus…

  8. Dnis dit :

    Bonjour,
    Ma première étape est finalisée avec le suivi de votre tuto gpio-freq.
    La finalité est l’utilisation d’un RPI comme compteur de conso gaz et eau.
    Je pense à une gestion d’interruption en incrémentant un compteur dans un fichier.
    Et ensuite le renvoyer sur DOMOTICZ.
    Le RPI ne fera pas que ça…
    Quelle solution me conseillez vous?
    Je débute en prog.
    Quel tuto suivre???? XENIMOIA, RTDM, interruption passive….
    Merci d’avance et bonne année 2015.

    • cpb dit :

      Bonjour,
      Inutile d’utiliser Xenomai ou RTDM, il me semble que les interruptions sur les compteurs de gaz ou d’eau sont relativement rares (espacées de plusieurs millisecondes). Xenomai (et son API de programmation de drivers RTDM) se justifie lorsque les interruptions se produisent toutes les 10 à 100 microsecondes. Si elles sont moins fréquentes, et si le délai de récupération de l’interruption n’est pas crucial, le noyau Linux standard suffit amplement.

      Si on veut utiliser un fichier pour stocker les résultats, le travail doit se faire dans l’espace utilisateur, pas en mode kernel. Je vous conseille d’utiliser une attente passive d’interruptions comme indiqué dans cet article. Le mieux serait d’écrire le programme en C/C++ ou en Python.

      J’ai un ami qui a mis ce principe en œuvre avec succès pour surveiller le niveau d’une citerne de gaz d’une cantine d’entreprise. Son programme lui envoie un mail lorsque le niveau dans la citerne descend sous 30% (« il faut appeler le fournisseur« ), sous 20% (« il faut appeler très rapidement le fournisseur« ) et sous 10% (« risque imminent de pénurie – et donc de révolte/mutinerie – à la cantine« ).

      • Dnis dit :

        Merci pour ce retour, je vais me concentrer sur l’attente passive.
        La compilation du programme en C est réalisé avec gcc? je n’ai pas trouver la méthode de compilation dans le tuto.

URL de trackback pour cette page