Arquitetura de software em camadas para iniciantes

Esta publicação tem como objetivo mostrar a quem está iniciando no mundo dos sistemas embarcados (sobretudo quem está iniciando em sistemas embarcados bare-metal) o que é uma arquitetura de software, a sua importância e que benefícios uma boa arquitetura de software pode proporcionar para o desenvolvimento, manutenção e evolução de um software. Em especial, vamos tratar de arquitetura de software em camadas.

 

 

Pré-requisitos

 

Recomendo que antes de ler este artigo você tenha uma noção de:

  1. O que é um gerenciamento de fila (FIFO, LIFO, etc.);
  2. O que é uma IDE e um microcontrolador (ou seja, onde você faz o projeto e onde ele vira um binário pronto para ser gravado em um microcontrolador);
  3. O que são funções / métodos.

 

 

O que é arquitetura de software embarcado e por que é importante?

 

Para responder essas perguntas, considere o caso a seguir. Para ilustrá-lo, o protagonista chama-se João, que é um desenvolvedor de software embarcado.

 

O chefe de João lhe solicitou que fosse desenvolvido um sistema embarcado bare-metal e está muito ansioso para fazê-lo. Logo de cara, no exato instante em que ele pisou fora da sala do chefe, sua mente parecia efervescer! Um turbilhão de ideias de como desenvolver o sistema surge e a única coisa que João deseja é chegar no seu computador e mandar ver no código para dar vida às suas ideias.

 

No auge de sua empolgação, ele conseguiu desenvolver o código-fonte de uma única vez, como um relâmpago. Porém, durante a escrita, ele não se preocupou em absolutamente nada quanto a comentários, modularização de código, identação de código, etc. Para agilizar ainda mais seu desenvolvimento, ele tomou uma sábia decisão para o momento: pegar na internet exemplos de como fazer tal parte do sistema. Assim, haverá uma coisa a menos para desenvolver! E, num ímpeto incontrolável, copiou e colou sem dó nem piedade o trecho de código da internet no código dele, sem ao menos questionar se funcionava ou ainda verificar se tinha alguma lógica (afinal, se está na internet deve funcionar, né?). João, para mostrar que é muito eficiente, antes mesmo dos testes, modificou as rotinas e as deixou mais rebuscadas, afinal toda obra deve ser uma obra prima, certo?

 

Enfim, para dar vazão às suas ideias e terminar o projeto o quanto antes (e passar a impressão de ser um funcionário eficiente), ele simplesmente foi lá e fez.

 

É chegada a hora da verdade: o primeiro teste! Agora João se sente como Tony Stark prestes a dar vida à armadura do homem de ferro, afinal ele fez algo que lhe foi solicitado e fez rápido. Eis que o pior acontece: tudo que se é possível imaginar acontece, exceto funcionar. João desconfia de tudo: do hardware, do compilador, do Windows e, se bobear, até do que os seus olhos estão vendo. Em desespero, sai correndo mexendo em código e arrumando. Em resumo: João gastará no mínimo duas vezes o tempo previsto para realizar a tarefa.

 

Parece exagero a história, não? Acedite, se você não se preocupar com arquitetura de software, a grande maioria do que foi citado ocorrerá em 10 de 10 projetos que você desenvolver. Desenvolver rápido e metralhando código sem pensar e planejar e utilizando códigos de terceiros sem questionar ou ao menos testá-los isoladamente pode parecer eficiente em tempo (fazer certo visando somente o tempo de desenvolvimento), mas não é nada eficaz (ou seja, não é feita a coisa certa). Logo, se o João fosse também eficaz, tudo ficaria melhor.

 

Então vem a pergunta: o que é afinal arquitetura de software?

  • Definição formal: A arquitetura de software de um sistema consiste na definição dos componentes de software, suas propriedades externas, e seus relacionamentos com outros softwares;
  • Na prática: Arquitetar um software é organizá-lo de forma a ser o mais eficiente E eficaz possível.

 

Ou seja, o segredo de um bom software é a organização, mesmo quando importa-se códigos de terceiros (neste caso, cuidado redobrado e muito critério são necessários!). Utilizar uma arquitetura de software bem definida num projeto é fazer um software não necessariamente da maneira mais fácil e confortável, mas sim da forma que tenha melhor performance e que seja fácil de dar manutenção e evoluí-lo. Sim, todo projeto evolui (ganha funcionalidades e novas aplicações). Acredite, se não for definida uma boa arquitetura de software num projeto, a sensação de evoluí-lo é como se estivesse tentando sair da areia movediça: quanto mais você mexe, pior fica.

 

Meus amigos, aqui temos a primeira realidade do mundo dos sistemas embarcados: organização é tudo!

 

 

Afinal, como organizar um software embarcado?

 

Pois bem, a história acima serviu para ilustrar o que NÃO se deve fazer. Vejamos agora uma das formas corretas de como se organizar um software embarcado.

 

Em 99,999% das vezes, um software embarcado terá que interagir com baixo nível (interagir com periféricos ou outros sistemas embarcados, a nível de bit e bytes) e alto nível (reportar dados, status e realizar operações para uma camada de aplicação, mais próxima do usuário final). Logo, o primeiro passo para se adotar uma boa arquitetura de software embarcado é dividir de forma clara e objetiva as camadas do mesmo, fazendo, claro, uma comunicação clara e objetiva entre as camadas (por meio de funções / métodos / mensagens bem definidas e versáteis).

 

 

Arquitetura de software em camadas

 

As camadas mais “baixas” (que interagem a nível de byte e bit, conversam com periféricos, lidam com pilhas de comunicação mais robustas) são chamadas de camadas mais especialistas, enquanto as camadas acima, que conversam mais com aplicações, são chamadas camadas menos especialistas. Observe a figura 1, a qual ilustra um exemplo de divisão de camadas da comunicação TCP/IP.

 

Software em camadas do TCP/IP
Figura 1 - Camadas simplificadas do TCP/IP

 

Desta figura podemos concluir, por exemplo, que a camada de aplicação (a camada menos especialista desse diagrama) não precisa “conhecer” como as camadas abaixo funcionam, porém ela se comunica por meio de mensagens claras e objetivas com a camada imediatamente inferior (Transporte). Assim como a camada de acesso à rede está preocupada em manter o canal de comunicação estável e seguro (do ponto de vista elétrico, sem risco de colisões de dados e coisas do gênero), ela precisa atender às solicitações da camada superior.  Em resumo, é como se uma operação/trabalho fosse dividido em vários programas diferentes, cada qual com sua finalidade e objetivos.

 

 

Vantagens de separar o software em camadas

 

Mas afinal, quais são as grandes vantagens deste formato de organizar um software? Veja a seguir: 

  • Separando em camadas, pode-se fazer o desenvolvimento de um sistema em etapas. Com isso, além da organização, ganha-se tempo e performance (por mais poderosos que microcontroladores sejam, ganhar microssegundos faz toda a diferença no mundo dos embarcados!);
  • Desenvolvendo desta maneira, o software das camadas tendem a ser mais limpos, facilitando o entendimento futuro do software;
  • Caso algum bug surgir, neste tipo de organização de software é mais fácil encontrá-lo e eliminá-lo, pois como as camadas são bem “isoladas” (focadas em funcionalidades específicas), fica relativamente simples descobrir em qual camada o bug está (por conseqüência, o tempo de debug diminui);
  • Por último e não menos importante: organizando em camadas é possível substituir uma camada inteira por outra sem comprometer o sistema todo. Um exemplo disso é o próprio TCP/IP. Se for necessário trafegar os dados via Wi-Fi ou cabo (ethernet, por exemplo), basta alterar a camada mais especialista, já que as camadas acima comunicam-se com mensagens / métodos / funções que independem do canal de transmissão. Com isso, o código ganha versatilidade.

 

Sim meus amigos, se as camadas forem bem definidas, será quase como brincar de Lego!

 

Portanto, se o João da história contada no início desse artigo tivesse dividido o software dele em camadas, talvez não tivesse tantos bugs e, caso tivesse, facilmente identificaria onde eles estão.

 

Ok, tudo muito bonito, mas e no código? Como fica este tipo de arquitetura de software em camadas? Aqui começa a mão na massa em termos de código. Note que até agora somente foi arquitetado/pensado quais camadas o sistema terá, quais serão as suas funcionalidades e quais as funções/métodos/mensagens necessárias.

 

Esta é a segunda grande realidade do mundo do software embarcado: escrever código é a menor de suas preocupações. O mais importante é pensar em como tudo funcionará.

 

Para exemplificar uma divisão de camadas eficiente e eficaz, consideremos o seguinte exemplo: um sistema embarcado que comunica-se com um módulo bluetooth, capaz de conectar-se a um dispositivo alvo (fornecendo-se um MAC address), enviar e receber dados e ter uma interface amigável de entrada e saída de dados (um teclado e display).

 

Percebe-se que temos três camadas neste sistema:

  1. Camada menos especialista: camada que contém rotinas de interface, ou seja, rotinas de display, teclado e ações a serem realizadas;
  2. Camada intermediária: contém o tratamento das solicitações das camadas menos especialistas e mais especialistas, além do gerenciamento das mensagens recebidas e das que devem ser enviadas às outras camadas (organização das mesmas em filas tipo FIFO, por exemplo);
  3. Camada mais especialista: composta do “rádio” (canal de transmissão do bluetooth) e comandos ao hardware bluetooth (bem como interpretar suas respostas).

 

Ou seja, nosso terminal bluetooth, de forma simplista, teria a seguinte estrutura:

 

Software em camadas - Bluetooth
Figura 2 - Estrutura do Bluetooth

 

De forma simplista, aí está a organização em camadas de um terminal serial deste nível. Há pontos importantes a serem ressaltados, como por exemplo: 

  • Cada módulo ficou focado em uma tarefa macro / em um tipo de gerenciamento. Logo pode-se dividir-se o desenvolvimento em etapas (o que minimiza o tempo de desenvolvimento);
  • Se, no futuro, for necessário substituir o canal de transmissão de bluetooth para ethernet, por exemplo, basta substituir a camada mais especialista. Assim como se for necessário alterar o tipo de display, basta alterar somente a camada menos especialista.

 

Em termos de código, que é o objetivo deste tópico, há dois caminhos: 

  1. Em compiladores e IDEs mais modernos, é possível separar o projeto em vários arquivos de código-fonte. Isto é ótimo nesta metodologia de software em camadas, pois neste caso bastaria fazer cada camada em um arquivo fonte (ou um arquivo fonte e um de cabeçalho, dependendo da linguagem escolhida);
  2. Em compiladores e IDEs mais antigos, é necessário fazer o famoso “código linguição” (tudo em um só fonte). Neste caso, deve-se agrupar as camadas em funções, tomando cuidado redobrado com os nomes das funções e documentação/comentários.

 

Sim, parece besteira, mas dar nomes intuitivos às funções faz toda a diferença na hora de desenvolver, dar manutenção e evoluir. Recomendo fortemente adotar um padrão de nomenclatura e seguí-lo em todo o código, isso torna as coisas mais fáceis para você e para quem for trabalhar no código no futuro.

 

Como pode ser observado, cada camada possui funções que interagem com outras camadas. Logo, tais funções devem ter escopo global.

 

É plenamente válido (e recomendo em muitos casos) o uso de bibliotecas consagradas para “conversar” com hardwares específicos (de preferência bibliotecas fornecidas por fabricantes dos próprios hardwares). Porém, tais bibliotecas não foram desenvolvidas seguindo sua arquitetura e nomenclatura, logo deve-se tomar muito cuidado ao colocá-las no seu sistema. Com isso, temos a terceira realidade do mundo dos sistemas embarcados: critério na importação de código terceiro é fundamental.

 

 

Conclusões

 

Resumindo tudo o que foi dito, uma boa arquitetura de software é aquela que permite seu software ficar organizado de forma que seja possível desenvolvê-lo, mantê-lo e evoluí-lo de forma bem definida. Para isto, foi apresentada a forma de arquitetura de software em camadas.

 

As camadas vão da menos especialista (mais próxima do usuário final) até a mais especialista (a camada que “conversa” com o hardware, a nível de bits e bytes, sendo que em caso de evolução ou alteração de software, basta alterar ou substituir camadas específicas sem comprometer o resto do sistema.

 

 

Saiba mais sobre arquitetura de software em sistemas embarcados

 

Estruturação de dados e mensagens entre camadas para iniciantes

Arquitetura de desenvolvimento de software

Projetos de Desenvolvimento: Primeiros passos

Boas práticas para o desenvolvimento de software

Referências

 

Créditos da imagem de destaque:  https://edmilsonsg.wordpress.com/2012/04/03/arquitetura-da-informacao/

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

2
Deixe um comentário

avatar
 
2 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Jonathan GonzagaArquitetura de Software em Sistemas Embarcados Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Jonathan Gonzaga
Visitante
Jonathan Gonzaga

Posso utilizar esse método de software em camadas juntamente com uma máquina de estados?

trackback

[…] Arquitetura de software em camadas para iniciantes […]