Le Raspberry Pi offre quelques possibilités d’entrées-sorties directes en utilisant les broches GPIO présentes sur son connecteur P1. Elles ne sont pas très nombreuses (une dizaine) mais cela peut suffire pour des petits projets interactifs nécessitant d’interroger des capteurs tout-ou-rien ou de valider des actionneurs.
Nous pouvons utiliser ces GPIO de différentes façons, depuis l’espace utilisateur ou depuis le noyau. Voyons-en rapidement les principaux aspects…
Les broches GPIO
Sur le connecteur P1 du Raspberry Pi, nous pouvons trouver plusieurs broches consacrées aux entrées-sorties GPIO. Celles-ci peuvent être configurées individuellement en entrées ou en sorties numériques. Attention, la tension appliquée sur une borne d’entrée doit rester inférieure à 3.3 V.
Les GPIO directement accessibles sont les suivantes.
Broche | GPIO |
3 | 0 (rev.1) ou 2 (rev.2) |
5 | 1 (rev.1) ou 3 (rev.2) |
7 | 4 |
11 | 17 |
12 | 18 |
13 | 21 (rev.1) ou 27 (rev.2) |
15 | 22 |
16 | 23 |
18 | 24 |
22 | 25 |
On peut remarquer que certaines broches (3, 5 et 13) ont changé d’affectations au gré des versions du Raspberry Pi, aussi évitera-t-on de les employer pour garder un maximum de portabilité aux applications.
Accès depuis l’espace utilisateur
L’accès simple, depuis le shell – ou tout autre programme de l’espace utilisateur – peut se faire très aisément grâce au système de fichiers /sys
.
/ # cd /sys/class/gpio/ /sys/class/gpio # ls export gpiochip0 unexport
Demandons l’accès au GPIO 24 (broche 18).
/sys/class/gpio # echo 24 > export /sys/class/gpio # ls export gpio24 gpiochip0 unexport /sys/class/gpio # cd gpio24/ /sys/devices/virtual/gpio/gpio24 # ls active_low direction edge subsystem uevent value /sys/devices/virtual/gpio/gpio24 # cat direction in
Sortie de signal
Par défaut, les broches GPIO sont dirigées en entrée. Inversons le sens du 24, puis regardons sa valeur.
/sys/devices/virtual/gpio/gpio24 # echo out > direction /sys/devices/virtual/gpio/gpio24 # cat value 0
Effectivement, le voltmètre confirme qu’il n’y a pas de tension sur la broche.
Modifions l’état de la sortie
/sys/devices/virtual/gpio/gpio24 # echo 1 > value
Vérifions la tension.
Re-basculons la sortie à zéro.
/sys/devices/virtual/gpio/gpio24 # echo 0 > value /sys/devices/virtual/gpio/gpio24 #
Lecture d’état
Demandons à présent l’accès à la broche 16 (Gpio 23)
# cd /sys/class/gpio/ /sys/class/gpio # echo 23 > export /sys/class/gpio # ls export gpio23 gpio24 gpiochip0 unexport /sys/class/gpio # cd gpio23/ /sys/devices/virtual/gpio/gpio23 # cat direction in
Je relie la broche 16 à la broche 20 (GND), puis je lis la valeur d’entrée.
/sys/devices/virtual/gpio/gpio23 # cat value 0
Je relie à présent la broche 16 à la broche 17 (+3.3V)
/sys/devices/virtual/gpio/gpio23 # cat value 1
Retour à nouveau sur la broche 20 (GND).
/sys/devices/virtual/gpio/gpio23 # cat value 0 /sys/devices/virtual/gpio/gpio23 #
Accès depuis le kernel
Lectures et écritures
Nous pouvons écrire un petit module pour accéder en lecture et écriture aux mêmes broches. Dans le module ci-dessous un timer à 8Hz fait clignoter la sortie sur la broche 18 seulement si la broche 16 est mise à 1 (+3.3V).
rpi-gpio-1.c #include <linux/module.h> #include <linux/timer.h> #include <linux/gpio.h> #include <linux/fs.h> // Sortie sur broche 18 (GPIO 24) #define RPI_GPIO_OUT 24 // Entree sur broche 16 (GPIO 23) #define RPI_GPIO_IN 23 static struct timer_list rpi_gpio_1_timer; static void rpi_gpio_1_function (unsigned long unused) { static int value = 1; value = 1 - value; if (gpio_get_value(RPI_GPIO_IN) == 0) value = 0; gpio_set_value(RPI_GPIO_OUT, value); mod_timer(& rpi_gpio_1_timer, jiffies+ (HZ >> 3)); } static int __init rpi_gpio_1_init (void) { int err; if ((err = gpio_request(RPI_GPIO_IN,THIS_MODULE->name)) != 0) return err; if ((err = gpio_request(RPI_GPIO_OUT,THIS_MODULE->name)) != 0) { gpio_free(RPI_GPIO_IN); return err; } if ((err = gpio_direction_input(RPI_GPIO_IN)) != 0) { gpio_free(RPI_GPIO_OUT); gpio_free(RPI_GPIO_IN); return err; } if ((err = gpio_direction_output(RPI_GPIO_OUT,1)) != 0) { gpio_free(RPI_GPIO_OUT); gpio_free(RPI_GPIO_IN); return err; } init_timer(& rpi_gpio_1_timer); rpi_gpio_1_timer.function = rpi_gpio_1_function; rpi_gpio_1_timer.data = 0; // non utilise rpi_gpio_1_timer.expires = jiffies + (HZ >> 3); add_timer(& rpi_gpio_1_timer); return 0; } static void __exit rpi_gpio_1_exit (void) { del_timer(& rpi_gpio_1_timer); gpio_free(RPI_GPIO_OUT); gpio_free(RPI_GPIO_IN); } module_init(rpi_gpio_1_init); module_exit(rpi_gpio_1_exit); MODULE_LICENSE("GPL");
La compilation se fait avec le fichier Makefile
suivant. Les lignes KERNEL_DIR
et CROSS_COMPILE
indiquent respectivement l’emplacement du répertoire de compilation du noyau pour le Raspberry Pi et le préfixe pour la toolchain sur mon système. Il faut les adapter à votre environnement.
Makefile ifneq (${KERNELRELEASE},) obj-m += rpi-gpio-1.o else ARCH ?= arm KERNEL_DIR ?= ~/linux-3.2.27 CROSS_COMPILE ?= /usr/local/cross/rpi/bin/arm-linux- MODULE_DIR := $(shell pwd) CFLAGS := -Wall all: modules modules: ${MAKE} -C ${KERNEL_DIR} ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} SUBDIRS=${MODULE_DIR} modules clean: rm -f *.o .*.o .*.o.* *.ko .*.ko *.mod.* .*.mod.* .*.cmd rm -f Module.symvers Module.markers modules.order rm -rf .tmp_versions endif
Après compilation et transfert sur le Raspberry Pi, nous chargeons le module et observons à l’aide d’un analyseur logique les deux broches 16 (canal 2) et 18 (canal 1), tandis qu’un signal de +3.3V est envoyé sur la broche 16.
Durant la période (mise en évidence par un trait rouge) où la broche 16 se voit appliquer une tension de +3.3V, nous voyons bien une oscillation de la sortie sur la broche 18.
Interruptions
À présent nous allons traiter les interruptions déclenchées par une entrée GPIO. Le module ci-dessous installe un handler d’interruption pour le GPIO 23 (broche 16). À chaque déclenchement de l’interruption, notre handler basculera l’état de la broche de sortie 18 (GPIO 24).
rpi-gpio-2.c #include <linux/interrupt.h> #include <linux/module.h> #include <linux/gpio.h> // Sortie sur broche 18 (GPIO 24) #define RPI_GPIO_OUT 24 // Entree sur broche 16 (GPIO 23) #define RPI_GPIO_IN 23 static irqreturn_t rpi_gpio_2_handler(int irq, void * ident) { static int value = 1; gpio_set_value(RPI_GPIO_OUT, value); value = 1 - value; return IRQ_HANDLED; } static int __init rpi_gpio_2_init (void) { int err; if ((err = gpio_request(RPI_GPIO_OUT, THIS_MODULE->name)) != 0) return err; if ((err = gpio_request(RPI_GPIO_IN, THIS_MODULE->name)) != 0) { gpio_free(RPI_GPIO_OUT); return err; } if ((err = gpio_direction_output(RPI_GPIO_OUT,1)) != 0) { gpio_free(RPI_GPIO_OUT); gpio_free(RPI_GPIO_IN); return err; } if ((err = gpio_direction_input(RPI_GPIO_IN)) != 0) { gpio_free(RPI_GPIO_OUT); gpio_free(RPI_GPIO_IN); return err; } if ((err = request_irq(gpio_to_irq(RPI_GPIO_IN), rpi_gpio_2_handler, IRQF_SHARED | IRQF_TRIGGER_RISING, THIS_MODULE->name, THIS_MODULE->name)) != 0) { gpio_free(RPI_GPIO_OUT); gpio_free(RPI_GPIO_IN); return err; } return 0; } static void __exit rpi_gpio_2_exit (void) { free_irq(gpio_to_irq(RPI_GPIO_IN), THIS_MODULE->name); gpio_free(RPI_GPIO_OUT); gpio_free(RPI_GPIO_IN); } module_init(rpi_gpio_2_init); module_exit(rpi_gpio_2_exit); MODULE_LICENSE("GPL");
Le second module ayant été ajouté dans le Makefile
, nous pouvons le compiler de la même façon que le précédent. Transférons-le sur le Raspberry Pi, puis chargeons-le dans le kernel.
/ # cat /proc/interrupts CPU0 3: 362 ARMCTRL BCM2708 Timer Tick 32: 419 ARMCTRL dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1 52: 0 ARMCTRL BCM2708 GPIO catchall handler 65: 20 ARMCTRL ARM Mailbox IRQ 66: 1 ARMCTRL VCHIQ doorbell 77: 123 ARMCTRL bcm2708_sdhci (dma) 83: 18 ARMCTRL uart-pl011 84: 317 ARMCTRL mmc0 FIQ: usb_fiq Err: 0 / # insmod rpi-gpio-2.ko / # cat /proc/interrupts CPU0 3: 434 ARMCTRL BCM2708 Timer Tick 32: 463 ARMCTRL dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1 52: 0 ARMCTRL BCM2708 GPIO catchall handler 65: 28 ARMCTRL ARM Mailbox IRQ 66: 1 ARMCTRL VCHIQ doorbell 77: 124 ARMCTRL bcm2708_sdhci (dma) 83: 119 ARMCTRL uart-pl011 84: 326 ARMCTRL mmc0 193: 0 GPIO rpi_gpio_2 FIQ: usb_fiq Err: 0 / #
Nous voyons que la ligne d’interruption (numéro 193) est apparue dans /proc/interrupts
. Pour l’instant aucune interruption ne s’est déclenchée. Connectons sur cette entrée un Générateur-Basse-Fréquence, qui lui envoie un signal carré [0, +3.3V] de 2.5kHz environ.
Aussitôt un signal carré apparaît sur la broche de sortie, avec une fréquence moitié du précédent. Nous pouvons le vérifier avec un oscilloscope.
Nous pouvons également vérifier dans /proc/interrupts
que le nombre d’interruptions 193 traitées progresse régulièrement.
/ # cat /proc/interrupts CPU0 3: 646 ARMCTRL BCM2708 Timer Tick 32: 617 ARMCTRL dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1 52: 29791 ARMCTRL BCM2708 GPIO catchall handler 65: 60 ARMCTRL ARM Mailbox IRQ 66: 1 ARMCTRL VCHIQ doorbell 75: 1 ARMCTRL 77: 124 ARMCTRL bcm2708_sdhci (dma) 83: 187 ARMCTRL uart-pl011 84: 342 ARMCTRL mmc0 193: 29792 GPIO rpi_gpio_2 FIQ: usb_fiq Err: 0 / #
En zoomant sur le point de déclenchement, nous mesurons la durée de prise en compte de l’interruption.
La durée entre la montée du signal d’entrée et la réponse du handler est d’environ 7 micro-secondes, ce qui est tout à fait correct pour cette gamme de microprocesseur.
Conclusion
L’accès aux GPIO du port d’extension du Raspberry Pi est très simple, tant depuis l’espace utilisateur que depuis le noyau. Il existe d’autres broches permettant des entrées-sorties GPIO, mais elles ont une autre fonctionnalité par défaut (RS-232, SPI, etc.).
Il serait également intéressant d’accéder aux GPIO depuis un driver RTDM pour Xenomai. Ceci fera l’objet d’un prochain article.
Pour en savoir plus
Si vous souhaitez approfondir l’écriture de drivers pour Linux – notamment pour les GPIO du Raspberry Pi -, je vous propose de vous retrouver en session de formation « Écriture de drivers et programmation noyau Linux » chez Logilin.
Article fort intéressant, merci beaucoup.
je suis en train de tester un RPI et maintenant j’aimerais bien implémenter la connexion RS232 du RPI pour commencer à bien jouer.
Si vous avez des références sur le sujet, je suis preneur.
Ben j’ai pas cherché bien loin, je vois que vous avez fait un article dessus, je vais y jeter un œil
merci
Bonjour,
Est-ce que cet article fait référence à une utilisation de des GPIO de PI avec un noyau temps-réel ou un noyau simple ?
merci
Pour l’instant un noyau classique, mais je vais essayer l’utilisation avec RTDM et Xenomai rapidement.
Cet article est très intéressant mais je ne suis pas sûr d’avoir vraiment tout compris au niveau des interruptions. Est ce qu’il existe un lien physique sur le raspberry pi entre le GPIO et le microprocesseur pour déclencher des interruptions? Ou bien la routine écrite en C est elle purement logicielle pour surveiller le changement d’état d’une broche du GPIO.
En tout cas merci pour les explications, plein de choses a faire avec ce Raspberry…
—
Guy
Bonjour Guy,
L’interruption est bien déclenchée directement par le changement d’état de la broche du GPIO. C’est l’APIC (Advanced Programmable Interrupt Controller) inclus dans le processeur qui détecte les variations de niveaux sur ces broches et envoie une demande d’interruption. Suivant sa configuration, il peut ainsi notifier le CPU d’un front électrique montant, descendant, d’un niveau haut ou bas. Toutes ces configurations ne sont peut-être pas accessibles sur l’APIC du Raspberry Pi, je n’ai pas encore vérifié.
Bonjour,
Merci pour l’article. J’ai cependant deux questions…
Quelle est la valeur de la constante HZ ? Et où est définie jiffies ?
Par ailleurs, si l’on souhaite avoir un timer à 8Hz, ne faut-il pas écrire HZ <> 3 ?
Peut-être me trompé-je lourdement puisque je n’ai aucune expérience dans l’écriture de pilotes, notamment sous Linux…
Merci d’avance !
Mon commentaire a légèrement été formaté…
Je voulais dire HZ << 8.
Et encore une erreur…
Mon dernier mot sera : HZ << 3.
Toutes mes excuses. 🙂
Bonjour,
La constante
HZ
est définie dans un fichier d’en-tête du kernel (<asm/param.h>
si je me souviens bien) et contient le nombre de ticks par secondes (même sur un système tickless).La variable
jiffies
(<linux/jiffies.h>
) contient le nombre de ticks écoulés depuis le boot.Donc
jiffies+HZ
signifie « maintenant + une seconde » (ou plutôt en français : « dans une seconde » ) etjiffies+HZ/8
oujiffies+HZ>>3
signifie « dans un huitième de seconde »Le timer se reprogramme ainsi régulièrement en demandant à être à nouveau invoqué dans un huitième de seconde.
Au temps pour moi, merci beaucoup pour l’explication claire et concise !
Bonjour
Je suis en train de réaliser un projet personnel avec ma mini2440 le noyau image que j’ai récupéré ne me permet pas d’accéder au répertoire sys/class/gpio/. J’aimerais connaître la procédure à faire lors de la compilation du noyau afin d’avoir accès au répertoire gpio. Un tutoriel ou un lien internet expliquant la démarche serait la bienvenue.
Cordialement.
problème résolu
Bonjour
Pour exploiter les GPIO du Raspberry Pi en domotique j’ai réalisé une carte de protection pour évité tout retour d’alimentation qui nuirai à la santé du Rasp, si cela peut vous interesser http://blueberry4pi.com/2013/02/01/carte-de-protection-pour-les-gpio-du-raspberry/
Intéressant, le schéma est-il disponible ?
Hello Christophe !
« high » n’est-il pas supposé mettre la broche en pull up et rien d’autre?
Ca semble passer son etat d’entré en sortie.
# echo in > direction
# cat direction
# in
# echo high > direction
# cat directon
# out
Normalement apres:
# echo high > direction
seule « value » devrait passer a ‘1’ (si broche « en l’air ») mais « direction » devrait rester en « in » ?!
Help !
Inscrire «
high
» dans le fichierdirection
a pour effet de basculer la broche en sortie (si elle ne l’était pas déjà) et la place à l’état1
(+3.3V).Y écrire «
low
» ou «out
» bascule la broche en sortie et la met à 0.Écrire «
in
» dansdirection
passe la broche en entrée.En fait, il ne faut pas considérer «
high
» comme « haute impédance », mais comme « sortie au niveau haut ».NB: le code correspondant est visible dans les sources du kernel, fichier
drivers/gpio/gpiolib.c
, fonctiongpio_direction_store()
.Ah ok.
Il n’y a donc aucun moyen de « tirer » la broche a 3.3V ou GND autrement que via une resistance externe ?
Je bricole juste qq chose pour faire un « shutdown -h » avec un poussoir & Bash.
Je ne suis pas sûr que cela soit possible avec le Raspberry Pi.
J’avais réalisé ce genre de chose sur une Pandaboard via le système de fichier
debugfs
(voir cet article), mais je n’ai pas encore regardé sur le Raspberry et je doute que cela soit possible.C’est un bon article, mais c’est dommage que tu ne fournisses pas les sources qui t’on permis d’arrive jusque-là.
Par exemple : on aimerait savoi d’où vient la table des correspondance broches/GPIO en début d’article. Ca permettrait à tes lecteurs d’avoir d’autres pistes à fouiller.
Hello
J’ai juste inclus j’ai des erreurs:
—————-
gcc -I/usr/include -I/usr/src/linux/include -Wall test.c -o test
In file included from /usr/src/linux/include/linux/list.h:4:0,
from /usr/src/linux/include/linux/module.h:9,
from test.c:8:
/usr/src/linux/include/linux/types.h:13:2: warning: #warning « Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders » [-Wcpp]
…
etc..
—————-
J’ai regardé les sources de wiringPi [http://wiringpi.com] vite fait, les fonctions C proposer semblent a premiere vue acceder au E/S par le biais de fichier (/sys/../value, etc..) est ce aussi ce qui ce passe derriere l’exemple que tu proposes?
Un article, « GPIOs from scratch for newbies », serait bienvenu !
Il ne faut pas faire de compilation des modules du noyau depuis la ligne de commande, il vaut mieux utiliser un Makefile qui va chercher les éléments de configuration et les fichiers d’en-tête du kernel.
Il y en a un présenté dans l’article, il faut juste configurer correctement KERNEL_DIR.
Les accès depuis l’espace utilisateur en début d’article se font en effet par l’intermédiaire de /sys.
J’ai trouvé mon bonheur en attendant d’etre plus degourdi.
« C library for Broadcom BCM 2835 as used in Raspberry Pi »
http://www.airspayce.com/mikem/bcm2835/
C’est moins « usine à gaz » que WiringPi.
Les executables doivent evidement se faire en root (acces a /dev/mem ). Pourtant si je fais un chmod +s dessus ca ne change rien; alors qu’avec « avrdude » cette manip me permet de le lancer en simple utilisateur (/dev/bus/usb je crois).
Que donne un «
ls -l <executable>
» (pour voir les droits et le propriétaire) ?Ok!! merci ! Effectivement le proprietaire etait resté un simple utilisateur ! Pfff… Le pire est que j’ai un « alias ls=’ls -lrt' » mais ca ne m’a pas empeché de ne rien voir.
Bizarrement quand on change le nom du « group », le flag ‘s’ de l’user disparait. Bah !
Bonjour cpb,
Je suis actuellement en train de travaillé sur une carte Emtrion Dimm-mx6 (sujet de stage de master) ou je dois piloté une irq via le kernel space.
Je voulais savoir si ton code (rpi-gpio-2) est général pour tous type de carte ou spécifique au raspberry pi ? (hormis les broches des IO)
Bonjour,
Ce code est assez générique et devrait marcher sur toutes les cartes où le support GPIO est présent dans le kernel.
Etant débutant en programmation sur le kernel, je voulais savoir a quoi correspondait « THIS_MODULE->name ».
j’ai pour but avec ma carte de générer une irq toute les 500µs, pouvez vous m’aidez a modifier votre code (signal irq interne et non d’un gbf avec top toute les 500µs ~2KHz)
THIS_MODULE
est une macro qui représente toujours un pointeur vers lastruct module
du fichier courant. Le champname
contient donc son nom. Ceci permet ici d’identifier le code qui réclame l’accès aux GPIO ou l’inscription d’un handler d’interruption.Vous voulez générer une IRQ toutes les 500µs ou déclencher un timer toutes les 500µs ? Dans le premier cas il faut programmer un timer du CPU pour cela (code spécifique qui dépend du matériel).
Dans le second cas il suffit de programme un HRTimer ainsi :
le but « final » c’est de générer une IRQ. Mais la je peux pour un 1er temps me contenter de générer un timer qui me fait bagoter ma sorti a chacun de ces tops d’horloge.
Comment incorporer le timer dans le rpi-gpio-2.c ?
Merci d’avance
Pour obtenir un signal périodique précis sur une broche de sortie, il est également possible d’utiliser un PWM. Le GPIO 18 sur la broche 12 permet ce genre d’utilisation. Je ne l’ai pas encore exploré mais ça ne doit pas être très compliqué à configurer.
Bonjour cpb,
Grace a ton aide j’ai pu avancer sur mes tests.
J’ai utiliser une pwm comme tu la mentionné dans ton dernier post et j’ai adapté le rpi-gpio-2.c à ma carte pour que ça marche.
Par contre dans le handler de mon programme je lui demande de faire une factorielle pour calculer sont temps de calcul. J’obtient un signal qui oscille beaucoup (pouvant aller au double du temps de calcul min). on m’a dit que cela pouvait venir de IRQF_SHARED | IRQF_TRIGGER_RISING car les IT shared sont gérées par le noyau sous la forme d’une liste chainée de handler. Le temps de réponse n’est donc pas déterministe d’ou mon oscillation.
As tu rencontré ce problème
Bonjour,
Merci pour cet article très bien rédigé.
Après plusieurs recherche c’est le premier article que je trouve avec une information importante concernant les entrées qui prennent du 3V3 max.
Les relevés à l’oscilla sont très intéressants.
Par contre pour l’utilisation côté utilisateur je trouve l’implémentation en python plus simple que celle en C.
La librairie se trouve ici : https://pypi.python.org/pypi/RPi.GPIO et de nombreux exemples sont disponibles sur le web.
J’ai hâte de commencer à utiliser ces GPIO pour la première fois !
Bonne continuation,
Cdlt,
bonjour,
Dans le cadre d’un projet j’ai besoin d’utiliser les broches GPIO de ma raspberry au niveau kernel j’ai pris exemple sur votre code mais j’ai un problème lors de la compilation il ne trouve pas le header .
le système d’exploitation actuel de la raspberry celui fournis sur le site de raspberry, raspbian Whezzy.
La version du kernel est la 3.10.25.
Le manque de ce header est-il normal ou cela vient t’il de l’installation de l’os?
Si cela est normal comment résoudre ce problème?
Merci par avance de votre réponse,
Flo_The_Geek
Bonjour,
Malheureusement, la distribution Raspbian ne fournit pas les sources et les fichiers de configuration du kernel nécessaires pour compiler des modules. Il est donc indispensable de recompiler le noyau. Soit en faisant une cross-compilation depuis un PC, soit en recompilant le noyau directement sur le Raspberry (compter environ 6 heures).
Cordialement,
Merci de votre réponse
bonjour, votre document est très intéressant. j’aimerai savoir comment configurer les broches des GPIO pour les configurer comme des sorties de signaux numériques. merci d’avance
Bonjour,
Pour sortir quel type de signaux ?
Bonjour, c’est une sortie numérique d’un capteur de température
En ce cas, je pense que le capteur doit communiquer ses mesures en utilisant un protocole I²C ou SPI.
Il n’est pas nécessaire d’utiliser les GPIO, il suffit de relier directement les broches correspondantes du connecteur d’extension.
Pour une communication en SPI, on peut se reporter à cet article.
En i²C, il suffit de relier la ligne SDA du capteur à la broche 3 du Raspberry Pi, et la ligne SCL à la broche 5 (et de relier la masse également, sur la broche 25 par exemple).
Ceci fait, il faut charger les modules kernel correspondants :
ou
Dans le premier cas, il suffira ensuite de lire le contenu de
/dev/spidev0.0
par exemple, dans le second cas, je conseille d’installer les outilsi2c-tools
.merci beaucoup.
Bonjour,
je viens de finir la toolschain en ayant suivi le tuto https://www.blaess.fr/christophe/2012/10/19/toolchain-crosstool-ng-pour-raspberry-pi/ merci encore .
Donc maintenant ma toolschain fonctionne pas contre je souhaite utiliser rpi-gpio-2.c malheureusement je rencontre un problème car je n’ai pas les include linux/interrupt.
Quelqu’un pourrais me dire ou les récupérer je pense avec apt-get linux header ou qq que chose comme ça.
je suis sur une vm ubuntu 12.04 et dans /usr/include/linux les fichier ni sont pas.
Merci a celui qui pourrais m’expliquer comme faire
cyrille
Bonjour,
Pour pouvoir compiler des modules pour le noyau Linux (comme c’est le cas pour
rpi_gpio_1.c
etrpi_gpio_2.c
), il faut unMakefile
particulier (comme celui indiqué dans l’article) dont on remplit la variableKERNEL_DIR
avec le chemin des sources du noyau de la cible.Il ne faut donc pas lui donner le chemin des sources de votre PC (ce que vous obtiendrez avec
apt-get install linux-headers
) mais celui du noyau du Raspberry Pi.Si vous l’avez compilé vous même (à la manière décrite dans ces articles) vous avez les sources du kernel à disposition.
Si vous utilisez sur le Raspberry Pi une distribution comme Raspbian, les en-têtes du noyau ne sont malheureusement pas fournis. Une solution relativement simple (mais qui va demander initialement un temps de compilation très long) est décrite dans cet article.
Merci de ta réponse
je n’ai fais aucune des 2 solutions d’écrites donc je vais faire la 2 ème :
Si vous utilisez sur le Raspberry Pi une distribution comme Raspbian, les en-têtes du noyau ne sont malheureusement pas fournis. Une solution relativement simple (mais qui va demander initialement un temps de compilation très long) est décrite dans cet article.
je commence de suite à moins que quelqu’un a déjà une image de faite ?
par avance merci
Alors donc voila maintenant je peux utiliser les interrupts par contre j’ai besoin d’utiliser le stdio or j’ai une erreur.
J’ai vérifié pour les includes interrupt = rpi-kernel/include/linux/interrupt.h
par contre le stdio = /usr/include/stdio.h
Comment faire pour l’utilisé du faite qu’il n’est pas dans le folder include.
Par avance merci
Cyrille
Aussi j’aurai une autre petite question après avoir activé le bouton qui est sur la GPIO 23 et bien je constate que l’utilisation du cpu ne fais que monté
CPU0
3: 55632 ARMCTRL BCM2708 Timer Tick
16: 0 ARMCTRL bcm2708_fb dma
32: 802570 ARMCTRL dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1
52: 24098 ARMCTRL BCM2708 GPIO catchall handler
65: 7 ARMCTRL ARM Mailbox IRQ
66: 1 ARMCTRL VCHIQ doorbell
75: 1 ARMCTRL
77: 21270 ARMCTRL bcm2708_sdhci (dma)
83: 19 ARMCTRL uart-pl011
84: 69625 ARMCTRL mmc0
193: 24098 GPIO rpi_gpio_2
FIQ: usb_fiq
—————————————————————————————
193: 32832 GPIO rpi_gpio_2
—————————————————————————————
193: 45614 GPIO rpi_gpio_2
etc …
Est ce que cela est normal?
pour liberé la mémoire j’utiliserai free par contre je ne sais pas pour le CPU
Cyrille
je me répond moi même en enlevant le bouton le cpu reste immobile .
Ce que l’on voit ici ce sont les interruptions déclenchées depuis le boot. Leur nombre ne peut qu’aller en augmentant au cours de la vie du système.
j’ai un petit problème car je ne peux pas utiliser stdio j’en ai besoin pour utiliser system() afin d’executer un script bash.
j’ai suivi le tuto qui permet de re-compiler le kernel du raspberry https://www.blaess.fr/christophe/2014/03/06/compilation-native-de-modules-kernel-sur-raspberry-pi/
Maintenant je peux utiliser interrupt par contre pas stdio
Quelqu’un aurai une idée sur le sujet svp
Cyrille
On ne doit pas appeler de code qui s’exécute en mode utilisateur (fichier exécutable invoqué par un
system()
par exemple) ni de script shell depuis un module qui fonctionne en espace noyau. C’est pour cela qu’il n’y a pas de<stdio.h>
ou< dans les fichiers d'en-tête du kernel.
l’objectif et de copier les fichiers d’origine après le clique sur le bouton.
genre un reset configuration.
Donc le faite d’avoir ton script plus haut permet d’écouter une action à tous moment ce qui m’intéresse .
Bonjour,
J’ai pu voir que vous étiez spécialisé dans tout ce qui tourne autour de linux embarqué.
Je suis de métier et de formation en informatique industrielle (plutôt soft) et je me mets progressivement à la programmation embarqué j’ai des bonnes connaissances en C mais je bloque un peu sur les datasheet de vrai cartes de développement (par d’arduino ou des raspbbery pi car les communautés sont énormes et les explications nombreuses). Je ne comprends pas comment et quelles informations allé chercher afin de pouvoir piloter tous les périphériques de n’importe qu’elle carte (en particulier les GPIO), mon souhait serait de pouvoir être autonome sur n’importe qu’elle carte pouvant embarquer linux juste en se débrouillant avec la datasheet de la carte et sans utilisé les script dans sys/class/gpio…..
http://www.geekbuying.com/item/Firefly-RK3288-Quad-Core-Cortex-A17-Processors-Development-Board-2G-16G-Android-Ubuntu-Dual-System-2-4G-5G-WIFI-HDMI-2-0-Bluetooth-1000M-Ethernet-336460.html par exemple.
merci d’avance
Bonjour,
Pour gérer des entrées/sorties de type GPIO sous Linux, il y a principalement trois possibilités
mmap()
de/dev/mem
et en accédant directement aux ports du contrôleur de GPIO : efficace et rapide mais déconseillé car potentiellement dangereux et non portable (y compris vis-à-vis des évolutions d’une même carte comme la Raspberry Pi dont les accès ont changé entre la B et la B+).Bonjour,
J’arrive bien aprés la bagarre, mais ce tuto est vraiment excellent donc merci cpb.
Cependant la RasPi a évoluée et nous en sommes aujourd’hui à la Pi3.
Je ne retrouve nul part le répertoire /linux et ses sources …
J’utilise actuellement la bibliothèque wiringPi de Gordon mais sur un simple exemple de recopie d’état d’une entrée sur une sortie comme le votre, il me manque des fronts !!!
Y aurait-il moyen d’utiliser une autre librairie sur la Pi3 ?
Merci pour l’info.
Thierry
Article très intéressant,
Par contre quand j’envoi une commande en python au port 24 configurer en OUT, cela se passe bien puis le GPIO 24 retourne à sa valeur par defaut IN.
je suis obliger de refaire un gpio export 24 out après chaque commande
Je comprends pas pourquoi.
Merci à vous
Bjr,
merci pour votre article. De mon coté je cherche l’adresse de base du GPIO pour le RPI5. Ensuite comment écrire sur un port (ex port 17) en assembleur arm64 ou arm32 sans avoir l’erreur de segmentation à l’exé ou au debuggage (segmentation fault).
FR