15 Comentários

GNU ARM Cross-toolchain – FreeRTOS + GCC + STM32F4Discovery – Parte 1

FreeRTOS 8 bare-metal

Os artigos anteriores desta série indicaram alguns passos muito importantes para o desenvolvimento de firmware usando microcontroladores ARM Cortex-M4 e ferramentas GNU. Até o momento trabalhamos com um projeto bare-metal, ou seja, que não faz uso de um sistema operacional. Este artigo foi dividido em duas partes. Na primeira, entenderemos as razões pelas quais faz-se necessário o uso de um sistema operacional de tempo-real, RTOS, usando o FreeRTOS como alternativa. Na segunda parte serão apresentados os passos que devem ser seguidos para a migração da aplicação bare-metal para a sua versão baseada no FreeRTOS.

Sistemas bare-metal

Até o momento trabalhamos com desenvolvimento bare-metal, ou seja, o desenvolvedor controla diretamente e manipula o hardware do sistema, executando instruções de acesso aos periféricos do microcontrolador. Pequenos sistemas embarcados que fazem uso desse tipo de arquitetura não possuem controle temporal explícito, fazendo com que o controle de tempo seja obtido por meio de rotinas, tais como delays, escritas pelo próprio desenvolvedor. A isso dá-se o nome de controle implícito de tempo. Uma metodologia muito empregada em sistemas embarcados bare-metal é Background/Foreground, onde a aplicação consiste de um loop infinito sem uma condição de saída. A lógica da aplicação é definida por chamadas a sub-rotinas numa ordem sequencial, dentro do loop, levando em consideração que essa sequência determina o comportamento temporal da aplicação.

O loop principal é normalmente chamado de Background, o qual pode ser interrompido (suspendido) por interrupções do microprocessador, que fazem com que rotinas de tratamento a interrupções, ISR, sejam chamadas. A essas rotinas é dado o nome de Foreground. Após o término do processamento dessas funções, o sistema troca o contexto de execução novamente para a operação de Background. Esse tipo de implementação gera um baixo overhead de sistema (memória e processamento), mas possui uma grande desvantagem: não é determinístico no que se refere a tempo. Uma simples alteração no loop principal pode alterar o comportamento temporal de todo processamento seguinte ao ponto modificado. Além disso, uma modificação dentro de uma ISR pode gerar resultados inesperados, pois uma operação de Background pode sofrer incrementos aleatórios no seu tempo de execução ao longo do tempo dependendo da alteração efetuada na rotina de tratamento da interrupção. Deve ser levado em consideração que geralmente operações críticas são realizadas em Foreground, o que faz com que haja uma tendência de adição de código mais do que o recomendado dentro de uma ISR. Como tratamos isso?

Por que usar um RTOS?

Uma solução seria usar um sistema operacional de tempo real, RTOS, o qual é responsável por garantir que tarefas sejam executadas com determinismo. Dá-se o nome de tarefas aos pedaços de código que executam um trabalho específico e bem definido, em loop, e que podem se comunicar com outras tarefas do sistema por meio de serviços oferecidos pelo kernel do RTOS utilizado. Este artigo não tem o objetivo descrever o que é um RTOS, mas sim apresentar uma visão geral sobre o assunto. Dentre as soluções open-source disponíveis no mercado, uma boa escolha é o FreeRTOS, já que oferece atualizações com frequência e possui uma comunidade grande de desenvolvedores.

Muitos sistemas embarcados possuem requisitos de tempo real, ou seja, possuem ações que devem ser tomadas dentro de um período máximo de tempo. Pode-se classificar tais requisitos em soft e hard. Requisitos de tempo real soft impõem que caso o limite de tempo para a execução de uma ação seja eventualmente ultrapassado, uma falha não é gerada, mas uma degradação do sistema é percebida. Já requisitos de tempo real hard impõem que toda ação deve ser executada dentro do seu limite de tempo, caso contrário uma falha no sistema é ocasionada. O FreeRTOS oferece tratamento para ambos requisitos por meio do tratamento das prioridades estabelecidas para as respectivas tarefas.

Uma das grandes vantagens do uso de um sistema operacional, seja de tempo real ou de uso genérico, é a modularidade, resultado da criação de tarefas que executam atividades e apresentam interfaces muito bem definidas. Por consequência, a inserção de rotinas de testes torna-se uma tarefa mais simples. Além disso, reuso de código e criação de tarefas orientadas a eventos são outras grandes vantagens.

FreeRTOS

FreeRTOS é um RTOS desenvolvido pela Real Time Engineers Ltd. que suporta 34 arquiteturas. Possui uma licença GPL modificada, o que permite a proteção do código proprietário do projeto e exige que as mudanças realizadas no código do RTOS em específico sejam disponibilizadas. Deve-se levar em consideração que precisa ser informado, de alguma forma, que o produto desenvolvido com o FreeRTOS faz uso desse sistema operacional.

Trata-se de um sistema operacional cujo kernel pode trabalhar de forma preemptiva ou cooperativa, com baixo footprint de memória Flash (4KB a 9KB), escrito predominantemente em C, e oferece suporte a alguns serviços muito interessantes para sincronização entre tarefas: 

  • Queues;
  • Binary semaphores;
  • Counting semaphores;
  • Recursive semaphores;
  • Mutexes;
  • Event group (novidade na versão 8.0).

Mas o que é necessário para colocamos o FreeRTOS para funcionar na placa STM32F4Discovery? Bem, vamos primeiramente entender a organização do código do FreeRTOS para que tenhamos condições de agregar à aplicação bare-metal somente os arquivos fundamentais para o processo.

Primeiramente, faça o download do código do FreeRTOS. Após descompactar o conteúdo do arquivo .zip, o conteúdo abaixo é oferecido:

A pasta FreeRTOS-Plus contém outros produtos oferecidos pela Real Time Engineers Ltd, sob licenças diferentes, e que não são o foco deste artigo. Já a pasta FreeRTOS contém o que é de mais importante: o código do kernel do FreeRTOS e muitas aplicações de demonstração. O conteúdo dessa última pasta é mostrado abaixo:

A sub-pasta Source, cujo conteúdo é exibido a seguir, disponibiliza o código do kernel, o qual pode ser caracterizado por três arquivos essenciais: task.c, queue.c e list.c. Além desses, são oferecidas implementações de software timer, por meio do arquivo timers.c, e um módulo com funções responsáveis por tratar co-routines, croutine.c, as quais são usadas para processamento cooperativo. Cada co-routine é uma função implementada como uma tarefa, contendo um loop infinito. No entanto, todas as co-routines de um projeto compartilham uma única stack, ao passo que cada tarefa propriamente dita mantém uma região de stack exclusiva e individual.

Os arquivos mencionados anteriormente não são dependentes da arquitetura do microprocessador utilizado. No entanto, existe uma outra camada de software que necessita de acesso ao hardware, esta sim dependente da arquitetura escolhida. A essa camada é dado o nome RTOS portable, e é implementada pelos arquivos existentes na pasta portable. Veja o seu conteúdo abaixo:

Pode-se verificar que seu conteúdo é separado por compilador e arquitetura, como, por exemplo, GCC + ARM Cortex-M4F, IAR + RX600, etc. Existem 18 toolchains e 34 arquiteturas suportados. Além disso, essa camada de abstração de hardware oferece um outro serviço, gerenciamento dinâmico de memória, cuja implementação está na pasta portable/MemMang. Existem quatro arquivos nesse local: heap_1.c, heap_2.c, heap_3.c e heap_4.c. O que são eles?

No artigo GNU ARM Cross-toolchain – Configuração stack e heap foi mencionado como reservar espaços da memória volátil do sistema para tais finalidades. Em específico, a região heap é utilizada para alocação dinâmica de memória, o que demanda o uso de um gerenciador de alocação de memória, chamado de allocator. A biblioteca C padrão, como visto no post anterior, oferece uma implementação própria, por meio da API mallocfreerealloc, etc. Mas ela oferece dois grandes perigos para sistemas embarcados com requisitos de tempo-real: não é thread safe e não oferece determinismo. Ou seja, tais funções podem gerar condições de corrida em ambiente multi-thread, por tratarem recursos compartilhados, e não são executadas num tempo constante. Tendo em vista isso, o FreeRTOS oferece, dentro da camada portable, algumas implementações de alocação de memória que endereçam esses problemas, cada uma representada por um desses arquivos.

E agora, como começo a minha aplicação? Esse passo fica para a parte 2 do artigo. É a hora em que os leds piscam!

Outros artigos da série

<< GNU ARM Cross-toolchain – OpenOCD + GDBGNU ARM Cross-toolchain – FreeRTOS + GCC + STM32F4Discovery - Parte 2 >>
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Software » GNU ARM Cross-toolchain – FreeRTOS + GCC + STM32F4Discovery - Parte 1
Comentários:
Notificações
Notificar
guest
15 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Pedro Igor Borçatti
Membro
07/02/2020 13:11

Existe port do freeRTOS para o stm32f103c8t6? se sim onde encontro isso?

Muito show seus artigos!!

Pedro Neto
Pedro Neto
06/08/2015 10:37

Henrique, o que separa uma decisão de usar ou não S.O. para embarcados? A casos que são bem claros, mas outros que gera uma "nuvem" de dúvidas

Henrique Rossi
Reply to  Pedro Neto
09/08/2015 22:54

Olá Pedro,

Entendo a sua dúvida. Basicamente me pergunto: "O sistema possui alguma restrição forte que precise de uma garantia de execução num determinado período?"

Se a resposta for positiva, faça uso de um RTOS. Se não, pondere. Uma máquina de estado bem feita pode resolver seu problema. Mas precisa tomar conta do processamento colaborativo gerado.

O uso de um RTOS facilita o entendimento do código, na minha opinião, pois torna o processamento linear. Já o com máquina de estado torna-se mais disperso.

Espero tê-lo ajudado. Abraços.

Pedro Neto
Pedro Neto
Reply to  Henrique Persico Rossi
09/09/2015 12:45

Obrigado!!!

Marcelo Jo
Marcelo Jo
12/03/2014 17:44

Henrique, tua série de posts tão ficando show!

Henrique Rossi
Reply to  Marcelo Jo
12/03/2014 21:10

Muito obrigado Marcelo! O próximo da série será o uso do Eclipse para brincarmos com a placa...

Grande abraço!

trackback
10/08/2014 17:32

[…] GNU ARM Cross-toolchain – FreeRTOS + GCC + STM32F4Discovery – Parte 1 » 12-03-2014 […]

trackback
11/07/2014 20:01

[…] GNU ARM Cross-toolchain – FreeRTOS + GCC + STM32F4Discovery – Parte 1 […]

trackback
31/05/2014 22:45

[…] GNU ARM Cross-toolchain – FreeRTOS + GCC + STM32F4Discovery – Parte 1 […]

trackback
17/04/2014 08:47

[...] GNU ARM Cross-toolchain – FreeRTOS + GCC + STM32F4Discovery – Parte 1 [...]

trackback
17/04/2014 08:46

[...] GNU ARM Cross-toolchain – FreeRTOS + GCC + STM32F4Discovery – Parte 1 [...]

trackback
17/04/2014 08:45

[...] primeira parte deste artigo foi responsável por introduzir o sistema operacional de tempo-real FreeRTOS, [...]

trackback
16/04/2014 00:03

[...] o projeto de exemplo do FreeRTOS apresentado num post anterior da série. É necessário realizar o download dos arquivos desse projeto aqui. Use a pasta [...]

Talvez você goste:

Séries



Outros da Série

Menu

WEBINAR
 
Debugging
em Linux embarcado

 

Data: 30/09 às 19:30h - Apoio: Mouser Elecctronics
 
INSCREVA-SE AGORA »



 
close-link