Programação GPIO

De Caninos Loucos
Ir para: navegação, pesquisa

Esta página explica como programar as saídas GPIO (General Purpose Input/Output) da Labrador, que são basicamente pinos nos quais você pode enviar e receber dados. Para facilitar a programação, a placa Labrador segue a interface padrão para userspace para Linux embarcado. O tutorial desta página funciona tanto com a Labrador 32 quanto 64-bits.

Além disso, a placa Labrador 32-bits é compatível com o formato da Raspberry Pi, e possui a biblioteca wiringK9, baseada na wiringPi, também da Raspberry Pi. Mais detalhes desta biblioteca pode ser encontrado nessa página Wiring K9.

Configuração dos pinos

A configuração de pinos para o cabeçalho de GPIO é a seguinte:

GPIO Labrador 32-bits

caption Mapeamento do header de 40 pinos.

GPIO Labrador 64 bits

Default Function Header Pin Default Function
VCC 1 2 5V
GPIOE3 3 4 5V
GPIOE2 5 6 GND
GPIOB18 7 8 UART0_TX
GND 9 10 UART0_RX
GPIOC0 11 12 GPIOB8
GPIOC1 13 14 GND
GPIOC4 15 16 GPIOD30
VCC 17 18 GPIOC6
TWI3_SDA 19 20 GND
GPIOC24 21 22 GPIOC5
TWI3_SCK 23 24 GPIOC23
GND 25 26 GPIOB19
GPIOB16 27 28 GPIOB14
GPIOB15 29 30 GND
GPIOB10 31 32 GPIOB13
GPIOB0 33 34 GND
GPIOB1 35 36 GPIOA28
GPIOB2 37 38 RESERVED
GND 39 40 RESERVED

Interface GPIO do Linux

O kernel Linux implementa em si uma solução de acesso à GPIO atraves de um modelo de criação e consumo de GPIO. Os drivers de criação são drivers como o controlador de GPIO que será detalhado nesta página, os consumidores são os drivers como sensores que utilizam estas linhas GPIO. Dentro do kernel Linux existe uma estrutura de alocação e registradores dos pinos GPIO chamado gpiolib, esta estrutura cobre os drivers em nível de kernel e userspace. As bibliotecas de espaço de usuário são, até a versão 4.7 do Kernel Linux a sysfs e a partir da versao 4.8 a chardev. Embora a placa Labrador esteja atualmente no Kernel 4.19, ambas ainda são compatíveis e cobriremos o uso das duas interfaces de espaço de usuário.

Interface sysfs

Na interface sysfs o usuário tem acesso às GPIO através de arquivos exportados em /sys/class/gpio. Para isso é necessário exportar um arquivo para cada GPIO, configurar a porta e escrever na mesma.

Identificando o número da GPIO

No método sysfs utiliza-se o número absoluto das GPIO para exportá-las individualmente. A Labrador possui 5 grupos de GPIO (A, B, C, D e E). Cada um desses possui 32 pinos agrupados, portanto para indicar o valor absoluto do pino temos um offset dado pelo grupo mais o valor do pino, este offset seguem a lógica a seguir:

  • A: 0
  • B: 32
  • C: 64
  • D: 96
  • E: 128

Portanto se quisermos acessar o pino 3 do header GPIO, no caso seria GPIOE3, portanto devemos exportar o pino GPIO 128+3=131. Isto seria feito com a seguinte linha de terminal:

$ echo 131 > /sys/class/gpio/export

Configurando a direção do pino

Após exportado o pino devemos configurar a direção do mesmo entre input (in) ou output (out). Para isto basta escrever no GPIO exportado o valor requerido. No nosso exemplo colocaremos como output:

$ echo out > /sys/class/gpio/gpio131/direction

Escrevendo ou lendo no pino

Para escrever no pino configurado como output basta enviar o valor para o parâmetro value do pino. No nosso exemplo colocaremos o valor 1 no pino:

$ echo 1 > /sys/class/gpio/gpio131/value

Caso o pino seja definido como input basta ler este mesmo arquivo.

$ cat /sys/class/gpio/gpio131/value

Lendo um parâmetro

O comando cat pode ser usado nestes arquivos de parâmetros para ler o que já foi configurado dos pinos ficamos então com os seguinte exemplo completos para configuração do pino GPIOE3 como output em alta e GPIOE2 como input:

$ echo 131 > /sys/class/gpio/export #Exportando GPIOE3
$ echo out > /sys/class/gpio/gpio131/direction #Definindo como output
$ echo 1 > /sys/class/gpio/gpio131/value #Escrevendo o valor 1
$ cat /sys/class/gpio/gpio131/direction #Lendo a direção do pino
out
$ cat /sys/class/gpio/gpio131/value #Lendo o valor do pino
1
$ echo 130 > /sys/class/gpio/export #Exportando GPIOE2
$ echo in > /sys/class/gpio/gpio130/direction #Definindo como input
$ cat /sys/class/gpio/gpio130/value #Lendo o valor do pino
0
$ cat /sys/class/gpio/gpio130/direction #Lendo a direção do pino
in

Interface chardev

A interface chardev é a interface padrão do kernel Linux a partir do kernel 4.8 e compatível com a Labrador 64-bits, apesar de esta solução não permitir o uso de comandos padrão do terminal linux para controle da gpio como echo e cat usados anteriormente, esta API utiliza a biblioteca libgpiod que provê uma série de ferramentas para uso em terminal e também para uso em C, com bibliotecas de vinculações disponíveis em C++ e Python. A solução chardev é mais simples, elegante e robusta que a sysfs.

Para instalar a biblioteca libgpiod no Debian Buster (10), execute:

sudo apt install gpiod libgpiod-dev libgpiod-doc

Identificando o número da GPIO

Para o chardev os diferentes controladores de GPIO possuem pastas diferentes, chamados gpiochip. No caso temos A=0, B=1, C=2, D=3, E=4. Portanto, os pinos agora serão definidos pelo controlador e pela linha dentro do mesmo.

libgpiod no terminal

gpiodetect

Os controladores podem ser identificados com o comando gpiodetect disponível pelo libgpiod

$ gpiodetect
gpiochip0 [209c000.gpio] (32 lines)
gpiochip1 [20a0000.gpio] (32 lines)
gpiochip2 [20a4000.gpio] (32 lines)
gpiochip3 [20a8000.gpio] (32 lines)
gpiochip4 [20ac000.gpio] (32 lines)

gpioinfo

O comando gpioinfo fornece as informações dos pinos de cada controlador, por exemplo para exemplos dos pinos do controlador E:

$ gpioinfo 0
        line   0:      unnamed       unused   input  active-high
        line   1:      unnamed       unused   input  active-high
        line   2:      unnamed       unused   input  active-high

No caso, nenhum destes pinos está em utilização.

gpioget

Os pinos estão configurados como entrada por padrão, para acessar os valores de entrada dos pinos basta utilizar o comando gpioget, no exemplo o pino GPIOE3 (controlador 4, pino 3)

$ gpioget 4 3
0

gpioset

O comando gpioset muda a direção para output e define o valor do mesmo, no exemplo definiremos o GPIOE3 para alto:

$ gpioset 4 3=1
1

gpiomon

Este comando é utilizado para interrupções e eventos, ele monitorará o pino para mudanças e retornará as mudanças encontradas.

$gpiomon 4 3
event:  RISING EDGE offset: 3 timestamp: [    322.073816438]
event: FALLING EDGE offset: 3 timestamp: [    323.467289198]
event:  RISING EDGE offset: 3 timestamp: [    324.245127683]

Utilizando chardev em C

A API chardev facilita o uso em programas em C, alguns exemplos podem ser encontrados com facilidade, como estes.