Arquitetura de Software em Sistemas Embarcados

arquitetura de software

Antes de entrarmos na discussão sobre arquitetura de software em sistemas embarcados, precisamos entender outros pontos. Quando um projeto é imaginado e validado conceitualmente e comercialmente, uma sequência de atividades pré-definidas dentro do processo adotado pela equipe são executadas. Podemos listar algumas:

  • O projeto é iniciado por meio de uma reunião de kick-off ou um simples e-mail;
  • Uma declaração de escopo é definida, contendo tanto características, restrições (técnicas, financeiras, comerciais, de sistemas, etc) e requisitos de produto. Quando existe uma clara visão do projeto desde o seu início, é possível que existam, também, requisitos de software já bem concisos;
  • Requisitos de software são mapeados tendo em vista a declaração de escopo descrita anteriormente. Cada item desse documento pode gerar um ou mais requisitos de software;
  • E o projeto deve ser efetivamente desenvolvido!

 

Assumindo que os requisitos foram muito bem elaborados, esse desenvolvimento pode ocorrer de uma forma organizada ou descentralizada. E é neste ponto, não nos preocupando com a elucidação dos requisitos, que devemos nos atentar em como garantir que cada um dos requisitos definidos para o projeto foram implementados.

 

Portanto, temos dois grandes grupos de preocupações:

  • O que o sistema deve fazer?
  • E como ele deve implementar todos os requisitos?

 

Para responder à primeira pergunta, a disciplina de Gerenciamento de Requisitos e Gerenciamento de Configuração e Mudanças nos ajudam. Já a segunda resposta é obtida por meio da Arquitetura de Software ou Sistema do projeto.

 

O objetivo deste artigo é destacar a importância da arquitetura de software de um projeto de sistema embarcado e ajudar a responder à segunda pergunta acima. Pois bem, o que é arquitetura de software? Para que serve? Por que requisitos não-funcionais são importantes? Responderemos a essas questões a seguir!

 

 

Onde tudo começa?

 

Um projeto de software deve atender requisitos, os quais são divididos em dois grandes grupos:

  • requisitos funcionais e;
  • requisitos não-funcionais ou qualidades.

 

De forma resumida, os requisitos funcionais definem o que o sistema deve fazer, ao passo que as qualidades ditam como o sistema deve ser. Esses últimos são a base da arquitetura de software do projeto. Explicar como fazer para elucidar todos os requisitos do projeto não é o objetivo deste artigo. Algumas alternativas são: entrevista com o cliente; análise de negócio; análise do problema, encontrando causas raízes e soluções para tal; estudo das soluções similares; etc. Como base, veja a ótima série Projetos de desenvolvimento: Antes de começar do Henrique Puhlmann.

 

 

Qualidades

 

Qualidades, também conhecidas como atributos de qualidade, requisitos não-funcionais, requisitos não-comportamentais, etc, auxiliam na implementação das funcionalidades do sistema. Dentre as qualidades existentes, pode-se citar: usabilidade, desempenho, modificabilidade, segurança, testabilidade, etc.

 

Embora algumas qualidades e funcionalidades sejam intimamente ligadas, as últimas ganham muito mais foco que as primeiras na etapa de desenvolvimento, o que prejudica a visão de futuro do sistema. Dada uma modificação pedida pelo cliente, o que menos se deseja é que o sistema seja redesenhado. Caso isso seja necessário, é um sintoma de que o projeto possui baixa manutenibilidade, baixa modificabilidade ou baixa escalabilidade, horizontal ou vertical.

 

 

O que é arquitetura de software?

 

Pelo fato de arquitetura de software ser uma disciplina em crescimento, e ainda muito jovem, não existe uma definição única para ela. A discussão sobre essa definição é muito extensa, já que existem diferentes pontos de vista envolvidos. A definição com a qual concordo é a seguinte:


The software architecture of a program or computing system is the structure or structures of the system, which comprise software elements, the externally visible properties of those elements, and the relationships among them.” [1]

 

Na definição acima são mencionados elementos, estruturas, propriedades e relacionamentos. Cada elemento possui uma implementação privada, que contém suas propriedades, e uma interface pública que, por sua vez, propicia relacionamentos com outros elementos. E o conjunto desses elementos forma uma estrutura. Desse modo, pode-se entender a arquitetura de software como uma abstração do sistema que omite detalhes dos seus elementos, ou seja, suas partes privadas, focando na representação e relação das estruturas envolvidas.

 

As partes privadas dos elementos não afetam como esses usam, são usados por ou interagem com os outros elementos do sistema. Portanto, a definição de qual estruturas de dados devem ser utilizadas e encapsuladas não é uma decisão arquitetural, ao passo que as interfaces com tais estruturas de dados faz parte da arquitetura do projeto.

 

Muito bem, eu sei que preciso atender um conjunto de requisitos não-funcionais, muito bem conhecidos, o que fazer então? Para cada problema existe uma solução! Para isso são usadas táticas, que são decisões arquiteturais que influenciam na resposta dada por um sistema com relação a uma ou mais qualidades. Como exemplo de tática para se obter disponibilidade no sistema, pode-se citar detecção de falhas, onde implementações de ping/echo, heartbeat e/ou tratamento de exceções são encontrados.

 

Geralmente são adotados padrões arquiteturais. Esses implementam um pacote de táticas já conhecidas e são, em sua essência, frameworks arquiteturais, descritos por meio de um conjunto de componentes computacionais, ou simplesmente componentes, e das interações que esses realizam entre si, denominadas conectores. De modo visual, pode-se entender a arquitetura de software de um sistema como um grafo no qual seus vértices representam os componentes e suas arestas interpretam os conectores. Tais conectores podem representar chamadas à funções, eventos, queries de banco de dados, etc.

 

Desse modo, um padrão arquitetural define:

  • um conjunto de elementos (componentes);
  • uma topologia estrutural de seus elementos;
  • um conjunto de mecanismos de interações (conectores) e;
  • um conjunto de restrições semânticas para seu uso.

 

Existem diversos padrões arquiteturais (abstração de dados e organização orientada a objetos ou eventos, repositórios, sistemas distribuídos, etc), mas um dos mais utilizados em sistemas embarcados é o de sistema em camadas. Um sistema desse tipo é organizado hierarquicamente, de modo que cada camada ofereça serviços para a camada acima e atue como um cliente para a camada logo abaixo. Geralmente as interações entre as camadas são realizadas por meio de chamadas de funções. Veja a Figura 1 um exemplo de diagrama de uso numa arquitetura de software desse tipo.

 

Arquitetura de Software: Exemplo de sistema em camadas.
Figura 1 - Exemplo de sistema em camadas.

 

Esse tipo de padrão é seguido pois ajuda a oferecer ao projeto qualidades muito importantes, tal como modularidade, coesão e encapsulamento. Cada camada tem uma função muito bem definida. Por exemplo, qualquer parte da aplicação não deve fazer acesso direto ao driver de um dispositivo, delegando essa responsabilidade a uma camada intermediária, conhecida como middleware ou serviço. Dessa forma, deve ser estabelecida uma interface entre cada uma das camadas.

 

Dado o conceito, é interessante utilizar um exemplo de projeto para especificar a sua arquitetura de software. A Figura 2 nos auxilia nesse sentido, mostrando como o sistema é visualizado pelo seu usuário.

 

Arquitetura de Software: Diagrama de entrada/sistema/saída do projeto.
Figura 2 - Diagrama de entrada/sistema/saída do projeto.

 

 

Requisitos do projeto

 

Foi definido que o sistema trata-se da placa STM32F4Discovery, o qual deve tratar algumas ações do usuário:

  • Clique de um botão;
  • Movimento por meio de um acelerômetro;
  • Comandos seriais por meio de uma porta UART.

 

Dadas essas ações/informações, reações devem ser executadas pelo sistema. Para isso foi preparada uma lista dos requisitos desse projeto que estamos preparando como exemplo:

  • O sistema deve acender o LED6 (azul) da placa quando o botão de usuário for pressionado, e apagá-lo quando o mesmo botão estiver desacionado;
  • O sistema deve tratar comandos seriais. Segue a lista:
    • LEDCCN: Apaga/Acende um LED, onde CC é o comando (00 apaga e 01 acende) e N é número do LED (3, 4, 5 ou 6);
    • ACLRDN: Leitura da aceleração de um eixo do acelerômetro, onde N é o código do eixo (X, Y ou Z). A resposta deve ser no formato ACLNVVVVV, onde N é o eixo e VVVVV é o valor da leitura;
    • VER: Leitura da versão do firmware. A resposta deve ser no formato VERMMNNNBBB, onde MM é o campo major, NNN é o campo minor e BBB é o campo build da versão do firmware.

 

Temos conhecimento suficiente para especificar a arquitetura de software do projeto. Mas por onde começamos? Podemos começar com um diagrama em blocos do firmware para visualizar de uma maneira mais clara a interação entre o hardware e a pilha de software necessária para dar suporte a e implementar os requisitos do sistema. Esse diagrama ajuda elucidar os blocos de software/firmware que devem ser implementados no projeto. Veja a Figura 3.

 

O que tem que ser desenvolvido é um firmware para o microcontrolador. Como vai ser utilizado um botão para indicar uma ação do usuário, deve ser utilizado um GPIO do microcontrolador para realizar essa interface, cujo acionamento é executado por um driver GPIO. Esse mesmo driver pode ser utilizado para acionamento do LED. Para o tratamento desses dois periféricos/drivers deve ser criado um serviço de abstração para cada. O mesmo pensamento se aplica para o aceletrômetro e a porta serial UART. No caso do acelerômetro devem ser desenvolvidos dois drivers, um para o periférico SPI e outro para o dispositivo LIS302DL, e um serviço. Para o periférico UART tem que ser desenvolvido um driver e, consequentemente, um serviço para tratar a stream de dados da porta UART.

 

Arquitetura de Software: Diagrama de software.
Figura 3 - Diagrama de software.

  

Esse diagrama ajuda a entender o que tem que ser feito com relação a drivers e serviços, mas ainda existem unidades de software que devem ser desenvolvidas para gerenciar cada um desses blocos, que compõem um nível de abstração maior, a aplicação, como já apontado na Figura 1. Agora é preciso unir esses dois diagramas, o de camadas e o de software, e criar um diagrama de camadas mais detalhado, dividindo cada uma das camadas em módulos que possuam responsabilidades e interfaces bem definidas. Damos a esse diagrama o nome de diagrama de uso. Veja as Figuras 4.a e 4.b. A partir dele é possível ter uma ideia dos módulos funcionais do projeto, os quais se comunicam entre si. Com isso, a equipe de gerenciamento de projetos pode ter uma noção de delegação de tarefas entre os desenvolvedores da equipe.

 

Arquitetura de Software: Diagrama de uso de software sem RTOS.
Figura 4.a - Diagrama de uso de software sem RTOS.
Arquitetura de Software: Diagrama de uso de software com RTOS.
Figura 4.b - Diagrama de uso de software com RTOS.

  

Foi apresentada uma versão bare-metal e outra que faz uso de um sistema operacinal de tempo-real. Qual a diferença? A diferença maior está em como os eventos são tratados, dando as devidas prioridades às tarefas que os tratam. A organização do código é um item a se considerar, mas uma versão bare-metal pode ficar tão modularizada quanto a versão com RTOS. Agora que temos os módulos que compõem o sistema e a relação de uso entre eles, precisamos detalhar como é esse uso, por meio da interface.

 

 

Especificação da interface na arquitetura de software

 

A interface de um sistema bare-metal geralmente ocorre por chamadas de funções via uma API ou por eventos. Quando esses eventos precisam ser tratados de acordo com um nível de prioridade e causar preempção, faz-se necessário usar um RTOS. Com isso a interface entre os módulos passam a usar uma API oferecida pelo sistema operacional utilizado. Mesmo sendo um projeto simples, existem muitas relações de uso. Portanto, a especificação da interface torna-se longa. Para isso vamos focar na interface entre os módulos responsáveis pelo tratamento do LED e Botão, sem RTOS.

 

Arquitetura de Software: Interface dos módulos responsáveis pelo tratamento do LED e Botão (sem RTOS).
Figura 5 - Interface dos módulos responsáveis pelo tratamento do LED e Botão (sem RTOS).

 

Uma vez que a definição da interface entre os módulos seja especificada, o gerente/coordenador de projetos em conjunto com o líder técnico/arquiteto de software do projeto (é difícil encontrar esse cargo nas empresas!) determinam os desenvolvedores que vão atuar na implementação de cada um dos módulos. Disciplinas a serem seguidas num projeto são especificação e gerenciamento de requisitos, gerenciamento de mudanças, definição da arquitetura de software e hardware, gerenciamento de tarefas, desenvolvimento e rastreabilidade entre todos os itens  mencionados. Fácil fazer um projeto, né?

 

 

Conclusões

 

Que legal...quer dizer então que se especificarmos corretamente a arquitetura de software do projeto contribuímos com o gerenciamento dele, correto? Sim! Já ouviram reclamações de atraso e de baixa qualidade nos produtos da empresa onde vocês trabalham? Pois é, aqui é uma pequena contribuição que você pode oferecer à equipe da qual faz parte.

 

A definição da arquitetura de software é uma etapa fundamental de um projeto e, feita corretamente, ajuda a gerenciar os recursos da equipe e mudanças futuras, que é a única certeza dentro de um projeto.

 

 

Saiba mais

 

Arquitetura de software em camadas para iniciantes

Arquitetura de desenvolvimento de software

Projetos de Desenvolvimento: Primeiros passos

 

 

Referências

 

BASS, L.; CLEMENTS, P.; KAZMAN, R. Software Architecture in Practice. 2nd ed. [S.l]: Addison-Wesley Professional, 2003.

LEFFINGWELL, D.; WIDRIG, D. Managing Software Requirements: A Unified Approach. [S.l]: Addison-Wesley Professional, 1999.

Kruchten P. (1995), Architectural Blueprints—The “4+1” View Model of Software Architecture, [Online], Disponível em: http://www.cs.ubc.ca/~gregor/teaching/papers/4+1view-architecture.pdf [25 de Janeiro de 2015]

Making Embedded Systems by Elecia White O'Reilly Copyright, ISBN:9781449302146

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.

Henrique Rossi
Engenheiro eletricista com ênfase em eletrônica e pós-graduado em Engenharia de Software. Comecei um mestrado, mas o interrompi. Especialista na área de sistemas embarcados, com mais de 12 anos de experiência em desenvolvimento de firmware (sistemas baremetal e baseados em RTOS) e Linux Embarcado. Atualmente sou administrador do site Embarcados, trabalho num fabricante de Set-Top Box e atuo como consultor/desenvolvedor na área de sistemas embarcados.

19
Deixe um comentário

avatar
 
9 Comment threads
10 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
7 Comment authors
Eduardo ScherrerMarcelo Rodrigo Dos Santos AndriolliJorge GuzmanHumberto Trindade da SilvaDimitrius Borges Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
C.K.
Visitante
C.K.

Parabéns pelo artigo. Muito elucidativo.

Henrique Rossi
Visitante

Muito obrigado C.K.! Que bom que gostou. Abraço

trackback

[…] Maker Projects. Arquitetura de Software em Sistemas Embarcados - Embarcados - Sua fonte de informações sobre Siste…. Quando um projeto é imaginado e validado conceitualmente e comercialmente, uma sequência de […]

trackback

[…] 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 […]

trackback

[…] a fuel for economic... | ARM Connected Community. Embedded: How Will the Next 50 Billion Devices. Arquitetura de Software em Sistemas Embarcados - Embarcados - Sua fonte de informações sobre Siste…. Fiview -- A Digital Filter Design, Viewing and Comparison […]

Eduardo Scherrer
Visitante
Eduardo C. Scherrer

Muito bom o artigo, realmente esclareceu muitos pontos, ainda mais como você disse em outro comentário, a maioria das pessoas que acessa o site vem da área de eletrônica. A questão da modularização ficou mais clara, pois abrir um código pronto e ver um monte de chamadas Hal, serviço, API, só gera a dúvida, como é que o cara conseguiu fazer um código assim? Eu não conseguiria. Parabéns pelo artigo.

Henrique Rossi
Visitante

Obrigado Eduardo! Realmente dá um trabalho enorme dar manutenção num código desse tipo. Pior ainda é portar esse código para um outro microcontrolador. 😉

Abraços

Marcelo Rodrigo Dos Santos Andriolli
Visitante
Marcelo Andriolli

Parabéns Henrique!! Muito bom o conteúdo e "linguagem" do teu artigo! Igualmente ao que o Dimítrius comentou, "muitas vezes, já realizamos certas abordagens/procedimentos sem nem nos darmos conta de que existe um padrão e um estudo sobre ela". E venho estudando mais a respeito de engenharia de software embarcado, buscando aplicar em projetos que desenvolvo e confesso que não tenho encontrado facilmente conteúdo a respeito. Encontrei o livro "Software Engineering of Embedded and Real-Time Systems" de Robert Oshana, comecei a ler e me parece bacana. O teu artigo me remeteu ao artigo do Lavrati(http://www.embarcados.com.br/principio-da-unica-responsabilidade-em-firmwares/)

Henrique Rossi
Visitante

Muito obrigado Marcelo!

Tenho esse livro e também o uso como referência. Estou gostando também!

O artigo do Lavratti é demais!!

Abraços

Jorge Guzman
Visitante
Jorge Guzman

Henrique parabéns pelo artigo, foi um dos melhores que eu já li. Coincidentemente eu estou tentando implementar algo assim do zero, mas tenho pouca experiência, seu artigo veio em boa hora kkkk. Eu só tenho uma duvida, como seria abstração de dados quando se utiliza interrupções, e caso eu precise chamar alguma função especifica de minha aplicação dentro de alguma interrupção(que eu imagino que fique na camada de Driver) como seria o fluxo de comunicação entre as camadas?

Henrique Rossi
Visitante

Olá Jorge, agradeço muito pelos elogios.

Huummm..boa pergunta. Este é o primeiro artigo de uma série que pretendo fazer sobre design de projetos. Inclusive vou usar o FreeRTOS como base, usando interrupções para geração de eventos assíncronos. O que aconselho é não utilizar chamadas da aplicação em interrupções, e sim usar o envio de eventos ou mensagens para um scheduler. Dessa forma isolamos bem uma camada da outra. Esse vai ser o tema de outro post rsrs

No que eu puder lhe ajudar, fique à vontade para entrar em contato.

Abraços!

Humberto Trindade da Silva
Visitante
Humberto Trindade

Muito bom o artigo! Esclareceu algumas dúvidas que tinha sobre desenvolvimento de software para sistemas embarcados. Definitivamente, um bom planejamento e estruturação do projeto permite economia de tempo e recursos.

Henrique Rossi
Visitante

Muito obrigado Humberto!

Espero ter ajudado um pouco o pessoal da área de sistemas embarcados a fazer pensar um pouquinho na etapa de definição da arquitetura de software de um projeto. Como boa parte dos profissionais dessa área possui formação muito voltada para eletrônica, e pouca bagagem em engenharia de software, existe uma tendência em partir para o código antes de sentar e planejar o projeto.

Abraços

Dimitrius Borges
Visitante
Dimítrius

Artigo sensacional! É interessante notar como, muitas vezes, já realizamos certas abordagens/procedimentos sem nem nos darmos conta de que existe um padrão e um estudo sobre ela. Eu não diria que aqui na empresa executamos (ou obedecemos) perfeitamente a arquitetura do software, não de forma tão detalhada. Mas a filosofia de vê-lo e construí-lo dessa forma já é intrínseca na maneira como trabalhamos. Fantástico! E o cargo "Arquiteto do Projeto" soa bonito pra caramba hehehehe.

Henrique Rossi
Visitante

Muito obrigado Dimítrius!

Realmente seguimos esses passos implicitamente, sem perceber. Existem diversos padrões de arquitetura e as referências que passei me ajudaram muito em entendê-las. Conhecendo os padrões mais utilizados e tendo em mente o problema, sai um trabalho legal.

Enganei-me no cargo, é arquiteto de software, e não arquiteto de projeto rsrs Obrigado pelo toque!

Abraços

Dimitrius Borges
Visitante
Dimítrius

Eu não conhecia o termo "Arquiteto de Projeto" e nem "Arquiteto de Software", eu realmente achei que esse cargo soa muito bem hehehe.

Henrique Rossi
Visitante

Entendi rs O processo de desenvolvimento RUP trouxe muitos papéis novos na área de TI. Um deles foi o de Arquiteto de Software. Depois estude esse processo, até para poder comparar com outros tipos. Acho que vale muito a pena!

Abraços

Dimitrius Borges
Visitante
Dimítrius

RUP eu tive oportunidade de estudar na faculdade, porém muito brevemente. Um outro modelo que tive contato foi o MVC, acabei "esbarrando" nele no desenvolvimento do meu TCC, porque um dos nossos avaliadores é bastante fã dele e já nos preparamos para sermos cobrados em relação a isso. Foi um aditivo muito bem vindo pra mim, porque foi a partir daí comecei a usa-lo de base quando vou desenvolver aplicativos/soluções que tem interação com usuário.

Henrique Rossi
Visitante

Bacana...O MVC é um padrão arquitetural, assim como o sistema em camadas, repositório de dados, sistemas distribuídos, etc. É muito utilizado pela Microsoft na plataforma .NET e na antiga (e utilizada ainda hoje) MFC, a qual faz uso de uma variante do MVC, o Document-View. O framework Qt também faz uso do MVC.