sexta-feira, 2 de maio de 2014

Usando GPIO a partir do userspace

Usando GPIO em sysfs


O que será apresentado aqui se aplica a praticamente qualquer placa com Linux Embarcado do mercado. Entretanto, é direcionado especificamente para placas com processadores da Allwinner. Neste artigo nós usaremos a Interface GPIO Sysfs para espaço de usuário.

A fim de que você possa usar os pinos de GPIO da sua placa, você precisa determinar se existe um driver de GPIO para o processador da sua placa. Além disso, você precisa saber se este driver segue o padrão do framework de GPIO. Cheque sob a pasta /drivers/gpio/xxx.c se há um driver de GPIO. Caso ele esteja presente, provavelmente ele segue o padrão do framework.

Para o caso de processadores Allwinner, havia um driver chamado sun4i-gpio, mas foi removido em favor de um mais novo, gpio-sunxi. Este novo driver usa o framework de GPIO. Isto significa que você pode manipular os pinos de E/S através de entradas no diretório /sys. Em adição, há muitos outros benefícios de usar o framework, porque há uma organização melhor no Sysfs. 

Desde que tenha encontrado o driver de GPIO para o processador da placa, como podemos acessar os pinos de E/S? Pode-se acessar os pinos por meio da linha de comando ou por software. A segunda opção é obviamente mais interessante para quem faz projetos. Neste artigo serão apresentadas ambas.




Definindo o número do pino


Primeiro você precisa determinar o número correspondente ao pino que você deseja usar. O número que o kernel "enxerga". No Linux há um padrão para definir este número. Por exemplo, se o CPU da placa tem um GPIO com duas portas, cada porta contendo 32 pinos, então o GPIO1.5 será 5, GPIO1.32 será 32 e GPIO2.1 será 33. Faça os cálculos de acordo com o número de pinos e portas do GPIO do CPU.

Você pode também adquirir informações sobre os pinos pelo controlador de GPIO, referenciado no kernel como gpiochipN. Controladores de GPIO têm caminhos como /sys/class/gpio/gpiochip42 (para um controlador implementado GPIOs iniciando em #42) e tem os seguintes atributos que podem apenas serem lidos, sob /sys/class/gpio/gpiochipN: base, label e ngpio.

Veja a documentação do fabricante ou o esquemático da placa para saber o número correto. Em Allwinner, o número correto está no arquivo script.fex. Por exemplo, se nós quisermos usar o pino PG9 na placa A13-OLinuXino:

[gpio_para]
gpio_used = 1
gpio_num = 6
gpio_pin_1 = port:PB03<1><0>
gpio_pin_2 = port:PB04<1><0>
gpio_pin_3 = port:PB05<1><0>
gpio_pin_4 = port:PB06<1><0>
gpio_pin_5 = port:PB07<1><1>
gpio_pin_6 = port:PG09<1><1>

você passará o número 6 como parâmetro. Este serve tanto para linha de comando como para software. Vejamos.


Exemplo de uso da GPIO via linha de comando


O uso via linha de comando é apenas útil para teste. Talvez com um script você possa fazer algo mais dinâmico. Para tarefas mais complexas, o método por software é o preferido.

GPIO=6
cd /sys/class/gpio
echo $GPIO > export
Se o comando export funcionar, você deveria ver uma nova pasta com nome gpioN. Entre nela.
cd gpio$GPIO
Configure a direção do pino usando as strings "in" ou "out". A primeira é para configurar como entrada e a segunda, para configurar como saída. Exemplo de leitura:
echo "in" > direction
cat value
Exemplo de escrita:
echo "out" > direction
echo 1 > value

Exemplo de uso da GPIO via software


No caso do software é interessante criar uma biblioteca com funções tais como export(), direction(), read(), write(), etc. Eu fiz uma biblioteca baseado no código de RidgeRun. Eu apenas rearranjei o código!
https://www.dropbox.com/sh/gaqxgasjuixmnr3/7rHxvPxdoC
Nós podemos setar um pino para nível alto e nível baixo como segue:
gpio = atoi(argv[1]); // pega pino como parâmetro
gpio_export(gpio);
gpio_set_dir(gpio, 1);
gpio_set_value(gpio, 1); // seta para nível alto
sleep(1);
gpio_set_value(gpio, 0); // seta para nível baixo

Por favor, mantenha a licença e os créditos do autor original! O código mostrado acima apenas funcionará se você aplicar este patch ao kernel: gpio-sunxi.patch, criado por Emilio Lopes.

Veja este vídeo no Youtube: https://www.youtube.com/watch?v=iN3mEWqaf1s

Referências


http://linuxembeded.blogspot.com.br/2014/04/using-gpios-from-userspace-under-linux.html
https://github.com/torvalds/linux/blob/master/Documentation/gpio/sysfs.txt
https://developer.ridgerun.com/wiki/index.php/How_to_use_GPIO_signals
http://sergioprado.org/user-space-device-drivers-no-linux-parte-2/

Nenhum comentário:

Postar um comentário