Manual

do

Maker

.

com

Rodar aplicações gráficas no framebuffer do Raspberry

Rodar aplicações gráficas no framebuffer do Raspberry

Você pode caprichar o quanto quiser na sua aplicação, mas se tiver uma interface com o usuário, certamente ele dará um jeito de mexer onde não deve. É fato, o maior problema dos sistemas computacionais está na chamada "layer 8" do modelo OSI prático. Mas há uma maneira de obter controle total sobre o que o usuário pode fazer no sistema, como veremos nesse tutorial, ao rodar aplicações gráficas no framebuffer do Raspberry.

Dilema: Como fazer para o usuário não destruir o sistema?

Bem, uma das desmotivações em desenvolver projetos com Raspberry certamente é a interface com o usuário. Se tudo será automático, ótimo! Podemos programar em qualquer linguagem desejada, afinal, é um Linux que roda ali. Mas quando temos que desenvolver um projeto com a tal interface, aí entram diversas considerações, tanto em relação à segurança quanto à experiência do usuário. Não há dúvidas de que conquista-se o usuário pelos olhos, por isso hoje teremos esse artigo especial onde apresentarei uma solução para ser utilizada no Raspbian Minimal, sem desktop. Mas calma, a aplicação é gráfica!

Então, instalamos um sistema no Raspberry. Que interface oferecer? Uma janela em ncurses? Menu em dialog? Programar em Python com TkInter?

Escolhendo a linguagem de programação para o Raspberry

Eu sempre procuro a maneira mais prática, mas também a melhor estratégia. Se instalarmos um sistema completo desktop para usar no Raspberry, o usuário poderá acessar tudo o que o sistema tem, tanto pelo menu quanto pelo console. Pensando primeiramente em segurança, podemos considerar como uma ótima opção uma interface em Qt. Daí você pode se perguntar: "E o desktop?".

Rodar aplicações gráficas no framebuffer do Raspberry

O Raspberry utiliza um dispositivo de framebuffer, cujo dispositivo é o /dev/fb0. Não precisamos de interface gráfica para escrever nesse dispositivo, apenas precisamos escrever para ele de algum modo. Compilando o Qt para embedded com suporte ao LinuxFB, podemos executar o aplicativo em Qt diretamente do console (por favor, eu sei que em breve ele será substituído pelo DRM).  Com isso, resolvemos duas questões; criamos um "jail" para o usuário e oferecemos uma interface bacana!

Compilando o Qt nativo no Raspberry com suporte a framebuffer

Tendo já definido os parâmetros para iniciar um projeto em Raspberry, temos duas opções; cross-compiling ou compilação nativa. Sem dúvidas o cross-compiling é a melhor alternativa, pois podemos aproveitar o processamento de um desktop/notebook para gerar o binário, mas aí entram algumas questões; você tem Linux no seu notebook/desktop? Se não tiver e for virtualizar um Linux, pode não ser tão atrativa a solução.

Compilar nativamente no Raspberry lhe permitirá ter um ambiente de desenvolvimento para futuros projetos, bastando gerar o binário, recolher as dependências, gerar o instalador e transferir para outro cartão.

Se desejar fazer cross-compiling, sugiro o artigo "Cross-compiling para Raspberry". Existe uma terceira opção, que é a compilação nativa em ambiente virtualizado. Se quiser virtualizar um Raspbian para desenvolver nele, sugiro o artigo "Ambiente de compilação Raspberry com Raspbian".

Dos quase 650 artigos publicados, acredito já ter feito algo com compilação nativa, mas como não lembro, resolvi escrever um tutorial completo.

Compilando o Qt

Primeiro passo, devemos fazer o download dos fontes do Qt para algum diretório. No meu caso, criei o diretório qt-src no home do usuário pi. Entrei no diretório e fiz o download:

mkdir qt-src
cd qt-src
wget http://download.qt.io/official_releases/qt/5.12/5.12.3/single/qt-everywhere-src-5.12.3.tar.xz

Enquanto é feito o download, aproveite para instalar uma sacola de dependências:

sudo apt-get install rsync cmake lib32ncurses5 lib32z1 git \
binutils-multiarch libinput-bin libinput-dev libinput-tools \ 
libinput10 clang-6.0 libclang-6.0-dev bison flex gperf \
ffmpegthumbnailer ffmpegthumbs libffmpegthumbnailer-dev \
libglu1-mesa-dev libgl1-mesa-dev libmysql++-dev libsqlclient-dev

Você notará no decorrer do processo que vai demorar pra concluir esse tutorial.

Depois de baixado os fontes, descomprima-o e entre no diretório:

tar zxJf qt-everywhere-src-5.12.3.tar.xz
cd qt-everywhere-src-5.12.3

Agora devemos gerar o makefile com nossas definições. No caso, utilize os parâmetros:

./configure -opensource -confirm-license -linuxfb -webengine-embedded-build -no-opengl

Tem um bug que não permite a compilação completa especificando múltiplos núcleos, mas inicie a compilação assim para adiantar um pouco:

make -j4

O erro deve causar a paralização na estrutura de exemplos. Se parar por aí, ótimo. Agora repita o make sem a flag:

make

Pode anotar esse tutorial para continuar depois e volte a partir desse ponto depois de muitas horas.

Após a conclusão da compilação, é hora de instalar o resultado para o sistema. Use:

sudo make install

Baixar fonte TTF

O Qt não traz mais consigo fontes ttf. Baixe a DejaVu no diretório de fontes:

mkdir -p /usr/local/Qt-5.12.3/lib/fonts
chmod -R 0777 /usr/local/Qt-5.12.3/
cd /usr/local/Qt-5.12.3/lib/fonts
wget -c http://sourceforge.net/projects/dejavu/files/dejavu/2.37/dejavu-fonts-ttf-2.37.tar.bz2
tar xvjf dejavu-fonts-ttf-2.37.tar.bz2

Variáveis de ambiente

Algumas variáveis de ambiente são necessárias para configurar adequadamente o modo de operação do programa. Essa variáveis podem ser alocadas no arquivo ~/.bashrcda seguinte maneira:

export QT_QPA_FB_DRM=0 #1 para DRM
export QT_QPA_FB_HIDECURSOR=1
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0:size=800X480
#offset=<widht>X<height>

No caso, utilizando o fb0 do Raspberry com o tamanho de 800x480. Existe uma razão para isso, mas vou manter em segredo, no final do artigo comento a respeito.

Conexão remota

Agora tem duas possibilidades; uma é compilar esse projeto de framebuffer e executá-lo após rodar o programa. O outro, muito mais simples, é rodar o programa mudando a plataforma de linuxfb para **vnc.**Daí é só conectar com um client VNC ao Raspberry:

./qteste -platform vnc

Mas também podemos fazer o export do VNC e simplesmente rodar a aplicação assim:

export QT_QPA_PLATFORM=vnc:size=800X480
export QT_QPA_FB_HIDECURSOR=1
cd qteste #é o nome da janela vazia que criei como projeto de teste no notebook e copiei para o Raspberry
/home/pi/qt-src/qt-everywhere-src-5.12.3/qtbase/bin/qmake
make

./qteste -platform

Daí, conecta-se com um client VNC a partir de qualquer dispositivo que não seja o próprio Raspberry:

vncviewer 192.168.1.123

E deve abrir uma janela do tamanho definido:

qt-embedded-300x194.webp

Que janela horrível, não? Pois é, mas funcionou perfeitamente! O objetivo era provar o conceito.

Será necessário acertar as fontes TTF ainda, mas estou desenvolvendo uma interface para usar no Raspberry sem desktop instalado; isto é, o Raspbian Minimal, sem servidor gráfico. Desse modo, não haverá como o usuário fazer qualquer operação que não seja a permitida no software.

Corrigindo problema com fontes TTF

À primeira vista chega a perturbar o espírito ver algo que parece tanto com um bug, mas é só uma questão de configuração.

Já temos a fonte TTF no diretório citado mais acima. Dele, copiei o diretório ttf para a raiz do diretório de bibliotecas por comodidade, então defini a variável de ambiente necessária para que o programa saiba onde buscar a fonte. Exporte a variável antes de rodar a aplicação:

export QT_QPA_FONTDIR=/usr/local/Qt-5.12.3/lib/fonts/ttf

E ao rodar o programa agora, já temos um label e um botão:

qt-emb2-300x194.webp

 

Criando a aplicação

Agora é a melhor parte. No seu computador pessoal, não importa o sistema operacional, instale o QtCreator. Desenvolva sua aplicação e copie o projeto para o Raspberry. Daí é só fazer a compilação lá no Raspberry, utilizando o Qt que compilamos ao início do artigo.

No nosso canal DobitAoByteBrasil no Youtube tem alguns tutoriais de Qt, recomendo a visita. Aproveite para se inscrever, clique no sininho para receber notificações e acompanhe os próximos artigos relacionados.

A última observação que gostaria de fazer é que, repare na janela, não tem decoração (botões e bordas), de modo que o visual ficará melhor ainda para aplicativos de caixa de supermercado, centrais de controle etc.

O segredo

Eu defini essa resolução para o framebuffer porque assim que os correios decidirem trabalhar (privatiza, Guedes) deve chegar um material do nosso parceiro Baú da Eletrônica, dentre eles, esse magnífico display para Raspberry. Por isso já estou preparando a interface e esse tutorial é o material introdutório para criarmos uma aplicação especialista, que nos permitirá dar um visual mais profissional a nossos projetos com Raspberry.

Promoção maluca

Do dia 13 ao dia 20 o Baú da Eletrônica vai dar 30% de desconto em "todos" os produtos do site (exceto ferramentas), aproveite a oportunidade para fazer suas compras nesse período e ainda por cima frete grátis para compras acima de R$300,00!

Aproveite e passe no site!

Projetos para sua empresa

Manual do Maker é mais do que um blog. Somos uma empresa de serviços, cuja principal atividade é desenvolvimento e implementação de projetos embarcados e IoT. Trabalhamos dentro da legalidade, emitindo nota fiscal de serviço, elaboração de requisitos de sistema e documentação do código. Não importa onde você esteja, montamos a prova de conceito e gravamos vídeo do projeto antes de entregar o código e/ou hardware configurado.

Em parceria com a AFEletrônica, projetamos e produzimos hardware industrial (também com nota), para lhe entregar a melhor experiência para seu projeto.

Se precisar de treinamento para sua equipe, palestra, projetos com requisitos, perícia forense digital, consultoria, auditoria, software ou hardware, somos quem você procura! Entre em contato: vendas@afeletronica.com.br Ou direto comigo: djames.suhanko@gmail.com

Será um prazer tê-lo como nosso cliente!

Inscreva-se no nosso canal Manual do Maker no YouTube.

Também estamos no Instagram.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.