Android embarcado: primeira aplicação em C nativa

O Android é, sem sombra de dúvidas, um dos sistemas operacionais mais dominantes do mundo. Ele está presente em smart phones, tablets, smart TVs, smart watches, veículos, etc., fazendo assim parte do nosso cotidiano. Uma das razões desta popularização massiva do Android foi o fato do mesmo ser open-source: ou seja, o código-fonte do Android "mais puro" / sem customizações dos fabricantes é disponibilizado na forma open-source, sendo ele chamado de AOSP (Android Open-Source Project). Logo, o que os fabricantes de dispositivos que utilizam o Android fazem é aproveitar o máximo possível do AOSP, customizando as partes baixo-nível (para adaptar o Android ao hardware desejado) e criando aplicações proprietárias em alto-nível (utilizando para isso recursos do rico Framework Android).

 

Dada sua grande possibilidade de customização e sua popularidade, concluí-se que o desenvolvimento de aplicações para o Android seja um mercado fértil e alinhado com as mais recentes inovações em termos de software. Este artigo ensinará o passo-a-passo de como desenvolver sua primeira aplicação em C nativa o Android, bem como o conteúdo básico para se orientar no AOSP (Android Open-Source Project).

 

Este artigo foi fortemente baseado no treinamento Android Embarcado, ministrado pela empresa Embedded Labworks. Aos que almejam ser profissionais no mercado de Android Embarcado, recomendo a realização do treinamento.

 

Pré-requisitos

 

Para compreender e conseguir reproduzir o projeto aqui proposto, você deve:

  • Ter certa vivência com Linux (dominar os comandos mais comuns);
  • Ter bom conhecimento em programação C em Linux (escrita de programas, leitura de códigos-fontes de diversas complexidades e noções de estruturação de um makefile);
  • Possuir conhecimentos básicos de comunicação com sistemas Android via ferramenta adb.

 

Em termos de software, você precisará ter instalado no computador host (que irá fazer as compilações):

  • Ferramentas para comunicação com Android. Se quiser instalar todas de uma vez e ainda ter um ambiente preparado para desenvolvimento futuro de aplicações Android baseadas no seu Framework, instale o Android Studio;
  • O computador que fará as compilações deverá ter como sistema operacional Ubuntu 14.04 64-bits;
  • O computador que fará as compilações deverá ter como requisitos mínimos de hardware: processador com oito núcleos/cores, memória RAM de 16 GB e grande espaço em disco (recomendo 100 GB no mínimo). Preferencialmente, o disco-rígido deve ser do tipo SSD (faz enorme diferença no desempenho das compilações aqui exigidas).

 

Considerações iniciais

 

O Android Embarcado (e seu desenvolvimento em si) possui alguns pontos de atenção:

  • AOSP: o AOSP (Android Open-Source Project) consiste, basicamente, no código-fonte do Android. Ele é fornecido pelo Google e mantido com a ajuda da comunidade, o que faz com que evoluções sejam uma constante.
  • É preciso de um computador com configurações de hardware muito boas: para compilar o Android é altamente recomendável utilizar como computador host um computador com, no mínimo, 16 GB de RAM e com um SSD (de 250 GB ou mais de capacidade). O processo de compilação é muito pesado. Como alternativa, pode-se alocar uma VPS para servir de build-server, atentando-se às configurações mínimas exigidas para a compilação.
  • Utilize como sistema operacional de seu computador host o Ubuntu 14.04: este sistema operacional já está bem consolidado para compilação de builds Android. Não é aconselhável a utilização de versões diferentes.
  • Apesar de se poder compilar o Android com o AOSP, não se pode diretamente gravar a versão que você compilou em seu dispositivo: o AOSP se comporta como uma espinha dorsal do Android, ou seja, é a base de tudo em se tratando de Android, porém sozinha não é suficiente para gerar um Android para um dispositivo qualquer. O processo de portar um Android para um device (o que é feito pelos fabricantes) é algo extremamente dependente do hardware do dispositivo e, além disso, exige customizações de software a nível de Kernel, algo não trivial para um iniciante em Android Embarcado.
  • A documentação é pobre, exigindo muita leitura de código: infelizmente, a documentação do Android é pobre: não acredito ser possível, somente com os guias para desenvolvimento do Google, entender das inúmeras partes do Android com grande nível de detalhamento. Logo, se almeja trabalhar com Android Embarcado, ter proficiência em ler códigos em C e Java faz grande diferença para entender como o sistema operacional funciona.
  • O Android não possui forte padronização: infelizmente, padronização de documentação em geral não é um ponto forte do Android. Por essa razão, o aprendizado pode parecer um pouco mais lento do que se espera. Um dos possíveis motivos disso é o grande número de pessoas contribuindo para o AOSP, gerando um crescimento muito grande em funcionalidades e deixa a desejar na documentação das features implementadas.
  • A comunidade será sua grande aliada: você deve contar com a comunidade para aprender e ver soluções de bugs conhecidos do Android. Portanto, frequentar foruns e listas de discussão sobre o assunto é uma boa prática.
  • O Android possui sua própria lib C e sistema de build C: o Android não utiliza as bibliotecas nem sistemas de build C padrão do Linux. Por exemplo, como lib C, ele faz uso da bionic. A razão disso é um tanto quanto obscura, mas um palpite seria a economia de recursos computacionais e otimização do consumo de bateria.

 

Overview - Android Embarcado e AOSP

 

Antes de mais nada, é necessário se habituar com conceitos básicos de arquitetura e ferramentas de desenvolvimento do AOSP. 

 

O Android é semelhante ao Linux?

 

De início, é importante ter em mente que o Android é baseado no Linux. A semelhança com o Linux se dá na questão dos sub-sistemas/componentes envolvidos (bootloader, kernel e file system) e por grande parte do Kernel Android ser uma customização do Kernel Linux. E para por aí. Ou seja, o Android é semelhante em algumas coisas ao Linux em questões mais internas/baixo-nível, para coisas em um nível mais alto (como estrutura de pastas e mecanismos de inicialização automática de serviços, por exemplo), a semelhança com o Linux acaba. 

Aqui vale ressaltar que os comandos Linux presentes no Android são um subset dos comandos disponíveis no Linux por padrão. Para ter acesso à grande maioria dos comandos padrão do Linux, é preciso utilizar algo adicional, como por exemplo o BusyBox.

Arquitetura do AOSP/Android

 

Em termos de arquitetura de software o Android pode ser representado pela figura 1. Nela, é possível observar que o que chamamos de Plataforma Android propriamente dita (ou seja, o que desenvolvedores alto-nível de aplicações que utilizam framework do Android) é a parte com maior nível de abstração (de biblitecas, daemons e tools para cima). O restante, apesar de ter suas peculiaridades, é fortemente baseado no Linux.

 

Arquitetura de software do Android
Figura 1 - Arquitetura de software do Android

 

Em termos de diagrama de blocos, a divisão entre as camadas do Android pode ser representada pela figura 2. Nela, se destaca a questão do Kernel Linux (baixo-nível) e do muito rico framework de aplicação (alto-nível), o qual permite o desenvolvimento de aplicações altamente portáveis e versáteis (interagindo facilmente com recursos do dispositivo Android em questão). O projeto deste tutorial será ambientado no nível mais baixo, chamada de camada nativa ou, no diagrama, de Linux Kernel.

 

Diagrama de blocos das distintas camadas de software do Android
Figura 2 - Diagrama de blocos das distintas camadas de software do Android

 

Onde obter o AOSP? E como ele é composto?

O código-fonte do AOSP pode ser obtido em: http://source.android.com/source/index.html

 

O AOSP é versionado através do git, mas por ser formado por centenas (quem sabe, até milhares) de repositórios distintos, o Google criou uma ferramenta chamada repo para gerenciar todos estes repositórios necessários ao AOSP. Para instalar tal ferramenta, siga os passos abaixo:

 

  1. Crie um diretório chamado bin no seu home e entre neste diretório:

  2. Baixe a ferramenta com o comando abaixo:

  3. Modifique as permissões para todos os arquivos de ~/bin/repo:

  4. Por fim, acrescente a sua variável de ambiente PATH o caminho para o diretório bin:

 

Nesta ferramenta, quem rege quais repositórios irão compor o AOSP é um arquivo chamado manifest.xml. Inclusive, uma das primeiras etapas de customização dos fabricantes que embarcam o Android em seus produtos é filtrar quais repositórios devem e não devem compor a base do AOSP desejada.

 

Como obter o AOSP?

 

Para obter o AOSP, siga os passos abaixo:

  1. Crie em seu home um diretório para baixar o código-fonte do AOSP e entre neste diretório. Supondo que tal diretório se chame android_aosp_source_code, execute o seguinte comando:

  2. Faça o repo init. O repo init consiste em baixar o manifest.xml em um diretório oculto .repo, além de preparar o terreno para baixar os repositórios (algo a ser feito no próximo passo).

  3. Uma vez feito o repo init, tudo está preparado para baixar de fato os repositórios (listados no manifest). Para isso execute o comando repo sync e aguarde (o download demora bastante, uma vez que pode vir mais de 30 GB de conteúdo).

 

Compilação do AOSP

 

Assim que a execução do repo sync for terminada, todo o código-fonte do AOSP já está à sua disposição. Agora, o próximo passo é compila-lo. A compilação do android é formada de duas etapas distintas: preparação do ambiente de compilação (onde as variáveis de ambiente necessárias são configuradas) e a compilação de fato.

  • Preparação do ambiente de compilação: para isso, é utilizado um script para preparação das variáveis de ambiente e uma ferramenta (já contida no AOSP) chamada lunch para se escolher para qual dispositivo o AOSP será compilado e o tipo de Android a ser compilado (como, por exemplo, o tipo eng: um Android com privilégios de engenharia/root). Portanto, para preparar o ambiente de compilação, esteja na pasta em que o código-fonte do AOSP foi baixado (este artigo faz a suposição que esteja em ~/android_aosp_source_code) e execute o comando abaixo:


    Agora é a hora de se escolher o dispositivo-alvo (target, no jargão de cross-compiling) e tipo de compilação de Android (build) com a ferramenta lunch. Como aqui buscamos testar tudo em emulador e não pretendemos criar uma build com restrições de execução e acessos, será escolhido como target uma plataforma genérica em modo eng. Para isso execute o comando abaixo e escolha a opção correspondente a aosp_arm-eng.

  • Compilação do AOSP: para compilar, faça o make. É altamente recomendável que você especifique o máximo número de jobs possíveis (atributo atrelado ao processador do computador host/que irá compilar). Para um computador com processador de 8 núcleos/cores, um bom número de jobs é 4.

    A compilação é um processo demorado e com desempenho altamente dependente da quantidade de memória RAM disponível e tipo de disco-rígido do computador host. Portanto, a compilação pode demorar bastante.

 

Ao final do processo de compilação, a build Android (por build, entenda "conjunto de arquivos oriundos da compilação do AOSP") estará disponível em: ~/android_aosp_source_code/out/target/product/generic/

 

Emulação do AOSP

 

O AOSP já vem com um emulador, o que facilita muito testes e desenvolvimento com Android Embarcado. Este emulador consiste no qemu customizado para rodar builds Android. Antes de utilizá-lo, assegure-se de ter rodado o script de preparação de variáveis de ambiente. Isto é importante para que o emulador saiba qual plataforma emular e onde está a build Android compilada.

Feito isso, basta utilizar o comando abaixo para emular o Android que você compilou:

O emulador ainda dá acesso, via adb, ao console do Android.

 

Construindo sua primeira aplicação C nativa do Android

 

Uma vez com o código baixado, compilando e apto a rodar no emulador, está tudo pronto para ser iniciado o desenvolvimento de sua primeira aplicação em C para rodar na camada nativa do Android. 

 

Considerações sobre compilação de aplicações nativas no Android

 

A compilação de qualquer aplicação / módulo nativo no Android é feita junto com a compilação do Android ou separadamente (e, posteriormente, adicionada às respectivas imagens na build Android final). O Android tem seu próprio sistema de build, o que significa dizer que o programador não pode "mandar" o Android compilar algo com parâmetros específicos, mas sim deve se limitar a escrever o código-fonte da aplicação e um makefile para a mesma. Obrigatoriamente, todos os makefiles de aplicações nativas no Android devem se chamar Android.mk. No geral, makefiles com nomes diferentes são incluídos, em algum ponto, por algum makefile chamado Android.mk.

 

Projeto da primeira aplicação em C nativa no Android

 

Esta aplicação, para fins de exemplo, será um Hello World. Para isso, siga o procedimento abaixo:

  1. Assumindo que você esteja com o código-fonte do AOSP baixado em ~/android_aosp_source_code, vá até o diretório device/generic/aosp_arm:

  2. Neste diretório, crie um diretório específico para sua aplicação. Aqui será considerado o nome hello_world como nome do diretório:

  3. Crie no diretório específico da sua aplicação (ou seja, o diretório ~/android_aosp_source_code/device/generic/aosp_arm/hello_world) um arquivo chamado hello_world.c (código-fonte de sua aplicação C) com o seguinte conteúdo:

  4. Agora, é hora de criar o makefile de sua aplicação. Para isso, no mesmo diretório (~/android_aosp_source_code/device/generic/aosp_arm/hello_world), crie um arquivo Android.mk com o seguinte conteúdo:

  5. Agora, é preciso especificar que sua aplicação deve estar presente na build Android a ser compilada, uma vez que ela foi definida como opcional. Para isso, edite o arquivo ~/android_aosp_source_code/device/generic/aosp_arm/common.mk de forma a adicionar o seguinte trecho após a definição original de PRODUCT_PACKAGES:

    Observação: infelizmente, nomes de makefiles podem sofrer alterações de tempos em tempos (devido à falta de padrões no AOSP em alguns aspectos). Se o makefile mmi_common.mk não existir neste diretório, o makefile correspondente (neste mesmo diretório) é aquele onde é definido o PRODUCT_PACKAGES (só haverá um makefile nesta pasta com esta definição).

  6. Pronto! Agora basta compilar o AOSP (conforme explicado no tópico "Compilação do AOSP" deste artigo) e a sua aplicação já estará contida na build Android compilada.

 

Testando a aplicação desenvolvida

 

Finalmente, é hora de testar a aplicação desenvolvida rodando na build Android compilada. Para isso, siga o procedimento abaixo:

  1. Execute o emulador (veja como no tópico "Emulação do AOSP" deste artigo.
  2. Comunique-se com o Emulador através da ferramenta adb.
    Para isso, execute o comando adb wait-for-devices no terminal Linux de seu computador host. Assim que a execução do comando for terminada, execute o comando adb devices e certifique-se que o emulador Android consta na lista de dispositivos exibida.
  3. Execute o comando abaixo para abrir uma sessão de terminal com o Android do emulador:

  4. Execute a sua aplicação pelo seu nome (no caso, o makefile construído neste artigo a nomeia como hello_world).

     

Considerações finais

 

O Android é um sistema operacional dominante, sendo parte integrante de muitos dispositivos que utilizamos rotineiramente, como, por exemplo: smart phones, tablets, smart TVs, smart watches e veículos. Além disso, é um sistema operacional, em essência, open-source, o que faz com que sua aplicação e evolução aumentem exponencialmente.

 

Porém, talvez devido ao crescimento exponencial de desenvolvedores e ferramentas para o Android, o AOSP (Android Open-Source Project) possui um grande ponto negativo: documentação fraca. Isso dificulta o aprendizado rápido e força a leitura de códigos-fonte para completo entendimento do funcionamento de um módulo. Apesar disso, é um sistema com arquitetura muito bem definida e robusta.

 

Para os que almejam conhecer mais do sistema operacional Android e, também, ser um profissional do ramo, aconselho a realização do Treinamento Android Embarcado, da Embedded Labworks. Este treinamento, ministrado pelo Sergio Prado, é seguramente o mais completo do país no segmento, sendo um ótimo primeiro-passo para aqueles que querem trabalhar com Android Embarcado.

 

Saiba mais

 

Iniciando com a plataforma Android Things

Cross-compilação de programas estáticos para Android

Compilando o Android para a BeagleBone Black

 

Referências

 

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.

Pedro Bertoleti
Sou engenheiro eletricista formado pela Faculdade de Engenharia de Guaratinguetá (FEG - UNESP) e trabalho com Android embarcado em Campinas-SP. Curioso e viciado em tecnologia, sempre busco me aprimorar na área de sistemas embarcados (modalidades bare-metal, RTOS, Linux embarcado e Android embarcado). Para mais informações, acesse minha página no Facebook:https://www.facebook.com/pbertoleti

4
Deixe um comentário

avatar
 
2 Comment threads
2 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
Aleksandro MatosPedro BertoletiRonaldo Nunez Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Aleksandro Matos
Membro
Aleksandro Matos

Pedro, artigo sensacional.
Uma pena o AOSP exigir tanto hardware. Assim facilitaria a vida de um curioso como eu tentar se aventurar.
Novamente parabéns pelo artigo. Muito didático.
Abraços!

Ronaldo Nunez
Visitante
Ronaldo Nunez

Parabéns pelo artigo, Pedro. Muito didático. Vou por na lista de coisas para aprender. 🙂