Tutorial – Sistema REPL com linha de comando para kit Tiva Launchpad

No artigo [1], foi apresentada a estrutura básica de um sistema de leitura/avaliação/impressão de comandos e respostas para testar ideias em projetos que necessitem de interação entre homem (usuário) e máquina (sistema embarcado). O artigo de hoje pretende apresentar a você leitor a implementação deste sistema no kit Tiva Launchpad [2] e um exemplo-guia para implementar comandos na plataforma.

 

Para implementar este projeto, utilizaremos a plataforma open source criada em [3]. Ela é composta pelas seguintes ferramentas:
– IDE (Eclipse Mars 4.5.2);
– Compilador (gcc-arm-none-eabi-5_3-2016q1-20160330-win32);
– Biblioteca Tivaware 2.1.2.111;
– Windows Build Tools (“make.exe” e “rm.exe”);
– LM Flash Programmer;
– Drivers para o kit Tiva Launchpad;

1) Estrutura do sistema REPL

A figura 1 mostra um diagrama conceitual do sistema REPL implementado no kit Tiva.
art06_fig01Figura 1 – Estrutura do sistema REPL implementado no kit Tiva Launchpad.

 

No main.c, encontra-se as principais funções do projeto. Elas podem ser divididas em duas seções conforme comentários – a primeira corresponde à configuração do microcontrolador (Config) e a segunda à execução do laço infinito do programa (Loop), conforme Figura 2.
art06_fig02
Figura 2 – Arquivo main.c, funções de configuração e execução do sistema REPL.
A biblioteca Config tem como propósito configurar todos os periféricos necessários para o funcionamento do kit e conexão entre este e o sistema hospedeiro (computador). Ela é sub-dividida em duas bibliotecas – Core e Comm. A biblioteca Core armazena as funções de configuração do núcleo do microcontrolador, enquanto que a biblioteca Comm possui as funções responsáveis por configurar o periférico de comunicação entre kit e computador, neste caso a interface serial UART, que opera através da porta USB (Debug) do kit.

 

Na seção de configuração, o microcontrolador é configurado com clock igual a 80 MHz (função ConfigLib_CoreClock_Set80MHz()) e o periférico UART0 é escolhido e configurado (função ConfigLib_Comm_UART0Config()) para realizar a comunicação com o PC através da porta USB do kit com taxa de transmissão igual a 115.000 bps. Para a configuração e comunicação com interface de linha de comando, um driver chamado “uartsdio” fornecido pela Texas Instruments através da Tivaware é utilizado neste projeto. Com ele, é possível não somente configurar o periférico UART como também capturar e imprimir caracteres, strings e outros tipos de dados com as funções UARTgets() e UARTprintf(), respectivamente. A última função deste bloco (IntMasterEnable()) habilita as interrupções dos periféricos utilizados para o processador, mais especificamente as interrupções da UART0.

 

A biblioteca REPL (REPL.c e REPL.h) contêm o laço principal do programa (função REPL_MainLoop()) com as funções que realizam a leitura, avaliação dos comandos e impressão dos resultados (Figura 3).
art06_fig03
Figura 3 – Laço principal do sistema REPL implementado na função REPL_MainLoop().

 

As funções de etapa do sistema REPL são armazenadas separadamente em bibliotecas (pastas Read, Eval e Print) para facilitar o entendimento do programa e deixá-lo mais organizado e modular. Dentre estas bibliotecas, a biblioteca Read (Figura 4) possui as funções que capturam e enviam os caracteres digitados pelo usuário na linha de comando para as funções da biblioteca Eval. A função UARTpeek() é empregada para detectar todos os caracteres digitados até o Enter. Depois, a função UARTgets() armazena os caracteres digitados em um buffer (g_cInput) para processamento pela biblioteca Eval.
art06_fig04
Figura 4 – Função LoopLib_Read().

 

Utilizando os caracteres digitados e armazenados no buffer, a função LoopLib_Evaluate() (Figura 5) retorna o código do comando equivalente caso este exista na tabela de comandos (Commands.c). Para isto é utilizada outra biblioteca fornecida pela Texas Instruments denominada “cmdline”. Com esta biblioteca é possível buscar e chamar as funções fornecidas pelos comandos declarados em um estrutura de comandos (Figura 6). A função LoopLib_Evaluate() retorna um valor decimal inteiro com sinal de 32 bits referente ao código do comando identificado. Os códigos negativos correspondem a mensagens de erro, enquanto que os códigos inteiros positivos correspondem aos comandos.
art06_fig05
Figura 5 – Função LoopLib_Evaluate().
 art06_fig06
Figura 6 – Lista de comandos implementados no projeto.

 

A seguir, a biblioteca Print é chamada (função LoopLib_Print()) para identificar o código do comando retornado pela função LoopLib_Evaluate() (variável i32_CommandStatus) e enviar a resposta apropriada (e formatada) ao usuário. Neste tutorial três comandos foram implementados: “help” (imprime o menu de funções), “clear” (limpa a tela) e “clock” (imprime o valor do clock do microcontrolador, em Hz). A função LoopLib_Print() implementa uma máquina de estados que identifica o código do comando digitado e identificado e chama a função que imprime a resposta deste comando (Figura 7).
art06_fig07
Figura 7 – Função LoopLib_Print().

 

A função LoopLib_Print() chama as funções das respostas formatadas (biblioteca Screen.c), que por sua vez podem chamar strings definidas para as linhas de cada resposta (Lines.h). Como exemplo de função que imprime resposta de comando, a função CoreClock_Screen() é mostrada na Figura 8.
art06_fig08
Figura 8 – Função CoreClock_Screen().

2) Tutorial: implementando comando para medição de temperatura

A seguir, será descrita passo a passo a implementação de uma função para medição de temperatura do núcleo do microcontrolador. Esta seção servirá como tutorial para você implementar ideias utilizando este template.

 

2.1) Configuração do periférico ADC

 

Antes de implementar a função para medir a temperatura, precisamos criar uma função para configurar e ativar o sensor de temperatura presente no kit. Este sensor encontra-se no processador e está conectado ao periférico ADC0. A função ConfigLib_Temp_ADC0Set() realiza a configuração desejada para o sensor (Figura 9). Para maiores esclarecimentos acerca dos detalhes de configuração do periférico ADC0, consulte [4] e [5].
art06_fig09
Figura 9 – Configuração do periférico ADC0;

 

2.2) Definindo o comando para medição

 

Após definida a função de configuração do periférico, é preciso definir o comando para medição da temperatura na biblioteca de comandos (Commands.c). Inicialmente, define-se a entrada para a estrutura, contendo a string que chamará o comando (“temp”), o callback para a função do comando (CMD_temp) e o texto descrevendo o comando, respectivamente (Figura 10).
art06_fig10
Figura 10 – Variáveis do comando “temp” declaradas na estrutura de comandos.

 

Após, declara-se a função CMD_temp() na mesma biblioteca (Figura 11). Ela deverá chamar uma função capaz de medir e armazenar a temperatura (ConfigLib_Temp_Measure()), e deverá ser implementada na biblioteca “Temp” (Figura 12). Esta função mede e armazena separadamente a parte integral e a parte decimal da temperatura para possibilitar o emprego da função UARTprintf() sem erros.
art06_fig11
Figura 11 – Implementação da função CMD_temp().
art06_fig12
Figura 12 – Função para medição da temperatura.

 

2.3) Definindo o código de resposta para comando

 

Após criadas as funções do comando e da medição de temperatura, devemos definir o código de resposta para o comando “temp”. Isto é feito através do retorno da função CMD_temp (Figura 11), que deverá retornar um valor único a ser reconhecido pela máquina de estados da função de impressão de respostas. Neste projeto definiu-se CMD_TEMP igual a 4 como código de retorno do comando (Figura 13).
art06_fig13
Figura 13 – Código de retorno para função chamada.

 

2.4) Definindo a função de resposta para o comando  
Com o código para resposta do comando definido, é hora de implementar a chamada condicional da função na biblioteca Print e a função para imprimir a resposta do comando “temp” (Figuras 14 e 15).

 

art06_fig14
Figura 14 – Processamento do código de retorno do comando (chamada da tela de resposta).

 

art06_fig15  Figura 15 – Tela de resposta para o comando “temp”.

 

Após estes passos, verifique a inclusão das bibliotecas e a declaração dos protótipo das funções. Compile o projeto e caso não dê nenhum erro ou aviso, é possível gravar e testar a nova função implementada com LM Flash Programmer. O código deste projeto está disponível para download em http://bit.ly/REPL_Tiva_github e poderá ser usado para qualquer fim não comercial, desde que seja citada a fonte.

 

Fique à vontade para compartilhar suas dúvidas, críticas e sugestões abaixo e continue acompanhando as postagens do blog. Até o próximo artigo!

– REFERÊNCIAS

Deixe um comentário