ÍNDICE DE CONTEÚDO
- Comunicação entre processos
- Biblioteca de Hardware
- fork, exec, e daemon
- Pipes
- FIFO
- Shared File
- Signal – O que é e como usar?
- MMAP
- Socket TCP
- TCP SSL
- Socket UDP
- UDP Broadcast
- UDP Multicast
- Socketpair
- Queue System V
- System V – Semaphore
- Shared Memory System V
- POSIX Queue
- POSIX Semaphore
- POSIX Shared Memory
- D-Bus
Introdução
No artigo anterior foi descrito o que era IPC e quais eram os seus tipos, neste artigo será descrito a implementação e instalação da biblioteca responsável por controlar as aplicações que são baseadas no famoso acionamento de um LED através de um botão, esta biblioteca foi criada através de três dos quatros pilares do paradigma de programação orientação a objetos que é a abstração, encapsulamento e herança. Para execução das aplicações serão feitas na plataforma Raspberry Pi 3 e a compilação da biblioteca tanto das aplicações serão feitas utilizando o CMake.
Raspberry Pi 3 B+
A Raspberry Pi 3 Model B+ Anatel é um mini-PC que roda distribuições Linux como o Raspbian e Ubuntu, mas também suporta outros sistemas operacionais como o Windows 10 IoT e versões customizadas do Linux.
A versão B+ da Raspberry Pi 3 tem processador de 1.4GHz, 1GB de memória e agora suporta redes wireless no padrão AC, proporcionando muito mais velocidade para a sua conexão e melhorando a performance da placa. Essas especificações, aliadas à outras melhorias no conjunto do hardware, fazem com que essa placa tenha uma performance 17% maior em comparação ao modelo anterior.
Especificação
- Raspberry Pi 3 Model B+ Anatel
- Processador Broadcom BCM2837B0 64bits ARM Cortex-A53 Quad-Core
- Clock 1.4 GHz
- Memória RAM: 1GB
- Adaptador Wifi 802.11 b/g/n/AC 2.4GHz e 5GHz integrado
- Bluetooth 4.2 BLE integrado
- 4 portas USB 2.0
- Conector Gigabit Ethernet over USB 2.0 (throughput máximo de 300 Mbps)
- Alimentação: 5V 3A (Recomendado)
- Interface para câmera (CSI)
- Interface para display (DSI)
- Slot para cartão microSD
- Conector de áudio e vídeo
- GPIO de 40 pinos
- Certificado de homologação Anatel: 01598-18-10629
- Dimensões: 85 x 56 x 17mm
CMake
CMake é uma ferramenta open source desenvolvida para compilar, gerar testes e construir pacotes para distribuir as aplicações em forma de .rpm ou .deb
Preparando o ambiente
Para o desenvolvimento dos passos a seguir é necessário ter a Raspberry Pi conectada na internet. Acesse a Raspberry via commando ssh ou se estiver conectada em um monitor abra um terminal, durante o desenvolvimento dos exemplos foi utilizado o acesso via ssh.
Acesse o target:
1 |
$ ssh pi@{raspberry_ip} |
Exemplo:
1 |
$ ssh pi@192.168.0.2 |
Atualize os repositorios e instale o cmake:
1 2 |
$ sudo apt-get update $ sudo apt-get install cmake |
Instale o wiringpi
1 |
$ sudo apt-get install wiringpi |
Faça o download do repositorio no link:
1 2 |
$ cd $ git clone https://github.com/NakedSolidSnake/Raspberry_lib_hardware |
Para acessar o repositório clique nesse link
Acesse o diretório Raspberry_lib_hardware para compilar e instalar a biblioteca responsável por controlar o botão e LED dos exemplos:
1 |
$ cd Raspberry_lib_hardware |
No diretório raiz crie uma pasta chamada build onde irá ficar os arquivos gerados pelo cmake e execute o comando do cmake gerar os arquivos para a compilação:
1 2 |
$ mkdir build && cd build $ cmake .. |
Uma vez que os arquivos foram gerados execute o comando make
1 |
$ make |
Irá ser gerado um diretorio bin onde os binarios da aplicação são salvos e um diretório lib onde as bibliotecas ficam salvas.
Agora instale a lib gerada.
1 |
$ sudo make install |
Rode o ldconfig para atualizar os links de biblioteca do sistema
1 |
$ sudo ldconfig |
Com o setup concluído, será apresentado a implementação da lib hardware.
Implementação da biblioteca de hardware
Headers
Para a implementação da lib hardware foi utilizado a API wiringPi que provê uma abstração do hardware da Raspberry Pi, dessa forma facilitando o desenvolvimento. Para saber mais sobre a API acesse wiringpi
gpio.h
Essa enumeração representa o modo em qual o gpio vai ser utilizado com dois estados possíveis: entrada ou saída.
1 2 3 4 5 |
typedef enum { eModeInput = 0, eModeOutput } eMode_t; |
Essa enumeração representa o estado do GPIO.
1 2 3 4 5 |
typedef enum { eStateLow = 0, eStateHigh } eState_t; |
Estrutura GPIO_t contém os atributos pin que recebe o número do GPIO a ser configurado e eMode que representa em qual modo ele vai ser utilizado.
1 2 3 4 5 |
typedef struct { int pin; eMode_t eMode; } GPIO_t; |
Função de inicialização do GPIO.
1 |
int GPIO_init(GPIO_t *gpio); |
led.h
Definição da estrutura de LED onde o unico atributo é a estrutura do GPIO, colocando o tipo GPIO como primeiro atributo da estrutura LED garante que em memória o tipo LED_t e GPIO_t tenham o mesmo endereço de memória assim utilizando o cast para GPIO_t é possível acessar os atributos de GPIO, isso será demonstrado na implementação em sources, mas isso caracteriza a herança do paradigma de programação orientado a objetos.
1 2 3 4 |
typedef struct { GPIO_t gpio; /**!< Herda Gpio */ } LED_t; |
Função de Inicialização do LED
1 |
int LED_init(LED_t *led); |
Função responsável por alterar o estado do LED conforme seu parâmetro eState.
1 |
int LED_set(LED_t *led, eState_t eState); |
button.h
Definição de um Tipo para ponteiro de função onde seu retorno é void e sem parâmetros de entrada, esse tipo serve para poder configurar o callback caso o botão seja configurado para poder gerar interrupções.
1 |
typedef void (*button_cb)(void); |
Definição de uma enumeração que representa como o pull será configurado, se for com resistor externo deve-se configurar como desligado.
1 2 3 4 5 6 |
typedef enum { ePullModePullOff = 0, ePullModePullDown, ePullModePullUp }ePullMode_t; |
Definição de uma enumeração que representa em qual borda vai ser invocada a função de callback.
1 2 3 4 5 6 7 |
typedef enum { eIntEdgeSetup = 0, eIntEdgeFalling, eIntEdgeRising, eIntEdgeBoth }eIntEdge_t; |
Definição Button_t e especializando para seu uso
1 2 3 4 5 6 7 |
typedef struct { GPIO_t gpio; ePullMode_t ePullMode; eIntEdge_t eIntEdge; button_cb cb; }Button_t; |
Função de inicialização do botão.
1 |
int Button_init(Button_t *button); |
Retorna o estado do botão
1 |
int Button_read(Button_t *button); |
Sources
Nesta seção é possível entender como foi feita a implementação e o conceito de herança utilizado.
gpio.c
Aqui podemos ver a implementação de GPIO_t sem muita complexidade, é possível ver a inicialização da API que quando chamada nesse formato mapeia os pinos para o modo schema onde são numerados de 0 à 16.
1 2 3 4 5 6 7 8 9 10 |
int GPIO_init(GPIO_t *gpio) { if(!gpio) return EXIT_FAILURE; wiringPiSetup(); pinMode(gpio->pin, gpio->eMode); return EXIT_SUCCESS; } |
led.c
Aqui pode-se ver como é passado o parametro para GPIO_init, fazendo casting para o tipo (GPIO_t *) a estrutura LED passa a ser GPIO devido ter as mesma referências em memória.
1 2 3 4 5 6 7 |
int LED_init(LED_t *led) { if(!led) return EXIT_FAILURE; return GPIO_init((GPIO_t *)led); } |
Aqui pode-se ver como é passado o parâmetro para GPIO_init, fazendo casting para o tipo (GPIO_t *) a estrutura LED passa a ser GPIO devido ter as mesma referências em memória.
1 2 3 4 5 6 7 8 9 |
int LED_set(LED_t *led, eState_t eState) { if(!led) return EXIT_FAILURE; digitalWrite(((GPIO_t *)led)->pin, eState); return EXIT_SUCCESS; } |
button.c
Aqui acontece o mesmo que em led.c, essa é uma forma de se obter a herança em C.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
int Button_init(Button_t *button) { if(!button) return EXIT_FAILURE; GPIO_init((GPIO_t *)&button); pullUpDnControl(((GPIO_t *)button)->pin, button->ePullMode); if(button->cb) wiringPiISR(((GPIO_t *)button)->pin, button->eIntEdge, button->cb); return EXIT_SUCCESS; } |
Implementação de leitura do botão
1 2 3 4 5 6 7 |
int Button_read(Button_t *button) { if(!button) return EXIT_FAILURE; return digitalRead(((GPIO_t *)button)->pin); } |
Testando a instalação e as conexões de hardware
A conexão dos componentes é bem simples demonstrado na figura a seguir:
Montagem do LED é do Botão no Fritzing.
Esquemático do LED e do Botão no Fritzing.
Uma vez montado o circuito agora é só testar para ver se está tudo funcionamento conforme o esperado, para isso acesse a pasta bin/tests:
1 |
$ cd bin/tests |
Execute a aplicação test_test, e assim que pressionar o botão o LED deve mudar de estado.
1 |
$ ./test_test |
Conclusão
Neste artigo foi apresentado como se configura o ambiente, verificação de como o código fonte foi implementado de uma forma simples mas sofisticada, para não dizer cheio de flores, e também como conectar os componentes aos gpio’s do Raspberry Pi 3 B+, e por fim como testar para verificar se a configuração foi executada corretamente. No próximo artigo abordaremos os mecanismos para criação de processos.
Para acessar a biblioteca completa clique aqui