Arquitetura de desenvolvimento de software – parte IV

função de recepção

No modelo de máquina de estados, assim que uma função termina, o processador automaticamente passa para a próxima tarefa, independente de questões temporais. No entanto, passa a ser extremamente complicado fazer qualquer garantia de tempo de execução, pois além dos tempos serem regidos pelo tamanho da tarefa, estes tempos podem ainda variar. Um bom exemplo é a recepção de comandos pela serial. Nem sempre o sistema recebe bytes e, mesmo quando recebe, ele precisa aguardar todos os bytes chegarem para processar a mensagem. Assim, a função de recepção tem pelo menos três durações diferentes: quando não há nada na serial, quando há informação na serial a ser salva e quando há uma mensagem para ser processada.

 

Uma característica desejada nos sistemas embarcados é que as funções tivessem um tempo determinado de execução. Deste modo, todo o sistema se tornaria mais previsível.

 

A maneira mais simples de realizar este procedimento é fazer com que, nas vezes que a função for executada e terminar antes, o sistema faça com que ela aguarde até um determinado valor de tempo. Este valor tem que ser maior que o pior caso de execução da função.

 

Apesar de não ser ideal, já que o processador irá ficar tempo ocioso apenas para padronizar os tempos de execução das funções, o determinismo atingido por esse método traz imensas vantagens no desenvolvimento. Outra vantagem é que é possível criar uma arquitetura que faça essa garantia consumindo poucos recursos, ou seja, esta é uma abordagem possível de se implementar em sistemas que não são capazes de suportar um sistema de tempo real como o FreeRTOS.

 

Para isso basta ter acesso à um temporizador em hardware. Basta então inicializar a contagem no top-slot da arquitetura de máquina de estados e aguardar o fim da contagem no bottom-slot. Deste modo, toda vez que um slot terminar, o sistema ficará aguardando o tempo definido antes de iniciar o próximo slot.

 

 

No exemplo apresentado é inserida a função AguardaTimer() no bottom-slot de modo que a próxima função só executará em 5 (ms).

 

Como podemos notar, se a função ultrapassar 5 (ms) todo o cronograma será afetado. É necessário então garantir que todo e cada slot será executado em menos de 5 (ms). Isto pode ser ser feito através de testes de bancada.

 

Com base no código acima e supondo que a tarefa 1 (LeTeclado(), S.1) gasta um tempo de 2.0(ms), a tarefa 2 (RecebeSerial() , S.2) consuma  3.1 (ms), a tarefa (EnviaSerial(), S.3) apenas 1.2 (ms),  com um top-slot de 0.5 (ms) e um o bottom-slot de 0.3 (ms) temos a figura abaixo representando a linha temporal de execução do sistema.

 

Linha temporal função de recepção

 

Podemos notar que para o ciclo do primeiro slot são gastos 0.5+2.0+0.3 = 2.8(ms). Deste modo o sistema fica aguardando na função AguardaTimer() durante 2.2 (ms) sem realizar nenhum processamento útil. Para o segundo slot temos um tempo livre de (5-(0.5+3.1+0.3))=1.1 (ms). O terceiro slot é o que menos consome tempo de processamento, possuindo um tempo livre de (5-(0.5+1.2+0.3))=3.0 (ms).

 

 

Utilização do tempo livre para interrupções

 

Dependendo do tempo escolhido para o slot e do tempo consumido pela função, podem existir espaços vagos na linha de tempo do processador. A figura abaixo apresenta uma linha de tempo de um sistema que possui apenas 1 slot cujo temporizador foi configurado para 8 (ms).

 

Linha temporal função de recepção

 

A cada ciclo "sobram" 3(ms). Este tempo pode ser considerado perdido caso exista apenas a tarefa S.1 no sistema. Nesta situação é até mesmo possível diminuir o tempo do temporizador para 5 (ms). Isto permitiria um acréscimo na frequência de execução da tarefa S.1 que era de 125(Hz) para 200(Hz), ou 60%.

 

No entanto, não havendo tempo livre, qualquer alteração acabaria com o determinismo além de impossibilitar o uso de interrupção sem atrapalhar a frequência de execução. Portanto, esse tempo livre é importante por dois motivos: evitar que pequenas alterações não esperadas na execução das funções impactem na taxa de execução e, mais importante ainda, permitir que as interrupções aconteçam sem causar problema na temporização das tarefas.

A figura abaixo demonstra o mesmo sistema sendo interrompido através de interrupções assíncronas. Neste caso, a interrupção "rouba" 1(ms) a cada iteração da máquina de estados.

 

Linha temporal com interrupções função de recepção

 

 

Como cada interrupção gasta um tempo de 1 (ms) e temos um tempo livre de 3 (ms) em cada ciclo, basta garantir que os eventos que geram a interrupção não ultrapassem a frequência de 3 eventos a cada 8 (ms). Esta análise deve ser feita para assegurar que o sistema, apesar de "perder" tempo de processamento, tenha um modo simples de garantir o determinismo na execução das funções.

 

O "perder" está entre aspas pois o tempo que o processador fica aguardando no bottom-slot é uma ótima oportunidade para colocar o sistema em baixo consumo de energia e permitir que ele seja acordado com a interrupção do timer. Indo por este caminho de economia de energia, o objetivo passa de "ter uma alta taxa de execução sem tempo ocioso" para "possuir o máximo de tempo livre", reduzindo efetivamente o consumo.

 

Outros artigos da série

<< Arquitetura de desenvolvimento de software – parte III
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.

12
Deixe um comentário

avatar
 
8 Comment threads
4 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
7 Comment authors
Marcos RibeiroMarcelo Rodrigo Dos Santos AndriolliAndré CastelanFelipe NevesFernando Almeida Stock Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Matheus Quick
Visitante
Matheus Quick

muito bom

Rodrigo Almeida
Visitante
Rodrigo Almeida

Obrigado Mateus!

trackback

[…] #sharebar { padding: 0; text-align: left; list-style: none; margin: 0; } #sharebar span {float: left; padding: 0 5px; } #sharebar { display: block; margin: 0; padding: 5px 0 5px 5px; overflow: visible; text-align: center; height: 20px;} #sharebar #fb { text-align: left;} #sharebar #tww { width: 95px; overflow: hidden; } p.recommended { padding: 14px; text-align: center; } .page { position: relative; } Tweetar lang: en_US (function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/pt_BR/all.js#xfbml=1"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk')); !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs'); window.___gcfg = {lang: 'pt-BR'}; (function()… Leia mais »

trackback

[…] Arquitetura de desenvolvimento de software – parte IV […]

Marcos Ribeiro
Visitante
Marcos

Muito bom Rodrigo Parabéns! Ficamos no aguardo dos próximos.

Marcelo Rodrigo Dos Santos Andriolli
Visitante
Marcelo Andriolli

Muito bom Rodrigo!! Quais seriam as referencias bibliográficas dessa série de artigos?

Rodrigo Almeida
Visitante
Rodrigo Almeida

Obrigado Marcelo!

Infelizmente não tenho um livro que fale especificamente sobre arquiteturas para lhe indicar. Boa parte das referências e exemplos que utilizei tirei de códigos fonte no github ou de projetos. Alguns livros interessantes e que comentam um pouco sobre isso são o "The art of programming embedded systems" do Jack Ganssle, e o Embedded systems design and applications with the 68HC12 and HCS12 do Steven Barrett.

Marcelo Rodrigo Dos Santos Andriolli
Visitante
Marcelo Andriolli

Obrigado Rodrigo pelas referencias passadas. Gostei muito da abordagem que foi dada ao a assunto e a organização lógica. Novamente Parabéns!

André Castelan
Visitante

Muito bom Rodrigo!

Felipe Neves
Visitante
Felipe Neves

Gostei muito dessa série artigos, acho que seria sensacional esse tipo de abordagem nas universades afim de demonstrar diferentes visões de arquitetura de sw para embarcados. E não apenas o tradicional while(1);

Abs.

Felipe

Rodrigo Almeida
Visitante
Rodrigo Almeida

Até o tradicional while(1) eu não gosto muito, parece que o cara quis fazer um while(i) mas digitou errado. Os meus alunos gostam mesmo é quando eu uso forever. =)

for(;;) //ever

{

}

Fernando Almeida Stock
Visitante
Fernando Almeida Stock

Excelente material! Parabéns!