Usando FreeRTOS para aplicações com a FRDM KL25Z

Freescale FRDM KL25z

Introdução

 

Neste artigo serão apresentados alguns conceitos envolvendo sistemas operacionais de tempo-real (RTOS) e a utilização do FreeRTOS para desenvolvimento de aplicações utilizando a placa Freedom KL25z e a IDE MCUXpresso, incluindo seu SDK (Software Development Kit) KSDK v.2.2.0.

 

Como base teórica, estão sendo utilizados a série de artigos publicados no Portal Embarcados por Rodrigo Almeida e Marcelo Barros intitulada “Desenvolvendo um RTOS”.

 

 

RTOS

 

Um sistema operacional de tempo-real é uma estrutura programada para gerenciar os recursos da CPU, controlando a sincronização de tarefas, gerenciamento de interrupções, etc. e garantindo os requisitos temporais.

 

Tendo em vista que essa estrutura consome processamento e memória, sua utilização é indicada quando há o aumento da complexidade do projeto tornando-se inviável sua implementação “crua” utilizando o one single loop.

 

Kernel é a camada do sistema operacional responsável por abstrair a utilização de memória e o processamento das aplicações. Gerencia a execução de processos, manuseia a memória disponível e faz a intermediação com o hardware.

 

O Kernel pode ser dividido em duas categorias, cooperativo e preemptivo. No primeiro, um processo (ou tarefa) só é executado após o término do anterior, sendo assim, loops infinitos travam o sistema. O segundo funciona de maneira que todos os processos são implementados como loops infinitos, o RTOS é responsável pela troca de contexto e empilhamento de funções para execução de múltiplas tarefas, pausando um processo para execução de outro baseando-se em ordens de prioridade, por exemplo.

 

 

FreeRTOS

 

O FreeRTOS é o sistema operacional de tempo-real mais utilizado na atualidade e tem suporte a grande parte dos fabricantes e IDE’s.

 

IDE’s e fabricantes suportados pelo FreeRTOS
Figura 1: IDE’s e fabricantes suportados

 

A interface com o hardware é implementada no RTOS e está pronta para ser utilizada. São abstraídas as maneiras com que são realizadas as trocas de contexto entre tarefas, de acordo com a prioridade que é atrelada a elas no momento de sua criação. Todas as tarefas são implementadas como loops infinitos, já que o sistema consegue trocar de contexto durante a execução de um processo para execução de outro.

 

 

Configurando o Ambiente

 

No Portal Embarcados existe uma série de artigos de Evandro Teixeira onde são implementadas as Bibliotecas de Software para FRDM-KL25Z, portanto, as funções de acesso às portas de entrada e saída (GPIO) utilizadas, por exemplo, serão semelhantes às criadas nesta série.

 

O primeiro passo é fazer a instalação da IDE (MCUXpresso) e do Software Development Kit (KSDK v.2.2.0) baixados do site do fabricante, que a partir de dezembro de 2015 passou a ser a NXP.

 

O download da IDE pode ser feito pelo site da NXP, clicando em “download →“MCUXpresso IDE” e selecionando o sistema operacional.

 

O download do SDK também pode ser feito pelo site da NXP, clicando em “Select Development Board”, selecione sua placa (neste exemplo será utilizada a FRDM-KL25Z) e clique em “Build MCUXpresso SDK”. Após isso, é necessário adicionar ao SDK o sistema operacional (FreeRTOS). Clique em “Add software component”, selecione o FreeRTOS e faça o download.

 

Adicionando o FreeRTOS ao SDK
Figura 2: Adicionando o FreeRTOS ao SDK

 

Obs.: Se ao realizar o debug dos exemplos, no momento em que a IDE tentar gravar o código no microcontrolador, surgir uma tela de erro com a mensagem “No Device Available” é provável que seja necessária atualização do bootloader. Este link pode ajudar.

 

Ao abrir a IDE pela primeira vez o SDK pode ser instalado arrastando a pasta ou o .zip baixado anteriormente a esta aba:

 

Aba de Instalação do SDK
Figura 3: Aba de Instalação do SDK

 

Após isto é necessário criar um projeto. Uma vez aberta a IDE, vá em File → New → Project → C/C++ → New C/C++ Project, selecione a placa correspondente ao SDK instalado, clique em next.

 

Criação do Projeto
Figura 4: Criação do Projeto

 

Escolha o nome do projeto, seu diretório e os recursos a serem utilizados, incluindo o FreeRTOS.

 

Importação dos recursos
Figura 5: Importação dos recursos

 

 

Utilizando o FreeRTOS

 

A IDE MCUXpresso realiza todos os includes necessários se os passos anteriores foram seguidos corretamente, se isso não fosse verdade seria necessário incluir às configurações de compilação os diretórios contendo os arquivos header (.h) das bibliotecas a serem utilizadas.

 

FRDM-KL25Z/rtos/freertos_9.0.0/Source/include

FRDM-KL25Z/rtos/freertos_9.0.0/Source/portable/GCC/ARM_CM0

 

A inclusão das bibliotecas externas para os periféricos deve ser feita adicionando os arquivos .c que necessitam ser compilados a pasta dentro do projeto de forma linkada. Para isso, clique com o botão direito sobre o projeto New → Folder. Clique no projeto e dê um nome para a pasta que conterá os arquivos a serem incluídos. Em “Advanced”, faça com que esta pasta seja uma “Linked Folder”. Digite seu endereço e clique em Finish.

 

Criação da pasta
Figura 6: Criação da pasta

 

Para ter certeza que estes arquivos serão compilados, clique com o botão direito sobre a pasta recém importada → Properties → C/C++ Build e desmarque a caixa “Exclude resource from build”.

 

Garantindo a compilação das bibliotecas
Figura 7: Garantindo a compilação das bibliotecas

 

O diretório contendo o header (.h) deve ser incluído nas configurações de compilação do projeto clicando com o botão direito sobre ele → Properties → C/C++ Build → Settings → MCU C Compiler → Includes. Clique no ícone “Add…” no canto superior direito e digite o endereço da biblioteca ou navegue utilizando o explorador de arquivos.

 

Adicionando bibliotecas externas
Figura 8: Adicionando bibliotecas externas

 

Uma vez que feitos todos esses passos, o FreeRTOS já está pronto para ser utilizado, basta que a biblioteca FreeRTOS.h seja incluída no arquivo principal, assim como as funcionalidades a serem utilizadas, task (task.h), queue (queue.h), semaphore (semphr.h), etc. O arquivo que contém a função principal é o arquivo (FreeRTOS_Teste.c), localizado na pasta “Sources” do projeto.

 

Para exemplificar, serão criadas duas tasks, uma responsável por piscar uma das cores do LED RGB presente na placa, outra responsável por ler um botão conectado a uma entrada digital e alterar qual dos LED’s será aceso pela primeira task.

 

Serão criadas duas “bibliotecas”, isso pode ser feito clicando com o botão direito sobre a pasta na qual se deseja guardar os arquivos, New->Source e New->Header. Elas serão as seguintes:

 

 

O propósito da biblioteca “button.h” é tratar da entrada digital onde será conectado um botão.

 

A função bInit() faz a inicialização da porta, configurando-a como entrada e ativando o resistor interno de pull-up, que faz com que, quando nada conectado à porta, ela tenha nível lógico alto.

 

A função bDebounce() foi implementada de maneira semelhante à implementada em um de meus artigos intitulado Tinkercad e PQDB: Teclado matricial, em que analisa a estabilidade do botão durante 42 (static uint8_t tempo) chamadas da função bDebounce, já que, por se tratar de um botão físico, sofre do efeito de bouncing, uma oscilação no sinal, já que o contato não é idealmente fechado, exatamente como é explicado pelo professor Rodrigo Almeida no artigo “Leitura de chaves mecânicas e o processo de debounce”.

 

A função bRead() retorna o estado do botão atualizado por bDebounce().

 

A biblioteca “gpio_x.h” manipula as entradas e saídas digitais do microcontrolador, configurando-as de maneira semelhante à feita por Evandro Teixeira em sua série de artigos onde implementa as Bibliotecas de Software para FRDM-KL25Z.

 

A biblioteca "fsl_device_registers.h" possui o mapeamento dos registradores do microcontrolador e as definições de tipo como o uint8_t, um inteiro, sem sinal e com 8 bits.

 

 

A biblioteca “ledState.h” é utilizada apenas para evitar utilização de uma variável global e faz com que o valor da variável state seja lido e alterado apenas por meio das funções getState() e setState(), respectivamente, de maneira semelhante como é feito o acesso à variáveis privadas de classes, em linguagens de programação orientadas a objeto.

 

 

A função main, cria um semáforo do tipo mutex (mutuamente exclusivo), que garante que o acesso à variável state, que indica qual dos LED’s será ativado, seja feito apenas por uma tarefa por vez. São criadas duas tasks (tarefas), blink_task e button_task, ambas com o tamanho de pilha mínimo, sem parâmetros, mas com prioridades diferentes. A macro tskIDLE_PRIORITY representa a prioridade da Idle Task, que é a task com menor prioridade, a qual é executada quando nenhuma outra é.

 

A task blink_task tem prioridade (tskIDLE_PRIORITY + 2), e a task button_task tem prioridade (tskIDLE_PRIORITY + 1), isso faz com que, quando o kernel tem que tomar uma decisão para definir qual das tarefas será executada no momento, blink_task será executada, já que possui maior prioridade.

 

vTaskStartScheduler() dá início ao scheduler do RTOS, dando ao kernel o controle sobre qual das tarefas é executada e quando.

 

A tarefa blink_task inicializa as saídas digitais correspondentes e, em seu loop infinito, realiza acesso à variável state e pisca o LED correspondente a seu valor. Ao fazer esse acesso, ela liga o mutex (xSemaphoreTake) de maneira que, se alguma outra task necessitar realizar o acesso à mesma variável, ele seja bloqueado, até que este semáforo seja desbloqueado (xSemaphoreGive). Após esta decisão, a task é colocada em modo sleep(vTaskDelay) até que, após 500 ms, sua execução seja retomada, piscando o LED.

 

A tarefa button_task inicializa o botão e, em seu loop infinito, executa a rotina de debounce, analisando o comportamento da porta digital a qual o botão está conectado, atualizando a variável state no momento em que é detectado o pressionamento do botão, protegendo, novamente, o acesso à variável state por meio do semáforo mutex.

 

Para compilar o código e enviá-lo ao microcontrolador, podem ser utilizadas tanto a opção de flash, que apenas envia o código, como a opção de debug, que possui algumas funcionalidades como a parada em break points, o acompanhamento da execução do código linha a linha, etc.

 

Flash Tool
Figura 9: Flash Tool
Debug
Figura 10: Debug

 

Obs.: Como o bootloader instalado na placa é o PEmicro, esta opção deve ser selecionada em ambos os modos de execução.

 

Funcionamento
Figura 11: Funcionamento

 

Todos os códigos podem ser acessados em meu GitHub.

 

Conclusões

 

Um RTOS facilita o desenvolvimento de aplicações embarcadas, mas em contrapartida, ao abstrair as camadas de processamento, acaba gastando mais recursos, portanto é indicado para projetos cuja complexidade esteja de acordo.

 

Neste artigo foram apresentados alguns conceitos básicos com relação ao funcionamento de um sistema operacional de tempo-real. Foram também exploradas particularidades sobre a utilização do FreeRTOS, criação de tarefas e mutexes, e sua utilização na implementação de códigos com a Freedom Board KL25Z, Kinetis Software Development Kit (KSDK v2.2.0) e a IDE MCUXpresso.

 

No próximo artigo abordaremos a utilização da biblioteca de acesso ao DAC e ADC, bem como a implementação da execução de sistemas dinâmicos baseados em equações de diferenças.

 

 

Referências

 

Desenvolvendo um RTOS

Desenvolvimento de SW embarcado: do baremetal ao RTOS

FreeRTOS

Bibliotecas de Software para FRDM-KL25Z

Leitura de chaves mecânicas e o processo de debounce

Tinkercad e PQDB: Teclado matricial

Outros artigos da série

Sistemas Dinâmicos e Equações de Diferenças com a FRDM KL25Z >>
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.

Thiago Pereira do Prado
Graduando em Engenharia de Controle e Automação pela Universidade Federal de Itajubá. Aficionado por Tecnologia, Programação e Sistemas Embarcados. Desde cedo era curioso por saber como as coisas funcionavam. Desmontava vários drivers de DVD e carrinhos de controle remoto atrás dos motores DC. Atualmente pesquiso na área de sistemas dinâmicos, controladores e filtros digitais.

2
Deixe um comentário

avatar
 
1 Comment threads
1 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Thiago Pereira do PradoFábio Souza Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Fábio Souza
Visitante

Excelente tutorial. Parabéns Thiago!