systemadmin.es > Hardware > Raspberry, controlar el LED de lectura de la SD por software

Raspberry, controlar el LED de lectura de la SD por software

Una de las primeras cosas que se me ha pasado por la cabeza con el raspberry pi, ha sido intentar controlar por software alguno de los los LEDs de los que disponemos. El led marcado como ACT, que indica que se esta usando la memoria SD, se puede controlar por software. Vamos a ver cómo hacerlo tanto desde el /sys de Linux como desde un programa en C:

Mediante el fichero /sys/class/leds/led0/trigger, podemos los drivers que pueden controlar dicho LED y cual es el activo:

$ cat /sys/class/leds/led0/trigger
[none] mmc0 

En este caso ninguno, pero si lo dejásemos en mmc0 con un echo, veríamos la actividad en la memoria SD. Para nuestro caso deberemos dejarlo a ningún driver para controlarlo nosotros:

# echo none > /sys/class/leds/led0/trigger

A continuación mediante el el fichero de brillo del LED, /sys/class/leds/led0/brightness, podemos encenderlo y apagarlo con un echo:

# while true; do \
 echo 0 > /sys/class/leds/led0/brightness; \
 cat /sys/class/leds/led0/brightness; \
 sleep 1; \
 echo 1 > /sys/class/leds/led0/brightness; \
 cat /sys/class/leds/led0/brightness; \
 sleep 1; \
done

Es así de fácil, pero siempre tiene más gracia (y posibilidades) poder controlarlo mediante código escrito en C. Podemos usar la librería bcm2835 para ello:

$ wget http://www.open.com.au/mikem/bcm2835/bcm2835-1.17.tar.gz
$ tar zxvf bcm2835-1.0.tar.gz
$ cd bcm2835-1.0
$ ./configure
$ make
$ sudo make install

Si miramos el fichero .h en buscar de las definiciones referentes a Raspberry (RPI), podemos encontrar las siguientes:

# grep '^ \+RPI_' /usr/local/include/bcm2835.h
    RPI_GPIO_P1_03        =  0,  ///< Version 1, Pin P1-03
    RPI_GPIO_P1_05        =  1,  ///< Version 1, Pin P1-05
    RPI_GPIO_P1_07        =  4,  ///< Version 1, Pin P1-07
    RPI_GPIO_P1_08        = 14,  ///< Version 1, Pin P1-08, defaults to alt function 0 UART0_TXD
    RPI_GPIO_P1_10        = 15,  ///< Version 1, Pin P1-10, defaults to alt function 0 UART0_RXD
(...)
    RPI_V2_GPIO_P1_03     =  2,  ///< Version 2, Pin P1-03
    RPI_V2_GPIO_P1_05     =  3,  ///< Version 2, Pin P1-05
(...)

Buscando por internet, indican que dicho LED corresponde al GPIO16, pero no corresponde a ninguna definición, ya que los 16 que encontramos se refieren al Pin16, no al GPIO16:

# grep '^ \+RPI_' /usr/local/include/bcm2835.h  | grep 16
    RPI_GPIO_P1_16        = 23,  ///< Version 1, Pin P1-16
    RPI_V2_GPIO_P1_16     = 23,  ///< Version 2, Pin P1-16

Por lo que, en base a los ejemplos de la librería, hacemos el siguiente programa en C pasando como identificador, simplemente 16:

#include <bcm2835.h>
#include <stdio.h>

int main(int argc, char **argv)
{
        if (!bcm2835_init())
        {
                printf("init FAIL!");
                return 1;
        }

        bcm2835_gpio_fsel(16, BCM2835_GPIO_FSEL_OUTP);

        for(;;)
        {
                bcm2835_gpio_write(16, HIGH);
                sleep(1);
                bcm2835_gpio_write(16, LOW);
                sleep(1);
        }

        return 0;
}

Compilamos y ejecutamos:

# gcc led.c -l bcm2835 -l rt -o led
# ./led

Y ya tenemos el mismo resultado que el ejemplo en bash, pero con código escrito en C. Es el LED de más a la derecha:



Deja un comentario:

XHTML - Tags permitidos:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>