{"id":3129,"date":"2012-11-26T08:00:37","date_gmt":"2012-11-26T07:00:37","guid":{"rendered":"http:\/\/www.blaess.fr\/christophe\/?p=3129"},"modified":"2013-01-07T11:34:45","modified_gmt":"2013-01-07T10:34:45","slug":"les-gpio-du-raspberry-pi","status":"publish","type":"post","link":"https:\/\/www.blaess.fr\/christophe\/2012\/11\/26\/les-gpio-du-raspberry-pi\/","title":{"rendered":"Les GPIO du Raspberry Pi"},"content":{"rendered":"<p style=\"text-align: justify;\"><a href=\"http:\/\/www.blaess.fr\/christophe\/2012\/11\/26\/les-gpio-du-raspberry-pi\/\" rel=\"attachment wp-att-3179\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-3179\" title=\"GPIO &amp; Raspberry Pi\" alt=\"GPIO &amp; Raspberry Pi\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-00.png\" width=\"150\" height=\"150\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-00.png 250w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-00-150x150.png 150w\" sizes=\"auto, (max-width: 150px) 100vw, 150px\" \/><\/a>Le Raspberry Pi offre quelques possibilit\u00e9s d&rsquo;entr\u00e9es-sorties directes en utilisant les broches GPIO pr\u00e9sentes sur son connecteur P1. Elles ne sont pas tr\u00e8s nombreuses (une dizaine) mais cela peut suffire pour des petits projets interactifs n\u00e9cessitant d&rsquo;interroger des capteurs tout-ou-rien ou de valider des actionneurs.<\/p>\n<p style=\"text-align: justify;\">Nous pouvons utiliser ces GPIO de diff\u00e9rentes fa\u00e7ons, depuis l&rsquo;espace utilisateur ou depuis le noyau. Voyons-en rapidement les principaux aspects&#8230;<br \/>\n<!--more-->\n<\/p>\n<h1>Les broches GPIO<\/h1>\n<p style=\"text-align: justify;\">Sur <a title=\"Connecteur P1 du Raspberry Pi\" href=\"http:\/\/www.blaess.fr\/christophe\/2012\/11\/02\/spi-sur-raspberry-pi-1\/\" target=\"_blank\">le connecteur P1 du Raspberry Pi<\/a>, nous pouvons trouver plusieurs broches consacr\u00e9es aux entr\u00e9es-sorties GPIO. Celles-ci peuvent \u00eatre configur\u00e9es individuellement en entr\u00e9es ou en sorties num\u00e9riques. Attention, la tension appliqu\u00e9e sur une borne d&rsquo;entr\u00e9e doit rester inf\u00e9rieure \u00e0 3.3 V.<\/p>\n<p style=\"text-align: justify;\">Les GPIO directement accessibles sont les suivantes.<\/p>\n<div align=\"center\">\n<table>\n<thead>\n<tr>\n<td style=\"text-align: center; background-color: #494949; color: #ffffff;\"><strong>Broche<\/strong><\/td>\n<td style=\"text-align: center; background-color: #494949; color: #ffffff;\"><strong>GPIO<\/strong><\/td>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: center; background-color: #ebe8df;\">3<\/td>\n<td style=\"text-align: center; background-color: #ebe8df;\">0 (rev.1) ou 2 (rev.2)<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center; background-color: #ebe8df;\">5<\/td>\n<td style=\"text-align: center; background-color: #ebe8df;\">1 (rev.1) ou 3 (rev.2)<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center; background-color: #ebe8df;\">7<\/td>\n<td style=\"text-align: center; background-color: #ebe8df;\">4<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center; background-color: #ebe8df;\">11<\/td>\n<td style=\"text-align: center; background-color: #ebe8df;\">17<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center; background-color: #ebe8df;\">12<\/td>\n<td style=\"text-align: center; background-color: #ebe8df;\">18<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center; background-color: #ebe8df;\">13<\/td>\n<td style=\"text-align: left; background-color: #ebe8df;\">21 (rev.1) ou 27 (rev.2)<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center; background-color: #ebe8df;\">15<\/td>\n<td style=\"text-align: center; background-color: #ebe8df;\">22<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center; background-color: #ebe8df;\">16<\/td>\n<td style=\"text-align: center; background-color: #ebe8df;\">23<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center; background-color: #ebe8df;\">18<\/td>\n<td style=\"text-align: center; background-color: #ebe8df;\">24<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center; background-color: #ebe8df;\">22<\/td>\n<td style=\"text-align: center; background-color: #ebe8df;\">25<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\">On peut remarquer que certaines broches (3, 5 et 13) ont chang\u00e9 d&rsquo;affectations au gr\u00e9 des versions du Raspberry Pi, aussi \u00e9vitera-t-on de les employer pour garder un maximum de portabilit\u00e9 aux applications.<\/p>\n<h1>Acc\u00e8s depuis l&rsquo;espace utilisateur<\/h1>\n<p style=\"text-align: justify;\">L&rsquo;acc\u00e8s simple, depuis le shell &#8211; ou tout autre programme de l&rsquo;espace utilisateur &#8211; peut se faire tr\u00e8s ais\u00e9ment gr\u00e2ce au syst\u00e8me de fichiers <code>\/sys<\/code>.<\/p>\n<pre>\/ # <strong>cd \/sys\/class\/gpio\/<\/strong>\n\/sys\/class\/gpio # <strong>ls<\/strong>\nexport     gpiochip0  unexport<\/pre>\n<p>Demandons l&rsquo;acc\u00e8s au GPIO 24 (broche 18).<\/p>\n<pre>\/sys\/class\/gpio # <strong>echo 24 &gt; export <\/strong>\n\/sys\/class\/gpio # <strong>ls<\/strong>\nexport     gpio24     gpiochip0  unexport\n\/sys\/class\/gpio # <strong>cd gpio24\/<\/strong>\n\/sys\/devices\/virtual\/gpio\/gpio24 # <strong>ls<\/strong>\nactive_low  direction   edge        subsystem   uevent      value\n\/sys\/devices\/virtual\/gpio\/gpio24 # <strong>cat direction<\/strong>\nin<\/pre>\n<h2>Sortie de signal<\/h2>\n<p style=\"text-align: justify;\">Par d\u00e9faut, les broches GPIO sont dirig\u00e9es en entr\u00e9e. Inversons le sens du 24, puis regardons sa valeur.<\/p>\n<pre>\/sys\/devices\/virtual\/gpio\/gpio24 # <strong>echo out &gt; direction <\/strong>\n\/sys\/devices\/virtual\/gpio\/gpio24 # <strong>cat value<\/strong>\n0<\/pre>\n<p style=\"text-align: justify;\">Effectivement, le voltm\u00e8tre confirme qu&rsquo;il n&rsquo;y a pas de tension sur la broche.<\/p>\n<p><a href=\"http:\/\/www.blaess.fr\/christophe\/2012\/11\/24\/les-gpio-du-raspberry-pi\/img-01\/\" rel=\"attachment wp-att-3157\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3157\" title=\"GPIO Raspberry Pi - 1\" alt=\"GPIO Raspberry Pi - 1\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-01.png\" width=\"400\" height=\"316\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-01.png 400w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-01-300x237.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Modifions l&rsquo;\u00e9tat de la sortie<\/p>\n<pre>\/sys\/devices\/virtual\/gpio\/gpio24 # <strong>echo 1 &gt; value<\/strong><\/pre>\n<p style=\"text-align: justify;\">V\u00e9rifions la tension.<\/p>\n<p><a href=\"http:\/\/www.blaess.fr\/christophe\/2012\/11\/24\/les-gpio-du-raspberry-pi\/img-02\/\" rel=\"attachment wp-att-3158\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3158\" title=\"GPIO Raspberry Pi - 2\" alt=\"GPIO Raspberry Pi - 2\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-02.png\" width=\"400\" height=\"304\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-02.png 400w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-02-300x228.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Re-basculons la sortie \u00e0 z\u00e9ro.<\/p>\n<pre>\/sys\/devices\/virtual\/gpio\/gpio24 # <strong>echo 0 &gt; value<\/strong>\n\/sys\/devices\/virtual\/gpio\/gpio24 #<\/pre>\n<p><a href=\"http:\/\/www.blaess.fr\/christophe\/2012\/11\/24\/les-gpio-du-raspberry-pi\/img-03\/\" rel=\"attachment wp-att-3159\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3159\" title=\"GPIO Raspberry Pi - 3\" alt=\"GPIO Raspberry Pi - 3\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-03.png\" width=\"400\" height=\"338\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-03.png 400w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-03-300x253.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h2>Lecture d&rsquo;\u00e9tat<\/h2>\n<p style=\"text-align: justify;\">Demandons \u00e0 pr\u00e9sent l&rsquo;acc\u00e8s \u00e0 la broche 16 (Gpio 23)<\/p>\n<pre># <strong>cd \/sys\/class\/gpio\/<\/strong>\n\/sys\/class\/gpio # <strong>echo 23 &gt; export <\/strong>\n\/sys\/class\/gpio # <strong>ls<\/strong>\nexport     gpio23     gpio24     gpiochip0  unexport\n\/sys\/class\/gpio # <strong>cd gpio23\/<\/strong>\n\/sys\/devices\/virtual\/gpio\/gpio23 # <strong>cat direction<\/strong>\nin<\/pre>\n<p style=\"text-align: justify;\">Je relie la broche 16 \u00e0 la broche 20 (<em>GND<\/em>), puis je lis la valeur d&rsquo;entr\u00e9e.<\/p>\n<pre>\/sys\/devices\/virtual\/gpio\/gpio23 # <strong>cat value<\/strong>\n0<\/pre>\n<p style=\"text-align: justify;\">Je relie \u00e0 pr\u00e9sent la broche 16 \u00e0 la broche 17 (<em>+3.3V<\/em>)<\/p>\n<pre>\/sys\/devices\/virtual\/gpio\/gpio23 # <strong>cat value<\/strong> \n1<\/pre>\n<p style=\"text-align: justify;\">Retour \u00e0 nouveau sur la broche 20 (<em>GND<\/em>).<\/p>\n<pre>\/sys\/devices\/virtual\/gpio\/gpio23 # <strong>cat value <\/strong>\n0\n\/sys\/devices\/virtual\/gpio\/gpio23 #<\/pre>\n<h1>Acc\u00e8s depuis le kernel<\/h1>\n<h2>Lectures et \u00e9critures<\/h2>\n<p style=\"text-align: justify;\">Nous pouvons \u00e9crire un petit module pour acc\u00e9der en lecture et \u00e9criture aux m\u00eames broches. Dans le module ci-dessous un timer \u00e0 8Hz fait clignoter la sortie sur la broche 18 seulement si la broche 16 est mise \u00e0 1 (+3.3V).<\/p>\n<pre><a title=\"rpi-gpio-1.c\" href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-11-26\/rpi-gpio-1.c\" target=\"_blank\"><strong>rpi-gpio-1.c<\/strong><\/a>\n#include &lt;linux\/module.h&gt;\n#include &lt;linux\/timer.h&gt;\n#include &lt;linux\/gpio.h&gt;\n#include &lt;linux\/fs.h&gt;\n\n\/\/ Sortie sur broche 18 (GPIO 24)\n#define RPI_GPIO_OUT 24\n\n\/\/ Entree sur broche 16 (GPIO 23)\n#define RPI_GPIO_IN  23\n\nstatic struct timer_list rpi_gpio_1_timer;\n\nstatic void rpi_gpio_1_function (unsigned long unused)\n{\n  static int value = 1;\n  value = 1 - value;\n  if (<strong>gpio_get_value(RPI_GPIO_IN)<\/strong> == 0)\n    value = 0;\n  <strong>gpio_set_value(RPI_GPIO_OUT, value)<\/strong>;\n  mod_timer(&amp; rpi_gpio_1_timer, jiffies+ (HZ &gt;&gt; 3));\n}\n\nstatic int __init rpi_gpio_1_init (void)\n{\n  int err;\n\n  if ((err = <strong>gpio_request(RPI_GPIO_IN,THIS_MODULE-&gt;name)<\/strong>) != 0)\n    return err;\n  if ((err = <strong>gpio_request(RPI_GPIO_OUT,THIS_MODULE-&gt;name)<\/strong>) != 0) {\n    gpio_free(RPI_GPIO_IN);\n    return err;\n  }\n  if ((err = <strong>gpio_direction_input(RPI_GPIO_IN)<\/strong>) != 0) {\n    gpio_free(RPI_GPIO_OUT);\n    gpio_free(RPI_GPIO_IN);\n    return err;\n  }\n  if ((err = <strong>gpio_direction_output(RPI_GPIO_OUT,1)<\/strong>) != 0) {\n    gpio_free(RPI_GPIO_OUT);\n    gpio_free(RPI_GPIO_IN);\n    return err;\n  }\n\n  init_timer(&amp; rpi_gpio_1_timer);\n  rpi_gpio_1_timer.function = rpi_gpio_1_function;\n  rpi_gpio_1_timer.data = 0; \/\/ non utilise\n  rpi_gpio_1_timer.expires = jiffies + (HZ &gt;&gt; 3);\n  <strong>add_timer(&amp; rpi_gpio_1_timer)<\/strong>;\n\n  return 0; \n}\n\nstatic void __exit rpi_gpio_1_exit (void)\n{\n  <strong>del_timer(&amp; rpi_gpio_1_timer)<\/strong>;\n  <strong>gpio_free(RPI_GPIO_OUT)<\/strong>;\n  <strong>gpio_free(RPI_GPIO_IN)<\/strong>;\n}\n\nmodule_init(rpi_gpio_1_init);\nmodule_exit(rpi_gpio_1_exit);\nMODULE_LICENSE(\"GPL\");<\/pre>\n<p style=\"text-align: justify;\">La compilation se fait avec le fichier <code>Makefile<\/code> suivant. Les lignes <code>KERNEL_DIR<\/code> et <code>CROSS_COMPILE<\/code> indiquent respectivement l&#8217;emplacement du r\u00e9pertoire de compilation du noyau pour le Raspberry Pi et le pr\u00e9fixe pour la toolchain sur mon syst\u00e8me. Il faut les adapter \u00e0 votre environnement.<\/p>\n<p>&nbsp;<\/p>\n<pre><a title=\"Makefile\" href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-11-26\/Makefile\" target=\"_blank\"><strong>Makefile<\/strong><\/a>\nifneq (${KERNELRELEASE},)\n\n  obj-m += rpi-gpio-1.o\n\nelse\n  ARCH          ?= arm\n  <strong>KERNEL_DIR ?= ~\/linux-3.2.27<\/strong>\n  <strong>CROSS_COMPILE ?= \/usr\/local\/cross\/rpi\/bin\/arm-linux-<\/strong>\n  MODULE_DIR    := $(shell pwd)\n  CFLAGS        := -Wall\n\nall: modules\n\nmodules:\n  ${MAKE} -C ${KERNEL_DIR} ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} SUBDIRS=${MODULE_DIR} modules\n\nclean:\n  rm -f  *.o  .*.o  .*.o.* *.ko  .*.ko  *.mod.* .*.mod.* .*.cmd\n  rm -f Module.symvers Module.markers modules.order\n  rm -rf .tmp_versions\nendif<\/pre>\n<p style=\"text-align: justify;\">Apr\u00e8s compilation et transfert sur le Raspberry Pi, nous chargeons le module et observons \u00e0 l&rsquo;aide d&rsquo;un analyseur logique les deux broches 16 (canal 2) et 18 (canal 1), tandis qu&rsquo;un signal de +3.3V est envoy\u00e9 sur la broche 16.<\/p>\n<p><a href=\"http:\/\/www.blaess.fr\/christophe\/2012\/11\/24\/les-gpio-du-raspberry-pi\/img-04\/\" rel=\"attachment wp-att-3165\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3165\" title=\"Raspberry Pi &amp; GPIO - 4\" alt=\"Raspberry Pi &amp; GPIO - 4\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-04.png\" width=\"400\" height=\"303\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-04.png 400w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-04-300x227.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Durant la p\u00e9riode (mise en \u00e9vidence par un trait rouge) o\u00f9 la broche 16 se voit appliquer une tension de +3.3V, nous voyons bien une oscillation de la sortie sur la broche 18.<\/p>\n<h2>Interruptions<\/h2>\n<p style=\"text-align: justify;\">\u00c0 pr\u00e9sent nous allons traiter les interruptions d\u00e9clench\u00e9es par une entr\u00e9e GPIO. Le module ci-dessous installe un handler d&rsquo;interruption pour le GPIO 23 (broche 16). \u00c0 chaque d\u00e9clenchement de l&rsquo;interruption, notre handler basculera l&rsquo;\u00e9tat de la broche de sortie 18 (GPIO 24).<\/p>\n<pre><a title=\"rpi-gpio-2.c\" href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-11-26\/rpi-gpio-2.c\" target=\"_blank\"><strong>rpi-gpio-2.c<\/strong><\/a>\n#include &lt;linux\/interrupt.h&gt;\n#include &lt;linux\/module.h&gt;\n#include &lt;linux\/gpio.h&gt;\n\n\/\/ Sortie sur broche 18 (GPIO 24)\n#define RPI_GPIO_OUT 24\n\n\/\/ Entree sur broche 16 (GPIO 23)\n#define RPI_GPIO_IN  23\n\nstatic irqreturn_t rpi_gpio_2_handler(int irq, void * ident)\n{\n  static int value = 1;\n\n  <strong>gpio_set_value(RPI_GPIO_OUT, value);<\/strong>\n  value = 1 - value;\n\n  return IRQ_HANDLED;\n}\n\nstatic int __init rpi_gpio_2_init (void)\n{\n  int err;\n\n  if ((err = gpio_request(RPI_GPIO_OUT, THIS_MODULE-&gt;name)) != 0)\n    return err;\n\n  if ((err = gpio_request(RPI_GPIO_IN, THIS_MODULE-&gt;name)) != 0) {\n    gpio_free(RPI_GPIO_OUT);\n    return err;\n  }\n\n  if ((err = gpio_direction_output(RPI_GPIO_OUT,1)) != 0) {\n    gpio_free(RPI_GPIO_OUT);\n    gpio_free(RPI_GPIO_IN);\n    return err;\n  }\n\n  if ((err = gpio_direction_input(RPI_GPIO_IN)) != 0) {\n    gpio_free(RPI_GPIO_OUT);\n    gpio_free(RPI_GPIO_IN);\n    return err;\n  }\n\n  if ((err = <strong>request_irq(gpio_to_irq(RPI_GPIO_IN), rpi_gpio_2_handler, IRQF_SHARED | IRQF_TRIGGER_RISING, THIS_MODULE-&gt;name, THIS_MODULE-&gt;name)<\/strong>) != 0) {\n    gpio_free(RPI_GPIO_OUT);\n    gpio_free(RPI_GPIO_IN);\n    return err;\n  }\n\n  return 0; \n}\n\nstatic void __exit rpi_gpio_2_exit (void)\n{\n  <strong>free_irq(gpio_to_irq(RPI_GPIO_IN), THIS_MODULE-&gt;name);<\/strong>\n  gpio_free(RPI_GPIO_OUT);\n  gpio_free(RPI_GPIO_IN);\n}\n\nmodule_init(rpi_gpio_2_init);\nmodule_exit(rpi_gpio_2_exit);\nMODULE_LICENSE(\"GPL\");<\/pre>\n<p style=\"text-align: justify;\">Le second module ayant \u00e9t\u00e9 ajout\u00e9 dans le <code>Makefile<\/code>, nous pouvons le compiler de la m\u00eame fa\u00e7on que le pr\u00e9c\u00e9dent. Transf\u00e9rons-le sur le Raspberry Pi, puis chargeons-le dans le kernel.<\/p>\n<pre>\/ # <strong>cat \/proc\/interrupts<\/strong>\n           CPU0       \n  3:        362   ARMCTRL  BCM2708 Timer Tick\n 32:        419   ARMCTRL  dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1\n 52:          0   ARMCTRL  BCM2708 GPIO catchall handler\n 65:         20   ARMCTRL  ARM Mailbox IRQ\n 66:          1   ARMCTRL  VCHIQ doorbell\n 77:        123   ARMCTRL  bcm2708_sdhci (dma)\n 83:         18   ARMCTRL  uart-pl011\n 84:        317   ARMCTRL  mmc0\nFIQ:              usb_fiq\nErr:          0\n\/ # <strong>insmod rpi-gpio-2.ko<\/strong>\n\/ # <strong>cat \/proc\/interrupts<\/strong>\n           CPU0       \n  3:        434   ARMCTRL  BCM2708 Timer Tick\n 32:        463   ARMCTRL  dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1\n 52:          0   ARMCTRL  BCM2708 GPIO catchall handler\n 65:         28   ARMCTRL  ARM Mailbox IRQ\n 66:          1   ARMCTRL  VCHIQ doorbell\n 77:        124   ARMCTRL  bcm2708_sdhci (dma)\n 83:        119   ARMCTRL  uart-pl011\n 84:        326   ARMCTRL  mmc0\n193:          0      GPIO  rpi_gpio_2\nFIQ:              usb_fiq\nErr:          0\n\/ #<\/pre>\n<p style=\"text-align: justify;\">Nous voyons que la ligne d&rsquo;interruption (num\u00e9ro 193) est apparue dans <code>\/proc\/interrupts<\/code>. Pour l&rsquo;instant aucune interruption ne s&rsquo;est d\u00e9clench\u00e9e. Connectons sur cette entr\u00e9e un G\u00e9n\u00e9rateur-Basse-Fr\u00e9quence, qui lui envoie un signal carr\u00e9 [0, +3.3V] de 2.5kHz environ.<\/p>\n<p>Aussit\u00f4t un signal carr\u00e9 appara\u00eet sur la broche de sortie, avec une fr\u00e9quence moiti\u00e9 du pr\u00e9c\u00e9dent. Nous pouvons le v\u00e9rifier avec un oscilloscope.<br \/>\n<a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-05.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3169\" title=\"Raspberry Pi &amp; GPIO 5\" alt=\"Raspberry Pi &amp; GPIO 5\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-05.png\" width=\"400\" height=\"300\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-05.png 400w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-05-300x225.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Nous pouvons \u00e9galement v\u00e9rifier dans <code>\/proc\/interrupts<\/code> que le nombre d&rsquo;interruptions 193 trait\u00e9es progresse r\u00e9guli\u00e8rement.<\/p>\n<pre>\/ # <strong>cat \/proc\/interrupts <\/strong>\n           CPU0       \n  3:        646   ARMCTRL  BCM2708 Timer Tick\n 32:        617   ARMCTRL  dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1\n 52:      29791   ARMCTRL  BCM2708 GPIO catchall handler\n 65:         60   ARMCTRL  ARM Mailbox IRQ\n 66:          1   ARMCTRL  VCHIQ doorbell\n 75:          1   ARMCTRL\n 77:        124   ARMCTRL  bcm2708_sdhci (dma)\n 83:        187   ARMCTRL  uart-pl011\n 84:        342   ARMCTRL  mmc0\n193:      29792      GPIO  rpi_gpio_2\nFIQ:              usb_fiq\nErr:          0\n\/ #<\/pre>\n<p style=\"text-align: justify;\">En zoomant sur le point de d\u00e9clenchement, nous mesurons la dur\u00e9e de prise en compte de l&rsquo;interruption.<\/p>\n<p><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-06.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3170\" title=\"Raspberry Pi &amp; GPIO 6\" alt=\"Raspberry Pi &amp; GPIO 6\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-06.png\" width=\"400\" height=\"297\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-06.png 400w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/11\/img-06-300x222.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\">La dur\u00e9e entre la mont\u00e9e du signal d&rsquo;entr\u00e9e et la r\u00e9ponse du handler est d&rsquo;environ 7 micro-secondes, ce qui est tout \u00e0 fait correct pour cette gamme de microprocesseur.<\/p>\n<h1>Conclusion<\/h1>\n<p style=\"text-align: justify;\">L&rsquo;acc\u00e8s aux GPIO du port d&rsquo;extension du Raspberry Pi est tr\u00e8s simple, tant depuis l&rsquo;espace utilisateur que depuis le noyau. Il existe d&rsquo;autres broches permettant des entr\u00e9es-sorties GPIO, mais elles ont une autre fonctionnalit\u00e9 par d\u00e9faut (RS-232, SPI, etc.).<\/p>\n<p style=\"text-align: justify;\">Il serait \u00e9galement int\u00e9ressant d&rsquo;acc\u00e9der aux GPIO depuis un driver RTDM pour Xenomai. Ceci fera l&rsquo;objet d&rsquo;un prochain article.<\/p>\n<h2>Pour en savoir plus<\/h2>\n<p>Si vous souhaitez approfondir l&rsquo;\u00e9criture de drivers pour Linux &#8211; notamment pour les GPIO du Raspberry Pi -, je vous propose de vous retrouver en session de formation \u00ab\u00a0<a title=\"Formation &quot;\u00c9criture de drivers Linux&quot;\" href=\"http:\/\/www.logilin.fr\/formations\/formation-ecriture-de-drivers-et-programmation-noyau-linux\/\" target=\"_blank\">\u00c9criture de drivers et programmation noyau Linux<\/a>\u00a0\u00bb chez Logilin.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>","protected":false},"excerpt":{"rendered":"<p>Le Raspberry Pi offre quelques possibilit&eacute;s d&rsquo;entr&eacute;es-sorties directes en utilisant les broches GPIO pr&eacute;sentes sur son connecteur P1. Elles ne sont pas tr&egrave;s nombreuses (une dizaine) mais cela peut suffire pour des petits projets interactifs n&eacute;cessitant d&rsquo;interroger des capteurs tout-ou-rien ou de valider des actionneurs. Nous pouvons utiliser ces GPIO de diff&eacute;rentes fa&ccedil;ons, depuis l&rsquo;espace [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,10,11],"tags":[],"class_list":["post-3129","post","type-post","status-publish","format-standard","hentry","category-linux-2","category-microprocesseur","category-raspberry-pi"],"_links":{"self":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/3129","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/comments?post=3129"}],"version-history":[{"count":55,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/3129\/revisions"}],"predecessor-version":[{"id":3314,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/3129\/revisions\/3314"}],"wp:attachment":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/media?parent=3129"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/categories?post=3129"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/tags?post=3129"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}