Integrando Aplicações em Imagens Linux Embarcado

Aplicações em Imagens Linux

Imagens de Linux embarcado pré-compiladas e prontas são muito comuns no meio maker. Elas já possuem os componentes mais comuns para que os estudantes e entusiastas do mundo de embarcados comecem a desenvolver. Dentre elas temos Ubuntu, Debian, Arch e etc.

  

Porém, esse não é o caso quando necessitamos de uma imagem Linux para sistema embarcado customizada e específica para um computador em módulo ou produto industrial. Existe todo um processo de geração de imagens no qual podemos eliminar qualquer item indesejado que muitas vezes aumenta tempo de boot, consumo de memória e processamento. Por utilizar uma distribuição pronta, muitas vezes desperdiçamos recursos do sistema. Por exemplo, em aplicações headless, onde não necessitamos de um ambiente desktop ou GUI, podemos gerar uma imagem console tendo assim uma imagem mais leve e rápida. Um outro ponto negativo de distribuições prontas são problemas com licenças. A Canonical, por exemplo, não permite a venda de um produto com Ubuntu modificado sem a devida parceria e certificação. Já com uma imagem customizada, podemos ter total controle dos pacotes instalados ou das licenças utilizadas. Podemos assim, ter uma imagem otimizada de acordo com os requisitos do projeto, sendo software ou hardware.

 

E se precisarmos incluir na nossa imagem uma aplicação em Qt feita por nós ou mesmo incluir um binário feito em linguagem C? Precisamos compilar primeiro e depois copiar para a placa? É necessário gerar um pacote “.ipk” ou “.deb” e instalar na placa? Como podemos incluir nossa aplicação no “IMAGE_INSTALL_append” dentro do arquivo “local.conf”? Como é feito o startup automático de aplicações em um equipamento embarcado?

 

Neste artigo vamos mostrar como fazer tudo isso de uma forma automatizada utilizando as ferramentas do Openembedded/Yocto, mostrando um pouco dos passos que ocorrem por trás do comando bitbake, como compilação, instalação de pacotes e geração de diretórios, incluindo um serviço que inicia nossas aplicações após a inicialização do sistema operacional, e no final teremos uma distribuição de linux embarcado pronta para um produto!

 

Embora os detalhes deste artigo variam de acordo com cada situação, diferentes plataformas de desenvolvimento e SBC, os princípios aqui descritos se aplicam de forma geral.

 

Para entender melhor sobre OpenEmbedded/Yocto, Bitbake e etc, recomendamos antes a leitura de alguns artigos que complementam bastante o nosso tema:

 

Cozinhando com Yocto Project

BeagleBone Black + Yocto

Desvendando Yocto Project (Poky) - Primeiros passos

 

Para a execução dos passos encontrados neste artigo é necessária a configuração de um ambiente para geração de imagens linux embarcado. Para configurar o ambiente de build, nos baseamos em um tutorial do site de desenvolvedores da Toradex. A Toradex usa o OpenEmbedded-core para geração de imagens. Basicamente, seguindo o tutorial, é necessário:

  • Instalação dos pré-requisitos;
  • Instalação do repo;
  • Download da imagem Toradex na versão 2.5.

 

A partir daí teremos uma estrutura de diretórios como a seguinte:

 

 

Dentro da pasta stuff é necessário a adição do layer meta-qt5 já que nossas aplicações são baseadas em Qt. Para isso executamos o seguinte comando dentro da pasta stuff:

 

 

Com isso já podemos gerar nossas próprias distribuições customizadas de Linux embarcado!

 

 

Criando aplicações com Qt Creator

 

Para o propósito do nosso artigo, desenvolvemos uma aplicação no estilo “dual-screen” ou “dual-display”, que na verdade são duas aplicações rodando em diferentes telas. Esse tipo de aplicação é bastante encontrada, por exemplo, em kiosks de check-in de aeroportos ou também em carros modernos, onde temos um cluster de instrumentação atrás da direção, e em outra tela no painel, temos uma central de mídia, GPS e etc.

 

Não entraremos em detalhes sobre configuração do Qt creator para cross-compilação. Essas informações estão muito bem documentadas no Toradex Developer Portal em Configurando o Qt Creator para cross-compilar para Linux embarcado.

 

O código fonte das aplicações app-artigo-screen1 e app-artigo-screen2 podem ser encontradas no GitHubLembrando que, quando gerarmos nossa imagem, as duas aplicações serão baixadas e compiladas automaticamente seguindo as configurações da nossa receita mais a frente.

 

IMPORTANTE: Quando geramos nossa imagem, a determinação do diretório onde a aplicação será instalada foi feita no arquivo “.pro” do projeto Qt, apenas incluindo as linhas abaixo de “# deployment on Linux”:

 

 

 

Sincronizando as aplicações com o GitHub

 

Optamos por usar o GitHub pelo fato do mesmo ser uma plataforma na nuvem e pela facilidade de controle de versões da aplicação, o que torna possível qualquer um ter acesso às aplicações e projetos lá armazenados. Mais a frente veremos como as receitas baixam essas aplicações do GitHub para então serem incluídas em uma imagem Linux de uma forma automatizada. Para isso é necessário sincronizar o nosso diretório local onde se encontram as aplicações com um repositório no GitHub. Deve ser criado um repositório para cada aplicação.

 

Partindo do ponto onde já temos uma conta criada, devemos adicionar um repositório. Clique em '+' no canto superior direito do site e então New Repository. Na página seguinte apenas adicione um nome e uma descrição para o repositório e em seguida clique em Create repository.

 

Aplicações em Imagens Linux Embarcado - Tela onde é criado um novo repositório.
Figura 1- Tela onde é criado um novo repositório.

 

Na próxima página, o GitHub nos dá algumas opções. Vamos escolher por conveniência a seguinte:

  

Aplicações em Imagens Linux Embarcado - Comandos de sincronização com GitHub.
Figura 2 - Comandos de sincronização com GitHub.

 

Os comandos acima devem ser executados no computador host dentro do diretório de cada aplicação do Qt, screen1 e screen2. Lembre-se de ajustar a seguinte URL com seu nome de usuário e nome de repositório escolhido.

 

 

Após o comando push, entre com nome de usuário e senha do GitHub e o upload dos projetos será feito. Repita o processo para a outra aplicação.

 

Entre em seu perfil do GitHub e poderemos ver os repositórios.

 

Aba de repositórios do GitHub.
Figura 3 - Aba de repositórios do GitHub.

 

 

Criando nosso layer e receitas

 

O que é uma receita? De acordo com o Reference Manual do Yocto, receitas são todos os arquivos terminados com sufixo .bb. Basicamente a receita contém informações sobre um determinado software. Essas informações incluem o local de onde baixar conteúdo, patches a serem aplicados, como compilar arquivos fonte e como compactar tudo isso no final do processo.

  

Um bom hábito para realizar a adição de uma receita ao ambiente build é colocar essa receita em um novo layer. Layers permitem a separação de determinados conjuntos de meta-data de acordo com tipo de machine, funcionalidades ou itens similares. Podemos ver muito disso em layers de empresas como da Toradex, que usa o layer meta-toradex para disponibilizar aos clientes Board Suporte Packages (BSP), Kernel customizado, U-boot, funcionalidades gráficas e muito mais. Outros layers conhecidos são, meta-beagleboard, meta-fsl-arm, meta-intel-galileo. Encontramos até alguns layers bem interessantes como meta-games, meta-maker e meta-uav para drones. Uma vasta lista de layers pode ser encontrada aqui. Como exemplo vamos criar um layer de nome “meta-projects”.

 

No diretório oe-core se encontra a pasta stuff, e dentro da pasta stuff são encontrados os layers, inclusive o layer da toradex “meta-toradex”. Para começar a criação do layer, crie a pasta meta-projects dentro de stuff com o comando:

 

 

Dentro de meta-projects crie uma pasta chamada conf:

 

 

Dentro da pasta conf crie um arquivo de nome layer.conf com o seguinte conteúdo:

 

 

Esse é um conteúdo minimalista e padrão para um arquivo de configuração de um layer. Note o nome do nosso layer meta-projects.

 

As receitas se encontram dentro de diretórios comumente organizadas por tipo de aplicação. Como exemplo o layer meta-toradex:

 

 

Podemos ver que todas as receitas e aplicações relacionadas a Qt estão em recipes-qt. As relacionadas a kernel estão em recipes-kernel e assim por diante. Já que nossas aplicações estão relacionadas a Qt, vamos criar dentro de meta-projects a pasta recipes-qt.

 

 

Dentro de recipes-qt, criamos uma pasta com o nome de cada aplicação.

 

 

 

Editando itens da receita e suas funções (download do GitHub, auto start-up)

 

Tomamos como base uma receita simples que apenas compila um programa tipo Hello World escrito em C e o instala nos devidos diretórios onde encontram-se os binários do sistema.

 

 

Programa em C

 

 

Dentro de cada pasta das receitas criaremos o arquivo .bb, que é a receita propriamente dita. Esse arquivo deve conter algumas variáveis básicas como:

  • DESCRIPTION - Contém uma breve descrição da aplicação e receita;
  • SECTION - Uma seção ou categoria que a receita se enquadra;
  • LICENSE - O arquivo de licença que se aplica à receita, aplicação ou software;
  • LIC_FILES_CHKSUM - O número checksum do arquivo da licença;
  • SRC_URI - O local onde se encontra a aplicação ou código fonte;
  • SRCREV - Tag do commit desejado do repositório do GitHub.

 

A receita usada no caso da primeira aplicação encontra-se a seguir, sendo que a receita da segunda aplicação segue o mesmo conceito.

 

 

Quebrando um pouco a receita podemos notar alguns itens importantes.

 

Nas seguintes linhas indicamos a licença a ser utilizada.

 

 

A licença MIT é bastante utilizada em projetos open-source e pode ser encontrada no seguinte diretório:

 

 

O número do checksum do arquivo da licença pode ser obtido usando a aplicação do linux md5sum, apenas execute:

 

 

Outras licenças podem ser criadas caso o foco do projeto não seja open-source. Lembre-se de indicar o path e o checksum corretos da licença.

 

Na variável SRC_URI temos o local onde se encontra nossa aplicação, no caso, GitHub. A aplicação será baixada, compilada e instalada no root-filesystem da imagem final.

 

 

A variável SRCREV carrega a tag do commit do repositório a ser usado. Para saber qual tag usar, entre no seu repositório do github na seção de commits:

 

https://github.com/giobauermeister/app-artigo-screen1/commits/master

 

Clique no botão indicado para copiar a tag. É sempre indicado usar o commit mais recente.

 

Lista de commits e suas tags
Figura 4 - Lista de commits e suas tags

 

Nas seguintes linhas indicamos algumas dependências do QT:

 

 

A seguir temos a função do_install que é responsável por instalar nosso script de inicialização da aplicação e também o arquivo Unit que é o responsável pelo startup automático da aplicação. Podemos vê-los abaixo em vermelho. Também temos algumas variáveis relacionadas ao systemd.

 

 

Lembrando que o diretório de instalação das aplicações são configurados no arquivo do projeto em Qt como já visto na seção “2. Criando aplicações com Qt Creator”.

 

O conteúdo do arquivo Unit qt-artigo-embarcados-screen1.service encontra-se a seguir:

 

 

Esse arquivo será iniciado automaticamente como um processo do linux. Mais informações sobre arquivos Unit podem ser encontradas aqui, e também no Portal de Desenvolvedores da Toradex.

 

Podemos notar que o arquivo Unit chama nosso script de inicialização. O conteúdo do script da primeira aplicação é o seguinte:

 

 

O script da segunda aplicação se diferencia em apenas alguns itens:

 

 

Note o comando export QT_QPA_EGLFS_FB. Esse comando determina em qual tela a aplicação será executada. Essa nova variável foi introduzida nas novas versões do Qt5.

 

Ambos os scripts devem estar no repositório do GitHub de cada aplicação e serão baixados e instalados quando gerarmos a imagem.

 

 

Gerando a imagem

 

Nesse ponto já devemos ter:

  • Um ambiente configurado de geração de imagens;
  • Aplicações em Qt sincronizadas com GitHub;
  • Criado nosso layer meta-projects e receitas.

 

Dentro da pasta oe-core, execute o comando:

 

 

O comando nos leva para a pasta build onde iremos gerar nossa imagem.

 

Dentro de build/conf encontramos os arquivos bblayers.conf e local.conf. Em bblayers.conf são listados todos os layers que contém recursos e pacotes para nossa imagem. Anteriormente já havíamos clonado o layer meta-qt5 dentro da pasta stuff. Devemos listar os dois novos layers meta-projects e meta-qt5 no arquivo bblayers.conf.

 

 

No arquivo local.conf encontram-se informações de como o build deve proceder, qual machine será utilizada, em quantos cores o build será executado, diretórios de download, etc. A variável que nos interessa é IMAGE_INSTALL_append. É essa variável que diz quais pacotes e aplicações serão instalados, assim, podemos também incluir nossas aplicações em Qt.

 

Entre no arquivo local.conf e adicione/edite o seguinte conteúdo:

 

 

Em IMAGE_INSTALL_append adicionamos alguns pacotes relacionados a Qt, nossas aplicações, e alguns pacotes para configuração de tela touch.

 

A variável ACCEPT_FSL_EULA deve ser setada confirmando que concordamos com a Licença da empresa Freescale por se tratar de um módulo iMX6.

 

Também removemos alguns itens que são encontrados em imagens com ambiente desktop pois nossa imagem será uma imagem console.

 

Após a edição dos arquivos .conf, na pasta build executamos o comando (dentro da pasta build) para finalmente gerar a imagem:

 

 

 

Instalando a imagem no módulo

 

O processo de instalação de novas imagens no módulo está muito bem documentado no site de desenvolvedores da Toradex em Flashing Embedded Linux to iMX6 modules.

 

 

Testando a imagem final

 

Após o update da imagem no módulo, o linux deve iniciar e em seguida também veremos nossas aplicações iniciarem automaticamente.

 

Nas mensagens de boot podemos ver algumas mensagens dos nossos serviços:

 

 

Neste vídeo mostramos na prática o resultado deste artigo:

 

 

 

Conclusão

 

Esse artigo serve de base para se obter uma imagem linux para sistema embarcado totalmente customizada e pronta para ser usada em um produto. Foram vistos conceitos de git, layers e receitas. Muitos desses conceitos são usados por empresas como a Toradex, uma desenvolvedora de SBC, que disponibiliza o layer meta-toradex com vários recursos de desenvolvimento como Board Support Packages e etc. Quem sabe não é você, caro leitor, o próximo criador de imagens, layers e aplicações que vão revolucionar o mundo dos embarcados!

 

 

Referências

 

http://developer.toradex.com/how-to/how-to-set-up-qt-creator-to-cross-compile-for-embedded-linux

http://www.yoctoproject.org/docs/current/dev-manual/dev-manual.html#new-recipe-writing-a-new-recipe

http://playerstage.sourceforge.net/wiki/Cross_Compile_Player_with_Openembedded_and_BitBake#Player_Recipe

http://bec-systems.com/site/501/best-practices-for-building-qt-applications-with-openembedded

https://wiki.yoctoproject.org/wiki/Creating_a_recipe_for_a_Qt_application

https://wiki.yoctoproject.org/wiki/Building_your_own_recipes_from_first_principles

https://community.freescale.com/docs/DOC-94849

https://wiki.yoctoproject.org/wiki/How_do_I

http://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html

https://www.embarcados.com.br/beaglebone-black-qt5-yocto-parte-1/

https://www.embarcados.com.br/raspberry-pi-2-qt5-yocto-parte-1/

https://www.embarcados.com.br/yocto-project-primeiros-passos-poky/

https://www.embarcados.com.br/beaglebone-black-yocto/

https://www.embarcados.com.br/cozinhando-com-yocto-project/

https://opensource.org/licenses/MIT

http://choosealicense.com/licenses/mit/

http://www.freedesktop.org/software/systemd/man/systemd.service.html

https://wiki.archlinux.org/index.php/Systemd

https://coreos.com/os/docs/latest/getting-started-with-systemd.html

http://developer.toradex.com/knowledge-base/how-to-autorun-application-at-the-start-up-in-linux

http://www.embeddedlinux.org.cn/OEManual/recipes_examples.html

http://wiki.openmoko.org/wiki/BitBake_recipe

https://www.wolfssl.com/wolfSSL/Docs-beginners-guide-yocto-openembedded-recipe.html

NEWSLETTER

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

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Giovanni Bauermeister
É formado em Técnico em Mecatrônica pelo SENAI Roberto Mange de Campinas, onde teve seus primeiros contatos com microcontroladores, eletrônica e programação. Em 2016 obteve a graduação em Engenharia de Controle e Automação pela UNISAL, também em Campinas. Durante a graduação, teve a oportunidade de ingressar como estagiário na empresa Toradex, onde atuou e desenvolveu habilidades em sistemas Linux embarcado. Participou do movimento maker, contribuindo com tutoriais e suporte ao cliente na Filipeflop. Atualmente atua na área de desenvolvimento de projetos.

7
Deixe um comentário

avatar
 
2 Comment threads
5 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
4 Comment authors
Diego SueiroRaul MunozUlysses FonsecaCleiton Bueno Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Ulysses Fonseca
Visitante
Ulysses Fonseca

Giovanni, excelente artigo.
Como que posso remover esses pinguins que aparecem no boot da placa?

Raul Munoz
Visitante

Olá Ulysses,
Que bom que gostou.
Você quer remover só o Pinguins ou todo console?
Se for só o pinguim tem que recompilar o kernel sem imagem de boot.
Se for remover o log de boot do kernel acho q da para resolver só no u-boot. (enviroments).

Diego Sueiro
Visitante
Diego Sueiro

Ulysses,

Para remover a imagem do Tux você pode inserir o parâmetro "logo.nologo" no kernel command line através do u-boot.

https://www.kernel.org/doc/Documentation/kernel-parameters.txt

Raul Munoz
Visitante

Vocês tem razão. logo.nologo funciona! Acabei de testar.

Achei que tinha que recompilar o kernel pois a vez que trabalhei com algo parecido foi para colocar a spashscreen com o Logo da Toradex. Ai alterei conforme esse link aqui:

http://developer.toradex.com/knowledge-base/splash-screen-linux

Abs

Cleiton Bueno
Visitante

Olá Ulysses, edite o arquivo de configuração de ambiente das variáveis do U-boot, acionando em bootargs ou extraargs, conforme a necessidade abaixo:

logo.nologo -> Remove o logo do Tux ou o logo utilizado, sem necessidade de recompilar o kernel
quiet -> Modo "silencioso" no console durante o boot

Exemplo:

bootargs=root=/dev/mmcblk0p1 rw rootwait quiet
bootargs=root=/dev/mmcblk0p1 rw rootwait logo.nologo quiet

Caso deseje trocar o logo, ae deverá modificar e recompilar o kernel.

Ulysses Fonseca
Visitante
Ulysses Fonseca

Obrigado a todos, vou fazer os testes aqui. Eu já fiz todas as customizações na minha imagem, removi o log no boot. No caso só faltava remover o pinguim mesmo.

Cleiton Bueno
Visitante

Excelente artigo, parabéns!