Programação GPIO: mudanças entre as edições
(Criou página com 'Esta página explica como programar as saídas GPIO (General Purpose Input/Output) da Labrador, que são basicamente fios nos quais você pode enviar e receber dados. Para fac...') |
|||
(15 revisões intermediárias por um outro usuário não estão sendo mostradas) | |||
Linha 1: | Linha 1: | ||
Esta página explica como programar as saídas GPIO (General Purpose Input/Output) da Labrador, que são basicamente | 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 <code>wiringK9</code>, baseada na wiringPi, também da Raspberry Pi. Mais detalhes desta biblioteca pode ser encontrado nessa página [[Wiring K9]]. | |||
== Configuração dos pinos == | == Configuração dos pinos == | ||
A configuração de pinos para o cabeçalho | A configuração de pinos para o cabeçalho de GPIO é a seguinte: | ||
=== GPIO Labrador 32-bits === | |||
[[File:40pinh.png|image|800px|caption Mapeamento do header de 40 pinos.]] | |||
=== GPIO Labrador 64 bits=== | |||
{| class="wikitable" style="background-color:#ffffff;" | |||
|- style="background-color:#c0c0c0;" | |||
! Default Function | |||
! colspan="2" | Header Pin | |||
! Default Function | |||
|- | |- | ||
| | | style="background-color:#efefef;" | VCC | ||
| | | 1 | ||
| | | 2 | ||
| | | style="background-color:#efefef;" | 5V | ||
|- | |- | ||
| | | GPIOE3 | ||
| | | 3 | ||
| | | 4 | ||
| | | style="background-color:#efefef;" | 5V | ||
|- | |- | ||
| | | GPIOE2 | ||
| | | 5 | ||
| | | 6 | ||
| | | style="background-color:#efefef;" | GND | ||
|- | |- | ||
| | | GPIOB18 | ||
| 7 | |||
| | | 8 | ||
| UART0_TX | |||
|- | |- | ||
| | | style="background-color:#efefef;" | GND | ||
| | | 9 | ||
| | | 10 | ||
| | | UART0_RX | ||
|- | |- | ||
| | | GPIOC0 | ||
| | | 11 | ||
| | | 12 | ||
| | | GPIOB8 | ||
|- | |- | ||
| | | GPIOC1 | ||
| | | 13 | ||
| | | 14 | ||
| | | style="background-color:#efefef;" | GND | ||
|- | |- | ||
| | | GPIOC4 | ||
| | | 15 | ||
| | | 16 | ||
| | | GPIOD30 | ||
|- | |- | ||
| | | style="background-color:#efefef;" | VCC | ||
| | | 17 | ||
| | | 18 | ||
| | | GPIOC6 | ||
|- | |- | ||
| | | TWI3_SDA | ||
| | | 19 | ||
| | | 20 | ||
| | | style="background-color:#efefef;" | GND | ||
|- | |- | ||
| | | GPIOC24 | ||
| | | 21 | ||
| | | 22 | ||
| | | GPIOC5 | ||
|- | |- | ||
| | | TWI3_SCK | ||
| | | 23 | ||
| | | 24 | ||
| | | GPIOC23 | ||
|- | |- | ||
| | | style="background-color:#efefef;" | GND | ||
| | | 25 | ||
| | | 26 | ||
| | | GPIOB19 | ||
|- | |- | ||
| | | GPIOB16 | ||
| | | 27 | ||
| | | 28 | ||
| | | GPIOB14 | ||
|- | |- | ||
| | | GPIOB15 | ||
| | | 29 | ||
| | | 30 | ||
| | | style="background-color:#efefef;" | GND | ||
|- | |- | ||
| | | GPIOB10 | ||
| | | 31 | ||
| | | 32 | ||
| | | GPIOB13 | ||
|- | |- | ||
| | | GPIOB0 | ||
| | | 33 | ||
| | | 34 | ||
| | | style="background-color:#efefef;" | GND | ||
|- | |- | ||
| | | GPIOB1 | ||
| | | 35 | ||
| | | 36 | ||
| | | GPIOA28 | ||
|- | |- | ||
| | | GPIOB2 | ||
| | | 37 | ||
| | | 38 | ||
| | | RESERVED | ||
|- | |- | ||
| | | style="background-color:#efefef;" | 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 <code>sysfs</code> e a partir da versao 4.8 a <code>chardev</code>. 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 <code>/sys/class/gpio</code>. 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: | |||
<pre>$ echo 131 > /sys/class/gpio/export</pre> | |||
=== Configurando a direção do pino === | |||
Após exportado o pino devemos configurar a direção do mesmo entre input (<code>in</code>) ou output (<code>out</code>). Para isto basta escrever no GPIO exportado o valor requerido. No nosso exemplo colocaremos como output: | |||
<pre>$ echo out > /sys/class/gpio/gpio131/direction</pre> | |||
=== Escrevendo ou lendo no pino === | |||
Para escrever no pino configurado como output basta enviar o valor para o parâmetro <code>value</code> do pino. No nosso exemplo colocaremos o valor 1 no pino: | |||
<pre>$ echo 1 > /sys/class/gpio/gpio131/value</pre> | |||
Caso o pino seja definido como input basta ler este mesmo arquivo. | |||
<pre>$ cat /sys/class/gpio/gpio131/value</pre> | |||
=== Lendo um parâmetro === | |||
O comando <code>cat</code> 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: | |||
<pre>$ 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 | |||
</pre> | |||
==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 <code>echo</code> e <code>cat</code> usados anteriormente, esta API utiliza a biblioteca [https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/ libgpiod] que provê uma série de ferramentas para uso em terminal e também para uso em C, com bibliotecas de [https://github.com/brgl/libgpiod/tree/master/bindings vinculações] disponíveis em [https://github.com/brgl/libgpiod/tree/master/bindings/cxx C++] e [https://pypi.org/project/gpio-next/ Python]. A solução chardev é mais simples, elegante e robusta que a sysfs. | |||
Para instalar a biblioteca libgpiod no Debian Buster (10), execute: <pre>sudo apt install gpiod libgpiod-dev libgpiod-doc</pre> | |||
=== 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 <code>gpiodetect</code> disponível pelo <code>libgpiod</code> | |||
<pre>$ 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)</pre> | |||
==== gpioinfo ==== | |||
O comando <code>gpioinfo</code> fornece as informações dos pinos de cada controlador, por exemplo para exemplos dos pinos do controlador E: | |||
<pre>$ gpioinfo 0 | |||
line 0: unnamed unused input active-high | |||
line 1: unnamed unused input active-high | |||
line 2: unnamed unused input active-high</pre> | |||
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 <code>gpioget</code>, no exemplo o pino GPIOE3 (controlador 4, pino 3) | |||
<pre>$ gpioget 4 3 | |||
0</pre> | |||
==== gpioset ==== | |||
O comando <code>gpioset</code> muda a direção para output e define o valor do mesmo, no exemplo definiremos o GPIOE3 para alto: | |||
<pre>$ gpioset 4 3=1 | |||
1</pre> | |||
==== gpiomon ==== | |||
Este comando é utilizado para interrupções e eventos, ele monitorará o pino para mudanças e retornará as mudanças encontradas. | |||
<pre>$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]</pre> | |||
=== Utilizando chardev em C === | |||
A API chardev facilita o uso em programas em C, alguns exemplos podem ser encontrados com facilidade, como [https://github.com/starnight/libgpiod-example estes]. |
Edição das 14h33min de 13 de junho de 2022
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
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.