Criando um projeto no IAR com o FreeRTOS

IAR com o FreeRTOS Comunicação entre tarefas alocação dinâmica de memória
Este post faz parte da série Projeto com FreeRTOS. Leia também os outros posts da série:

O intuito deste artigo é criar um projeto no IAR com o FreeRTOS, apresentando e demonstrando o uso desse RTOS. O exemplo prático apresentado foi implementado com um microcontroaldor LPC2368 utilizando um kit de desenvolvimento MCB2300.

Para evitar ser repetitivo, está sendo assumido que o leitor já conhece os conceitos básicos de um RTOS. Para os que desejam revisar o tema, recomendo a série de artigos escrita por Henrique Puhlmann. Também merecem atenção os artigos de Rodrigo Almeida sobre a construção de um RTOS.

O FreeRTOS

O FreeRTOS é um sistema operacional de tempo real e de código aberto, gratuito e disponível para download aqui. Devido à sua simplicidade e disponibilidade para diversas plataformas de hardware, este RTOS tem sido amplamente adotado em projetos de sistemas embarcados.

O FreeRTOS permite a fácil implementação de multitarefa preemptiva ou não preemptiva com diversos níveis de prioridade de tarefas. Além disto, o FreeRTOS também oferece suporte a funcionalidades como:

  • Comunicação entre tarefas através de filas;
  • Timers de software;
  • Semáforos e mutexes para sincronização de acesso a recursos compartilhados;
  • Diversos algoritmos de gerenciamento de memória;
  • Gerenciamento de notificações e eventos.

Mais de 90% do código fonte do FreeRTOS é escrito em linguagem C (o restante do código é escrito em assembly). A arquitetura do FreeRTOS é dividida em camadas conforme a Figura 1.

Camadas de software do FreeRTOS
Figura 1: Camadas de software do FreeRTOS

Todo o código que tem qualquer interação direta com o hardware do processador está contido na camada dependente de hardware. Desta forma é possível portar o FreeRTOS para novas arquiteturas reescrevendo apenas o código desta camada. Devido a esta simplicidade, o FreeRTOS já foi portado para mais de 35 arquiteturas diferentes e é suportado pelos principais compiladores disponíveis no mercado, como GCC, Keil, IAR, etc.

O download da versão mais recente do FreeRTOS pode ser feito de forma gratuita aqui. Este download pode ser feito na forma de um arquivo ZIP ou um arquivo EXE, que nada mais é do que um auto extrator. Não se assuste com o tamanho e a quantidade de arquivos que serão extraídos (são mais de 10.000 arquivos totalizando 275MB!). A grande maioria desses arquivos contém códigos de demonstração e exemplos de uso do FreeRTOS nas diversas arquiteturas suportadas. Antes de prosseguir, é importante entender a organização do código fonte para não ficar perdido nesta grande quantidade de arquivos. Recomendo este artigo em que o Henrique Rossi explica a organização do código fonte do FreeRTOS.

Na época que este artigo foi escrito (abril/2016) a versão mais atual era a 8.2.3.

IAR Embedded Workbench

A IAR Systems fornece um ambiente completo para desenvolvimento de firmware para microcontroladores: o IAR Embedded Workbench. O pacote disponibilizado pela IAR contém, além do compilador, um ambiente de desenvolvimento (IDE) gráfico e suporte a ferramentas para depuração de código. Esta IDE é disponibilizada pela IAR sob vários e diferentes modelos de licenciamento. A versão Kickstart é uma versão gratuita que permite desenvolvimento de qualquer software desde que o tamanho do código esteja limitado a 32KB. Apesar desta limitação é possível implementar muitos projetos interessantes e, por este motivo, a versão Kickstart foi escolhida para ser usada aqui.

Ao fazer o download no site da IAR tome o cuidado de selecionar a versão do Embedded Workbench for ARM (EWARM) pois a IAR oferece a mesma IDE com suporte a outras arquiteturas.

Todos exemplos apresentados neste artigo foram testados na versão 6.50 do EWARM.

Criando um projeto novo no EWARM

Após concluir a instalação do EWARM e com a IDE já em execução, e clique em Project->create new project para criar um projeto novo. A Figura 2 mostra a janela que será aberta. Selecione a opção C->main. O EWARM irá solicitar um nome e um diretório para salvar o projeto. Recomendo que o projeto seja salvo em um diretório criado para esta finalidade. O EWARM salvará todos os códigos fontes e demais arquivos de projeto neste diretório.

IAR com o FreeRTOS : Criação de um novo projeto no EWARM
Figura 2: Criação de um novo projeto no EWARM

A Figura 3 ilustra a tela do EWARM após a criação do projeto. A janela da esquerda contém uma lista de todos os arquivos que fazem parte do projeto. Neste momento apenas o arquivo main.c foi adicionado ao projeto. Também é possível ver que o EWARM criou uma função main vazia.

IAR com o FreeRTOS: Projeto vazio criado automaticamente pelo EWARM
Figura 3: Projeto vazio criado automaticamente pelo EWARM

Para deixar o código fonte mais organizado e concentrar todos os arquivos necessários em um único local, eu copiei o diretório Source do FreeRTOS para dentro do diretório em que o projeto foi salvo. Desta forma, o diretório do projeto terá a estrutura mostrada na Figura 4.

IAR com o FreeRTOS: Estrutura do diretório do projeto
Figura 4: Estrutura do diretório do projeto

O próximo passo é incluir os arquivos que compõem o código fonte do FreeRTOS no projeto do EWARM. Devem ser incluídos, no mínimo, os seguintes arquivos:

  • List.c – Contém o código que implementa listas usadas internamente pelo FreeRTOS;
  • Queue.c – Contém o código que implementa filas usadas para comunicação entre as tarefas de software. As filas também são usadas internamente pelo FreeRTOS;
  • Tasks.c – Contém a parte mais importante do FreeRTOS: o escalonador. O escalonador é responsável por controlar a execução das diversas tarefas de software implementando o multitarefa;
  • Portable/IAR/LPC2000/port.c – Contém o código dependente de hardware. Neste exemplo será usado um microcontrolador LPC2368. O port LPC2000 é o que mais se aproxima do microcontrolador a ser usado e por isto foi escolhido. Como existem algumas pequenas diferenças entre o LPC2000 e o LPC2368, será necessário fazer alguns ajustes neste arquivo;
  • Portable/MemMang/heap_1.c – Contém o código que realiza o gerenciamento da memória RAM. Aqui são implementadas variantes das funções malloc e free usadas pelo FreeRTOS. O gerenciamento de memória do FreeRTOS será detalhado melhor em um artigo futuro;
  • Portable/IAR/LPC2000/portasm.s79 – Contém código assembly dependente de hardware, relacionada à troca de contexto entre as tarefas.

Para incluir um arquivo no projeto clique em Project->Add Files e, na janela que irá abrir, selecione os arquivos list.c, queue.c e tasks.c. Lembre-se que estes arquivos estão dentro do diretório Source. Após isto, repita o processo para os arquivos heap_1.c (que está dentro de source/portable/MemMang) e port.c (que está dentro de source/portable/IAR/LPC2000).

Um último arquivo importante a ser incluído no projeto é um arquivo assembly que contém a definição dos vetores de interrupções/exceções do processador. Neste caso vamos copiar o arquivo lpc2xxx_cstartup.s localizado no diretório Demo/ARM7_LPC2129_IAR/SrcIAR/ do código fonte original do FreeRTOS para o diretório raiz do projeto. O arquivo utilizado é do processador que mais se assemelha ao LPC2368 entre os exemplos apresentados no código fonte do FreeRTOS. Mais adiante será necessário fazer alguns ajustes neste arquivo.

A Figura 5 mostra uma visão do projeto após a inclusão dos arquivos do FreeRTOS no projeto.

IAR com o FreeRTOS: Visão do projeto após a inclusão do código fonte do IAR
Figura 5: Visão do projeto após a inclusão do código fonte do IAR

Antes de compilar o projeto, é necessário fazer alguns ajustes nas suas configurações. Para editar as configurações do projeto clique em Project->options. A janela que será aberta permite configurar diversas opções do projeto. Vamos começar selecionando o modelo do microcontrolador, que no nosso exemplo será o LPC2368 (Figura 6). Para selecionar o microcontrolador, clique no botão à direita do label “Device” e selecione o fabricante (NXP), depois a família de microcontroladores (LPC2300) e por fim o modelo do microcontrolador (LPC2368).

IAR com o FreeRTOS: Seleção do modelo do microcontrolador nas configurações do projeto
Figura 6: Seleção do modelo do microcontrolador nas configurações do projeto

Um outro ponto importante é a seleção correta do mapa de memória do microcontrolador. O mapa de memória é um arquivo texto que contém instruções para o compilador alocar o código em diversas regiões da memória flash do microcontrolador. Através deste mapa, é possível também reservar regiões da memória para usos específicos. Para verificar qual o mapa de memória em uso, clique em Linker. Pela Figura 7 é possível observar que o EWARM selecionou um arquivo LPC2368.icf que é o mapa de memória padrão para este microcontrolador. Por enquanto vamos utilizar este mapa de memória padrão.

IAR com o FreeRTOS: Seleção do mapa de memória
Figura 7: Seleção do mapa de memória

Para informar ao compilador os diretórios em que ele deve procurar por arquivos .h (esta configuração é conhecida como include path) clique em C/C++ Compiler, selecione a aba Preprocessor e insira um diretório por linha no campo “Additional include directories”. Devem ser incluídos os seguintes diretórios:

  • Source/include – Contém todos os arquivos de cabeçalho do FreeRTOS que são independentes de hardware;
  • Source/portable/IAR/LPC2000 – Contém os cabeçalhos do código dependente de hardware;
  • O diretório raiz do projeto.

A Figura 8 mostra a inclusão do destes diretórios na janela de configuração. Observe que foi utilizada a macro $PROJ_DIR$ que o compilador irá substituir pelo nome do diretório raiz do projeto. A grande vantagem de usar esta macro é que, desta forma, o projeto irá utilizar caminhos relativos. Isso significa que se este projeto for copiado para outro diretório ou, até mesmo, outro computador, não será necessário fazer ajustes no nome dos diretórios para refletir o novo local.

IAR com o FreeRTOS: Configuração do include path para o compilador C/C++
Figura 8: Configuração do include path para o compilador C/C++

A inserção do include path deve ser repetida na tela de configuração do assembler. Para isto, clique em Assembler, selecione a aba Preprocessor e insira os mesmos diretórios conforme a Figura 9.

IAR com o FreeRTOS: Configuração do include path para o assembler
Figura 9: Configuração do include path para o assembler

Feitos os ajustes acima, clique em OK para fechar a janela de configuração.

Agora vamos fazer os ajustes necessário no arquivo port.c. Lembrando que as famílias LPC2000 e LPC2368 são microcontroladores que utilizam núcleos ARM7 idênticos (consequentemente possuem o mesmo conjunto de instruções assembly), mas existe uma diferença na implementação de seus controladores de interrupções (conhecido como VIC – Vectored Interrupt Controller). Devido a isto, é necessário fazer um ajuste na função prvSetupTimerInterrupt. Nesta função, é feita a configuração do timer 0 que é utilizado pelo FreeRTOS e do VIC para habilitar e as interrupções deste timer. As principais diferenças entre os VICs destas duas famílias são as seguintes:

  • No LPC23xx o timer 0 é associado ao vetor de interrupção 4 enquanto que no LPC2000 é possível escolher o vetor ao qual o timer 0 será associado. Desta forma é necessário alterar todas as referências ao número do vetor para 4;
  • No LPC23xx o registrador VICVectCntl controla a prioridade da interrupção.

A seguir é exibido o código fonte da função prvSetupTimerInterrupt com as modificações para o microcontrolador LPC2368. O código original do LPC2000 está comentado logo acima do código que deve ser usado para o LPC2368.

O próximo passo é ajustar os vetores de interrupção do processador no arquivo lpc2xxx_cstartup.s. Sempre ocorre uma interrupção de hardware, o controlador de interrupção disponibiliza o endereço da rotina de tratamento da interrupção em um registrador chamado VICAddress. O endereço deste registrador no LPC2368 é diferente do LPC2129 e, por isto, é necessário fazer um ajuste no código. Lembre-se que o arquivo lpc2xxx_cstartup.s que utilizamos não é do LPC2368 pois o FreeRTOS não possui um exemplo para este processador. Este ajuste é necessário pois as interrupções periódicas do timer 0 serão tratadas pelo vetor IRQ. A seguir é exibido um trecho do código do arquivo lpc2xxx_cstartup.s com destaque para o trecho de código alterado para o LPC2368.

O FreeRTOS possui diversos parâmetros de configuração que controlam o comportamento do escalonador e outras funcionalidades do sistema operacional. Através da configuração é possível também desabilitar funcionalidades que não são utilizadas, reduzindo, assim, o total de memória ocupada pelo FreeRTOS. O arquivo de configuração do FreeRTOS é o FreeRTOSConfig.h que, por ser um arquivo especifico do projeto e não ser dependente de hardware, não deve ficar dentro da pasta portable. Além deste arquivo de configuração, precisamos também do arquivo que contém as definições do hardware do processador, como, por exemplo, os endereços dos registradores. Cada um dos exemplos apresentados na pasta demo no código fonte original do FreeRTOS contém um arquivo de configuração e um arquivo de cabeçalho com as definições do processador. Para o nosso exemplo, vamos copiar os arquivos FreeRTOSConfig.h e lpc23xx.h do diretório demo/ARM7_LPC2368_Eclipse/RTOSDemo para o diretório raiz do projeto.

Se tentarmos compilar o projeto neste momento, receberemos mensagens de erro que podem ser eliminadas editando o arquivo FreeRTOSConfig.h. Uma configuração importante é a constante configCPU_CLOCK_HZ que informa ao FreeRTOS o valor do clock do processador. Este valor será usado para calcular todas as bases de tempo do FreeRTOS. Como o cristal utilizado na placa MCB2300 é de 12MHz, vamos ajustar esta constante de acordo com isso. A seguir é exibida a parte do arquivo FreeRTOSConfig.h com comentários nos trechos alterados. As linhas modificadas estão destacadas em amarelo.

Tudo que está após a linha que contém #endif /* FREERTOS_CONFIG_H */ (linha 136) deve ser apagado ou comentado. Alguns erros de compilação ocorrerão se estas linhas não forem removidas.

Após salvar o arquivo podemos compilar o código fonte. A compilação pode ser feita apertando a tecla F7 ou clicando em Project->Rebuild All. Se tudo correr bem, a compilação deve gerar apenas alguns warnings que, por enquanto, serão ignorados.

Criação de tarefas (tasks)

A rotina principal (main) de um software com FreeRTOS deve conter, no mínimo, a inicialização do hardware do processador (dependendo da aplicação isso pode não ser necessário), a criação de algumas tarefas e a inicialização do escalonador. O código mostrado a seguir mostra um exemplo de uma rotina main com a criação de uma tarefa que foi chamada de vGPIOTask.

No FreeRTOS, cada tarefa deve ser implementada como uma função em C que fica em loop infinito. O escalonador se encarregará de selecionar e executar as tarefas criadas pelo usuário. A seguir é exibido o código fonte de uma tarefa simples que faz piscar os LEDs da placa MCB2300. Observe que toda inicialização específica da tarefa é feita antes do loop infinito.

Com este exemplo chegamos ao fim deste artigo. Espero ter ajudado os leitores a terem uma ideia sobre o uso do EWARM e do FreeRTOS.

Outros artigos da série

Comunicação entre tarefas no FreeRTOS: Filas >>
Este post faz da série Projeto com FreeRTOS. Leia também os outros posts da série:
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.

Gabor Sipkoi
Engenheiro eletrônico (UFPE) com mestrado em engenharia de sistemas (UPE) com 18 anos de experiencia com desenvolvimento de hardware e software para sistemas embarcados de tempo real. Tem grande experiencia com desenvolvimento de software para as famílias de microcontroladores ARM, PIC, Freescale e 8051. Atualmente é engenheiro consultor no CESAR - Centro de Estudos e Sistemas Avançados do Recife.

3
Deixe um comentário

avatar
 
1 Comment threads
2 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Gabor SipkoiBruno Albrecht Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Bruno Albrecht
Visitante
Bruno L. Albrecht

belo artigo. creio que vai ajudar na minha empreitada também: http://hardwaresw.blogspot.com.br/

Gabor Sipkoi
Visitante
Gabor Sipkoi

Olá Bruno. Seu artigos estão muito bons! Fico feliz em saber que há outras pessoas interessadas em divulgar o FreeRTOS.

Bruno Albrecht
Visitante
Bruno L. Albrecht

valeu Gabor! =) teu artigo também está muito bem escrito. aguardo os próximos!