[LAB] Bibliotecas e Hardware Handling
Neste projeto vamos aprofundar um pouco mais na manipulaĆ§Ć£o dos hardwares e perifĆ©ricos dos sistemas embarcados utilizando Linux. Vamos desenvolver uma aplicaĆ§Ć£o bĆ”sica que realize algumas tarefas que sĆ£o comumente utilizadas em aplicaƧƵes embarcadas, como: manipulaĆ§Ć£o de GPIO, geraĆ§Ć£o de PWM, trigggers e callbacks.
Para desenvolver aplicaƧƵes em sistemas Linux embarcados, geralmente utilizamos bibliotĆ©cas in-house ou de terceiros para desempenhar determinados papeis na aplicaĆ§Ć£o, por exemplo, comunicaĆ§Ć£o com hardware, protocolos, criptografias e etc.
Esta Ć© uma escolha usualmente simples, pois muitas vezes nĆ£o Ć© desejĆ”vel re-implementar este tipo de funĆ§Ć£o, ou estĆ” fora do escopo do projeto ou simplesmente pois existe uma gama tĆ£o grande de bibliotecas que desempenham este papel com maestria e jĆ” foram massivamente testadas e possuem um bom suporte que nĆ£o convĆ©m desenvolvelas novamente.
Para a manipulaĆ§Ć£o de hardware nĆ£o Ć© diferente, existem diversas bibliotecas e APIs na comunidade para este fim. Cada uma com sua especificidade, sua aplicaĆ§Ć£o, sua interface e sua linguagem de implementaĆ§Ć£o, tais como: WiringPi, PIGPIO e RPi.GPIO.
Por alguns motivos em particular, vamos utilizar a biblioteca PIGPIO
para as implementaƧƵes desta atividade. ElĆ” possui um interface em linguagem C, Ć© suportada para todas as versƵes das Raspberrys e possui uma boa gama de funƧƵes, tais como: manipulaĆ§Ć£o bĆ”sica de GPIOs, timers, comunicaĆ§Ć£o serial e etc.
Cross-compilando e Instalando o PIGPIO no host
A compilaĆ§Ć£o deve ser feita utilizando cross-compiling, uma vez que o cĆ³digo Ć© feito para rodar no embarcado. Portando, altere a variĆ”vel CROSS_COMPILE
dentro do Makefile
para receber o prefixo da ferramenta de cross compilaĆ§Ć£o.
ApĆ³s a compilaĆ§Ć£o observe os arquivos gerados dentro do diretĆ³rio PIGPIO
. Estamos especialmente interessados nas bibliotecas compartilhadas (.so
) e nos cabeƧalhos.
Instalando o PIGPIO no target (Buildroot)
Para instalar a PIGPIO
podemos utilizar o Buildroot, uma vez que o Busybox tem esta biblioteca em seu repositĆ³rio.
Abra o menu de configuraĆ§Ć£o dos pacotes do Buildroot:
Na seĆ§Ć£o Target packages entre na subseĆ§Ć£o Hardware Handling, onde se encontram diversos pacotes para a manipulaĆ§Ć£o e perifĆ©ricos e entĆ£o selecione o pacote pigpio
. Save a configuraĆ§Ć£o e recompile o nosso RootFS. NĆ£o se preocupe, o processo de compilaĆ§Ć£o ignora os arquivos jĆ” compilado, desta forma o processo se torna simples e rĆ”pido.
EntĆ£o, grave a nova imagem do RootFS no cartĆ£o SD e realize a configuraĆ§Ć£o novamente. Para que tenhamos acesso agora, a essa nova biblioteca no nosso sistema embarcado.
Por padrĆ£o, as bibliotecas sĆ£o instaladas dentro de /usr/lib
no nosso target. NĆ£o diferente, se listarmos os arquivos disponĆveis dentro deste diretĆ³rio encontraremos os referidos arquivos.
Utilizando a PIGPIO
:
PIGPIO
:Primeiro passo que devemos fazer Ʃ importar esta nossa biblioteca atravƩs da primitiva de prƩ-processamento:
EntĆ£o, ao compilar o cĆ³digo percebemos que nĆ£o Ć© possĆvel realizar a compilaĆ§Ć£o pois o linker nĆ£o encontrou a referida biblica, pois a mesma nĆ£o se encontra no diretĆ³rio de execuĆ§Ć£o. Portanto, faz-se necessĆ”rio informar tanto o caminho do diretĆ³rio que deve ser incluĆdo no PATH do compilador como o nome da biblioteca, assim:
Clique com o botĆ£o direito sobre o projeto e em Properies > C/C++ Build > Settings.
EntĆ£o, na aba central, escolhemos a subseĆ§Ć£o Cross GCC Compiler > Includes.
Em "includes paths (-l)" adicionamos o caminho atƩ a biblioteca compilada: /home/gbs/dsle20/libs/PIGPIO
.
Na subseĆ§Ć£o Cross GCC Linker > Libraries em "Libraries (-l)" adicionamos o nome da biblioteca: pigpio
(sem o prefixo lib e sem a extensĆ£o .so).
Por fim, em "Library search path (-L)" adicionamos novamente o caminho para a biblioteca compilada: /home/gbs/dsle20/libs/PIGPIO
Finalmente apĆ³s a compilaĆ§Ć£o iremos copiar os binĆ”rios gerados para dentro da RPi e entĆ£o executar o nosso cĆ³digo de teste.
Este erro Ć© ocasionado pois o executĆ”vel nĆ£o conseguiu encontrar o arquivo "libpigpio.so.1
". De fato, podemos listar as bibliotecas instaladas e procurar pela libpigpio no target:
Ao passo que no host:
Nota-se que hĆ” um link simbĆ³lico libpigpio.so -> libpigpio.so.1, ou seja, no processo de compilaĆ§Ć£o a biblioteca a libpigpio.so
Ć© substituĆda por libpigpio.so.1
. Normalmente, este nĆŗmero no final da biblioteca indica o versionamento atual da biblioteca, Ć© muito comum realizar este tipo de link. PorĆ©m, na versĆ£o instalada na plataforma target, nĆ£o hĆ” o arquivo *.so.1
desta forma, precisamos criar este link no target para conseguir realizar a execuĆ§Ć£o corretamente.
Agora basta compilar o cĆ³digo e tudo deve funcionar como o esperado.
Toda as funƧƵes utilizadas nesta (e nas seguintes) prĆ”tica podem ser consultadas atravĆ©s da documentaĆ§Ć£o da biblioteca PIGPIO
ou mesmo atravƩs do comando man
.
GeraĆ§Ć£o de Sinal PWM utilizando a Biblioteca PIGPIO
PIGPIO
Com a biblioteca devidamente instalada em ambas as plataformas podemos dar inĆcio a prĆ”tica deste laboratĆ³rio.
O primeiro objetivo Ć© gerar um sinal PWM em um dos pinos de uso geral da RPi3, de acordo com a especificaĆ§Ć£o mostrada no diagrama de forma de onda abaixo, isto Ć©, PWM de 50Hz e 50% de duty-cycle.
Primeiramente, devemos inicializar a biblioteca PIGPIO, esta inicializaĆ§Ć£o Ć© feita atravĆ©s da funĆ§Ć£o gpioInitialise
.
Depois de inicializada devemos configurar o modo de operaĆ§Ć£o do pino que produzirĆ” o sinal PWM. Nesta prĆ”tica iremos utilizar o GPIO 23 (observe o pinout da RPi para verificar a localizaĆ§Ć£o fĆsica do mesmo). Para configurar o GPIO 23 como um pino de saĆda, basta utilizar a funĆ§Ć£o gpioSetMode
.
Em seguida, utilizamos a funĆ§Ć£o gpioSetPWMfrequency
para definir a frequĆŖncia de geraĆ§Ć£o do pulso.
Em seguida devemos definir o atravĆ©s da funĆ§Ć£o gpioSetPWMrange
a resoluĆ§Ć£o do pulso gerado, bem como o duty-cycle do PWM atravĆ©s da funĆ§Ć£o gpioPWM
. O duty-cycle Ć© definido pela razĆ£o entre o range e o parĆ¢metro passado a funĆ§Ć£o gpioPWM
.
ApĆ³s a execuĆ§Ć£o do cĆ³digo Ć© necessĆ”rio encerar as configuraƧƵes dos pinos, similarmente como realizado no processo de inicializaĆ§Ć£o.
ISR e Callbacks utilizando a Biblioteca PIGPIO
PIGPIO
Na segunda parte da atividade iremos realizar a configuraĆ§Ć£o de uma ISR (interrupĆ§Ć£o) em um dos pinos. Esta interrupĆ§Ć£o serĆ” vinculada a uma funĆ§Ć£o signal_handler_io
que tem como objetivo executar uma determinada tarefa, como por exemplo a manipulaĆ§Ć£o de um outro pino ou mesmo a execuĆ§Ć£o de uma outra funĆ§Ć£o qualquer.
Primeiramente vamos realizar a configuraĆ§Ć£o de mais duas GPIOs. A GPIO 20 serĆ” configurada como uma porta de entrada e estarĆ” vinculada Ć ISR. AlĆ©m disso, iremos inializar o GPIO 16 como saĆda para que a mesma seja manipulada pela callback da interrupĆ§Ć£o.
Para atrelar um GPIO a uma ISR devemos utilizar a funĆ§Ć£o gpioSetISRFunc
da biblioteca PIGPIO. Como parĆ¢metros podemos passar a GPIO utilizada, a borda Ć ser detectada, um timeout e tambĆ©m a funĆ§Ć£o (callback) a ser chamada quando o evento acontecer.
Assim, devemos criar a funĆ§Ć£o signal_handler_IO para ser utilizada como callback.
Populamos a funĆ§Ć£o com alguma tarefa qualquer, neste caso, foi proposto calcular o tempo entre duas interrupƧƵes e tambĆ©m alterar o estado do GPIO 16, ligando-o e desligando conforme ocorrem as interrupƧƵes.
Ao executar o cĆ³digo podemos observar o seguinte diagrama:
A primeira forma de onda Ć© o sinal PWM gerado pelo GPIO 23 ao passo que a segunda Ć© a forma de onda gerada pelo GPIO 16.
Realizando um contato elĆ©trico entre os GPIO 23 e GPIO 20, ou seja, conectando o PWM ao pino ISR Ć© possĆvel obter o diagrama a seguir.
Desta forma, foi possĆvel visualizar a operaĆ§Ć£o da ISR dos dois modos: timeout e detecĆ§Ć£o de borda. Estes tĆ³picos serĆ£o abordados no projeto final.
Last updated