Linux customizado e início de programas após boot usando RPi e Buildroot

Buildroot

Muitas vezes quando usamos sistemas embarcados com suporte ao Linux, queremos usar apenas o mínimo de pacotes necessários para que o nosso sistema funcione. Por exemplo, se usarmos uma Raspberry Pi para criar um servidor, não precisamos de todas as funcionalidades incluídas em uma distro como a Raspbian, como por exemplo a interface gráfica.

É óbvio que existem distribuições já prontas (inclusive da própria Raspbian) que já vem com menos funcionalidades, porém ainda assim podemos querer customizar ainda mais. Para automatizar e facilitar a construção de uma distro customizada, existem algumas ferramentas de build para sistemas embarcados baseados em Linux. Entre elas estão incluídas, por exemplo, o Yocto e o Buildroot, que são projetos open-source.

Da mesma forma que existem diferentes ferramentas, existem diferentes placas que são capazes de rodar um sistema Linux Embarcado, como a BeagleBone e as placas ODROID. Neste post vamos falar um pouco sobre o uso do Buildroot para a criação de uma imagem para a Raspberry Pi, incluindo:

  • Criar nosso próprio pacote (um programa simples em Python) e disponibilizá-lo para que possa ser incluído na nossa imagem;
  • Escolher quais pacotes queremos adicionar à imagem final;
  • Iniciar a execução do nosso programa assim que a raspberry fizer boot, evitando que seja necessário acessar a Raspberry (via ssh ou teclado) para começar a executar.

O sistema operacional no host (minha máquina) usado para construir esse tutorial é o Ubuntu 16.04 LTS. Porém, os conceitos se aplicam a qualquer distribuição, mudando apenas alguns pequenos detalhes como o gerenciador de pacotes (no caso deste tutorial, apt-get).

Buildroot

O que é?

Como dito anteriormente, o Buildroot é uma ferramenta que auxilia e automatiza a criação de distribuições Linux Embarcado. Ele faz a cross-compilação do código para a arquitetura da placa para a qual se quer construir a distribuição (mais sobre Cross-compilação neste artigo).

A documentação do Buildroot é bem completa (embora um pouco difícil de entender à primeira vista) e existe bastante referência online e na comunidade, como o site do Sérgio Prado e da Bootlin (antiga Free Electrons).

Instalação

Instalar o Buildroot é, basicamente, clonar ou baixar o repositório da ferramenta. Porém, para que possa ser usada, alguns pacotes são necessários, como explicado neste outro artigo. Para instalá-los, execute no terminal:

Clone o repositório oficial ou o mirror no github:

ou:

Crie uma nova branch tendo como raiz a LTS (no momento, a LTS mais recente é a 2018.02):

Criando um pacote para o buildroot

Você pode desenvolver qualquer aplicação que desejar. Por simplicidade, recomendo o uso de Python caso você não tenha familiaridade com makefiles e cross-compilação de programas em C.  

Para o Buildroot, importa que o código esteja em algum lugar acessível para que a ferramenta possa fazer o download e compilação (se necessário). Por exemplo, criando um repositório no seu Github.

Para este tutorial usarei um programa em Python que simula o comportamento de um jogo de GENIUS (SIMON, em inglês).

O jogo gera sequências crescentes aleatórias de quatro botões e o jogador deve repetir a sequência gerada para passar de nível. O código está disponível no github.

Na pasta do Buildroot, crie a pasta que terá as instruções de download e compilação do seu pacote. O manual do Buildroot recomenda a seguinte hierarquia quando criando novos pacotes:

Estrutura de diretórios recomendada pelo manual do Buildroot.
Figura 1: Estrutura de diretórios recomendada pelo manual do Buildroot.

Como só temos um novo pacote e não precisamos criar uma pasta para a empresa, a nossa estrutura ficará um pouco diferente:

Estrutura de diretórios do pacote criado.
Figura 2: Estrutura de diretórios do pacote criado.

O seu pacote pode ter qualquer nome, desde que o nome do diretório seja o mesmo do nome do arquivo com a extensão “.mk”.

Para isso, estando dentro do repositório do Buildroot que você clonou:

Abra os arquivos criados com o seu editor de texto favorito, copie o conteúdo dos arquivos Config.in e simon-game.mk e salve.

Por fim, modifique o arquivo package/Config.in para incluir o seu pacote na ferramenta menuconfig. Neste arquivo, existe uma seção “menu Games”, e dentro dela iremos incluir o nosso jogo. Inclua a linha:

Caso você deseje, é possível criar o seu próprio menu com os seus pacotes.

A partir desse momento, caso você queira pular para a seção Instalando o pacote criado e dependências via menuconfig, o seu sistema funcionará. Porém, o jogo simon não estará executando assim que a Raspberry Pi se iniciar. É preciso que você a acesse e execute diretamente o programa em /usr/local/bin/simon-game-master/simon_gpio.py.

Inicializando a aplicação no momento do boot

Iremos criar um script que será responsável por iniciar e parar o jogo. Esse script deve ser colocado em uma pasta específica, em que todos os scripts dentro dela são executados quando o sistema se inicia. A pasta em questão é /etc/init.d/.

Existem (pelo menos) duas formas de fazer com que o nosso script seja copiado para a Raspberry Pi no caminho desejado. Embora a primeira solução seja mais elegante (IMHO) e a recomendada no manual do buildroot, com a segunda solução fazemos com que o nosso pacote seja auto-contido, por isso eu segui com ela no meu desenvolvimento.

  • Alterando rootfs_overlayDe acordo com o manual do buildroot: “A filesystem overlay is a tree of files that is copied directly over the target filesystem after it has been built.” Ou seja, após criado o sistema, os arquivos presentes na pasta de rootfs_overlay são copiados. É importante que a estrutura de diretórios dentro da rootfs_overlay seja mantida igual à estrutura de onde queremos adicionar os arquivos ou diretórios. Então deveríamos ter algo como /board/raspberrypi/rootfs_overlay/etc/init.d/S70simon.
  • Criando o script na pasta do pacote e modificando o .mkDentro de package/simon-game, criamos um novo arquivo que será o script de execução do jogo, chamaremos o arquivo de S70simon (a nomeclatura deve obrigatoriamente começar com “S” seguido de um numeral). Modifique o arquivo simon-game.mk, adicionando o comando para copiar o script para a pasta desejada.

Instalando o pacote criado e dependências via menuconfig

Com todas as alterações salvas, na pasta raiz do buildroot, execute:

Caso você esteja usando alguma outra versão da Raspberry Pi, modifique para o defconfig adequado (todos os arquivos de defconfig estão em /configs). Em seguida, vamos adicionar o nosso pacote:

Tela do menuconfig. do Buildroot
Figura 3: Tela do menuconfig.

Navegue para Target packages > Games e selecione simon-game. Volte para a tela inicial do menuconfig (esc-esc volta uma página), siga para Filesystem images > exact size e altere para 120M.

Salve as alterações e saia.

NOTA: O tamanho padrão da imagem que o buildroot gera é menor do que o que precisamos, o que causa um erro se não modificarmos este valor. Para descobrir o valor que precisamos, primeiro encontramos o tamanho da pasta target (após a primeira compilação sem sucesso), dividimos o valor por (1024)² e adicionamos mais 50M de padding (mais informações aqui e aqui).

Compilação e criação do SD

Inicie a compilação e vá fazer alguma outra coisa, visto que este processo é bastante demorado (algumas horas, na minha máquina).

Após finalizada a compilação, o seu diretório output/images deve ter a seguinte estrutura:

Buildroot
Figura 4: Estrutura de diretórios em output/images.

Copie o arquivo de imagem para o cartão de memória. Caso você não saiba onde o seu cartão foi montado, você pode usar o programa “disks” no seu Ubuntu para verificar. Substitua o valor após “of=” pelo caminho para o seu SD.

O seu cartão também pode ter sido montado em /dev/mmcblkX.

NOTA: O seu sistema operacional é comumente montado em /dev/sda. NÃO COLOQUE ESSA ROTA COMO SAÍDA DO COMANDO dd OU VOCÊ PERDERÁ TODOS OS SEUS ARQUIVOS.

Verificando o resultado

Ligue a Raspberry Pi à energia e verifique se o jogo inicia ao apertar o botão de start game.

As ligações de fios e conexões de entrada e saída estão descritas no readme do projeto.

Raspberry Pi pinout.
Figura 5: Raspberry Pi pinout.
 

Botão Start

Botão Verde

Botão Vermelho

Botão Amarelo

Botão Azul

LED Verde

LED Vermelho

LED Amarelo

LED Azul

Pino

29

31

33

35

37

22

24

26

28

BCM

5

6

13

19

26

25

8

7

1

Esquema de ligações na placa.
Figura 6: Esquema de ligações na placa. (Desenhado com Fritzing).

Caso você queira ver se o processo está sendo executado no seu sistema, logue via ssh e execute:

Resumo

O buildroot facilita e automatiza o processo de criação de uma distribuição Linux customizada apenas com os pacotes que são do interesse do desenvolvedor. Neste artigo falamos sobre como usar o Buildroot para criar uma distribuição Linux contendo pacotes criados por nós e fazer com que esses programas sejam executados assim que a Raspberry Pi fizer o boot.

No github estão disponíveis os repositórios com o jogo em Python e com o buildroot modificado.

  • Instale as dependências para o buildroot:
  • Baixe, fork ou clone o repositório pauloserrafh/buildroot e siga para a branch buildroot_simon_rpi:
  • Inclua os pacotes necessários:
  • Navegue para Target packages > Games e selecione simon-game. Volte para a tela inicial do menuconfig (esc-esc volta uma página), siga para Filesystem images > exact size e altere para 120M.
  • Compile e grave no cartão de memória:

Saiba mais

Introdução a cross-compiling com a Raspberry Pi

Criando uma imagem customizada para a BeagleBone Black com Buildroot

Webinar Gravado: Desenvolvendo com Linux Embarcado

Referências

https://www.raspbian.org/
https://buildroot.org/
https://beagleboard.org/
https://odroidinc.com/
http://buildroot.net/downloads/manual/manual.html
https://sergioprado.org/?s=buildroot
https://bootlin.com/
https://git.buildroot.net/buildroot/
https://github.com/buildroot/buildroot
https://unix.stackexchange.com/questions/353156/how-to-calculate-the-correct-size-of-a-loopback-device-filesystem-image-for-debo
https://stackoverflow.com/questions/49211241/is-there-a-way-to-automatically-detect-the-minimum-required-br2-target-rootfs-ex
http://cellux.github.io/articles/diy-linux-with-buildroot-part-1/
http://cellux.github.io/articles/diy-linux-with-buildroot-part-2/
https://github.com/pauloserrafh/simon_python
https://github.com/pauloserrafh/buildroot/tree/simon_game_buildroot
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Linux Embarcado » Linux customizado e início de programas após boot usando RPi e Buildroot
Comentários:
Notificações
Notificar
guest
3 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Eduardo Scherrer
Eduardo
10/04/2018 00:08

Olá Paulo, achei o local, fica no git, exatamente na sua conta.
Mas se eu não quiser deixar o meu código do git, é possível deixar local, e o arquivo .mk apontar para este novo local?

Abraço

Eduardo Scherrer

Eduardo Scherrer
Eduardo
09/04/2018 23:43

Olá Paulo,

Onde deve estar salvo o arquivo .py? Não encontrei o lugar correto.

Abraço.

Talvez você goste:

Séries

Menu

WEBINAR
 
NVIDIA JETSON – A Inteligência Artificial na palma de sua mão

Data: 08/07 às 14:00h Apoio: Arrow | NVIDIA
 
INSCREVA-SE AGORA »



 
close-link

WEBINAR
 
Redes Mesh para Monitoramento
e Controle de Sensores

Data: 15/07 às 14:00h Apoio: Artimar| Microchip| Tecsus
 
INSCREVA-SE AGORA »



 
close-link