?>/script>'; } ?> Asociar IRQ a GPIO desde un modulo en C Widgets Magazine

Autor Tema: Asociar IRQ a GPIO desde un modulo en C  (Leído 2331 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Pablico

  • Visitante
Asociar IRQ a GPIO desde un modulo en C
« en: 05-03-2017, 23:43 (Domingo) »
Hola

¿Puede asociarse una interrupcion a cualuier linea GPIO?

Estoy trasteando con un Huawey HG556a RevC , y despues de soldar los cables para los GPIO25 y GPIO29  (no usados) queria configurar uno de ellos como entrada capaz de detectar un pulso, pero no hay manera.
No me refiero a usar scripts para ello, sino a usar un módulo en C que lo haga.

De hecho, el módulo es el "famoso" de Derek Molloy para la BeagleBoneBlack:

http://derekmolloy.ie/beaglebone/beaglebone-gpio-programming-on-arm-embedded-linux/

pero compilado para mi OpenWrt (CHAOS CALMER 15.05, r46767). Este modulo enciende un led cuando uno pulsa un botón, asi que usa un GPIO de entrada y otro de salida.

Al cargar el modulo en el router, mediante los comandos sobre el /sys/class/gpio/...etc puedo ver que efectivamente los GPIO se comportan como deben, con el GPIO497 (base=472 + gpio=25) de salida encendiendo el LED, y con el GPIO501 (472+29) de entrada detectando cuando tengo el cable conectado a masa o no (con una R=270Ohm)

El problema viene en que esta parte de codigo deberia asociar una interrupcion al GPIO de entrada,para evitar hacer polling detectando cuando cambia su valor:

   irqNumber = 11; // gpio_to_irq(gpioButton); --> No funciona
   printk(KERN_INFO "EBB Button: The button %d is mapped to IRQ: %d\n", gpioButton,irqNumber);

   if(!isRising){                         
      IRQflags = IRQF_TRIGGER_FALLING;     
   }
   
   result = request_irq(irqNumber,           
                        (irq_handler_t) ebbgpio_irq_handler,  --> manejador de la interrupcion
                        IRQflags,             
                        "ebb_button_handler", 
                        NULL);   
   

aunque crea correctamente la interrupcion (se ve en /proc/interrupts) , no hace que se llame al manejador en ningun momento. Vamos, que es como si no existiera.
Por otra parte, la llamada a gpio_to_irq(gpioButton)  no funciona, y devuelve siempre -1, asi que viendo que la IRQ=11 no estaba usada, le he puesto esa a cascoporro,y el modulo se carga pero cuando pongo el cablecito del gpioButton a masa, nada, la interrupcion no se genera, aunque el cat /sys/class/gpio/gpio501/value si devuelve 0o 1 como debe.

Esto me lleva a preguntarme ¿Puede ser que para esta CPU bcm63XX resulte que no haya posibilidad de hacer que una linea GPIO produzca una interrupcion mas que para solo unos pocos GPIO ? ¿O siempre se puede asociar una interrupcion no usada a cualquier GPIO no usado?

Perdón por el tocho, pero sois mi unica esperanza...;-)
 
   

Desconectado Tki2000

  • Moderador
  • *
  • Mensajes: 2247
Re: Asociar IRQ a GPIO desde un modulo en C
« Respuesta #1 en: 06-03-2017, 09:48 (Lunes) »
Hola

¿Puede asociarse una interrupcion a cualuier linea GPIO?

Estoy trasteando con un Huawey HG556a RevC , y despues de soldar los cables para los GPIO25 y GPIO29  (no usados) queria configurar uno de ellos como entrada capaz de detectar un pulso, pero no hay manera.
No me refiero a usar scripts para ello, sino a usar un módulo en C que lo haga.

De hecho, el módulo es el "famoso" de Derek Molloy para la BeagleBoneBlack:

http://derekmolloy.ie/beaglebone/beaglebone-gpio-programming-on-arm-embedded-linux/

pero compilado para mi OpenWrt (CHAOS CALMER 15.05, r46767). Este modulo enciende un led cuando uno pulsa un botón, asi que usa un GPIO de entrada y otro de salida.

Al cargar el modulo en el router, mediante los comandos sobre el /sys/class/gpio/...etc puedo ver que efectivamente los GPIO se comportan como deben, con el GPIO497 (base=472 + gpio=25) de salida encendiendo el LED, y con el GPIO501 (472+29) de entrada detectando cuando tengo el cable conectado a masa o no (con una R=270Ohm)

El problema viene en que esta parte de codigo deberia asociar una interrupcion al GPIO de entrada,para evitar hacer polling detectando cuando cambia su valor:

   irqNumber = 11; // gpio_to_irq(gpioButton); --> No funciona
   printk(KERN_INFO "EBB Button: The button %d is mapped to IRQ: %d\n", gpioButton,irqNumber);

   if(!isRising){                         
      IRQflags = IRQF_TRIGGER_FALLING;     
   }
   
   result = request_irq(irqNumber,           
                        (irq_handler_t) ebbgpio_irq_handler,  --> manejador de la interrupcion
                        IRQflags,             
                        "ebb_button_handler", 
                        NULL);   
   

aunque crea correctamente la interrupcion (se ve en /proc/interrupts) , no hace que se llame al manejador en ningun momento. Vamos, que es como si no existiera.
Por otra parte, la llamada a gpio_to_irq(gpioButton)  no funciona, y devuelve siempre -1, asi que viendo que la IRQ=11 no estaba usada, le he puesto esa a cascoporro,y el modulo se carga pero cuando pongo el cablecito del gpioButton a masa, nada, la interrupcion no se genera, aunque el cat /sys/class/gpio/gpio501/value si devuelve 0o 1 como debe.

Esto me lleva a preguntarme ¿Puede ser que para esta CPU bcm63XX resulte que no haya posibilidad de hacer que una linea GPIO produzca una interrupcion mas que para solo unos pocos GPIO ? ¿O siempre se puede asociar una interrupcion no usada a cualquier GPIO no usado?

Perdón por el tocho, pero sois mi unica esperanza...;-)
 
   

No todos los pines son usables para producir interrupciones de sistema, y esto es por diseño. Los pines que sí se puedan asociar a interrupciones, estarán descritos en la correspondiente Datasheet del procesador. Esto es así, con este procesador y con cualquier otro. La mayoría, debe habilitar una máscara de interrupciones, y asociarlo con el pin en concreto, para que actúe. Si buscas el datasheet, seguro que encuentras los GPIO que se pueden asociar con interrupciones, y la forma de usarlo. En cuanto a si ese pin concreto, se puede usar o no para hacer una interrupción de sistema, no te lo puedo decir, sin mirar el datasheet. Tampoco te puedo asegurar, que aunque el pin se pueda usar para provocar interrupciones, openwrt sea capaz de gestionarlo correctamente.

danitool

  • Visitante
Re: Asociar IRQ a GPIO desde un modulo en C
« Respuesta #2 en: 06-03-2017, 10:56 (Lunes) »
Este router solo tiene 6 GPIOs con IRQs:

GPIO32 GPIO33 GPIO34 GPIO35 GPIO36 GPIO37

Y la función gpio_to_irq solo hace un par de semanas que ha sido implementada en LEDE. Así que podrías usarlo con un LEDE snapshot. Pero solo con esos GPIOs




El resto de SoCs brcm63xx también tienen una situación parecida solo con unos pocos GPIOs con IRQs disponibles

Ver tabla: https://wiki.openwrt.org/doc/hardware/soc/soc.broadcom.bcm63xx#external_irqs

En otros SoCs como los ar71xx todos los GPIOs tienen IRQs, pero en estos todavía no se ha incorporado el controlador de interrupciones de los mismos en el kernel, estará disponible a partir del kernel 4.9.

Como comenta Tki2000 la situación es diferente en cada SoC.

Pablico

  • Visitante
Re: Asociar IRQ a GPIO desde un modulo en C
« Respuesta #3 en: 06-03-2017, 21:18 (Lunes) »
Muchas gracias por vuestras respuestas.

Vaya,es lo que me temía.
Intentaré reusar uno de esos GPIO que pueden producir interrupciones.En concreto, el GPIO36 que parece se usa para temas de diagnóstico parece adecuado.Voy a buscarlo en el hilo que tenéis acerca de usar los gpio como en la BB-pi o la BB-Black, a ver si aparece y esta accesible para soldarle algo.
Y ya veremos si openwrt hace algo con el, como decís. Si no, miraré en LEDE si buceando un poco en el código no veo nada.

Pablico

  • Visitante
Re: Asociar IRQ a GPIO desde un modulo en C
« Respuesta #4 en: 06-03-2017, 21:33 (Lunes) »
Diez minutos me ha costado encontrarlo

https://foro.seguridadwireless.net/openwrt/openwrt-en-huaweig-hg556a/msg340831/#msg340831

Sois unos figuras...ya me veía pinchando pines hasta las tantas...
Enhorabuena por el foro

danitool

  • Visitante
Re: Asociar IRQ a GPIO desde un modulo en C
« Respuesta #5 en: 06-03-2017, 21:54 (Lunes) »
De todas formas, en la wiki están los GPIOs localizados en placa para todas las versiones del HG556a

https://wiki.openwrt.org/toh/huawei/hg556a#gpios

En las versiones A y B solo se ha podido localizar un GPIO con interrupciones, el GPIO32

https://wiki.openwrt.org/_media/media/huawei/hg556/hg556a_ab-gpios-extra.jpg