Criando seu próprio shell para sistemas embarcados

Neste artigo usaremos o Kit NUCLEO-F446RE da ST para demonstrar o uso da lib micro-shell. Mostraremos como criar, receber e tratar comandos vindos pela porta serial.

 

Usaremos o CubeMX para gerar o código de inicialização e a IDE Atollic para programar nosso Kit com o suporte ao sistema operacional FreeRTOS.

 

A biblioteca micro-shell usada neste artigo foi baseada na lib-shell criada originalmente pelo Felipe Neves.

 

 

O Problema

 

Muitas vezes durante o processo de desenvolvimento, chegamos ao instante em que precisamos enviar comandos ao nosso microcontrolador.

 

A primeira opção seria enviar caracteres simples para controle on/off. Se precisarmos indicar o valor de um set point acabamos combinando letras e números como “S:135\n”. Existem várias formas de fazer isso, porém, muitos desses métodos são bem simples e muitas vezes precisamos enviar várias sequências de comandos para realizar uma única configuração.

 

A segunda opção seria usar um protocolo industrial como o modbus. Porém não basta implementar o protocolo do lado do micro, também é preciso implementar o protocolo do lado do software. Isso pode levar muito tempo e dependendo da aplicação é inviável.

 

 

A Solução

 

A solução parece óbvia: por que não implementar uma lib que conseguisse replicar o que o shell do linux faz em minha aplicação embarcada?

 

No mundo Unix, o termo Shell é mais usualmente utilizado para se referir aos programas de sistemas do tipo Unix que podem ser utilizados como meio de interação entre interface de usuário para o acesso a serviços do kernel no sistema operacional. Este é um programa que recebe, interpreta e executa os comandos de usuário, aparecendo na tela como uma linha de comandos, representada por um interpretador de comandos, que aguarda na tela os comandos do usuário. (Fonte: wikipedia)

 

Conversando com o Felipe descobri a biblioteca que ele tinha montado. Acabei alterando a biblioteca original dele para usá-la com FreeRTOS, e esta é a solução que está sendo compartilhada neste artigo.

 

 

Principais Funções da Lib Micro-Shell

 

Abaixo descreveremos um pouco as funções da lib micro-shell.

 

Macro SHELL_PRINTF: esta macro é usada para indicar qual função será usada como output das respostas do micro-shell. Em nosso exemplo usaremos uma saída serial, mas nada o impede de usar outro tipo de saída, como por exemplo ethernet, usb, etc.

 

vTaskMicroShell_init: Função usada para criar a task que trata os comandos vindos pela serial e verificar se eles são válidos ou não.

 

Obs: Ocasionalmente pode acontecer Stack Overflow ao criar a task; para corrigir isso será preciso aumentar o tamanho da stack usada pela task, que é feito através do parâmetro de entrada multi_stack_size.

 

vTaskShell: Task da aplicação micro-shell, é usado um semáforo binário para acordar e sinalizar a task, para informar que existe um pacote e ele precisa ser tratado.

 

shell_parser: Função que realiza toda a mágica de parse do pacote recebido. Obs: dedique um tempo para entender bem esta função, ela pode lhe agregar bastante conhecimento.

 

shell_getc: Função usada para armazenar o byte recebido pela serial, e internamente controla a montagem do pacote recebido. Ao receber o caractere “\n” ou “\r” ele sinaliza a task principal que chegou um comando e que ele precisa ser tratado.


shell_isr_getc: Função parecida com a shell_getc, esta função deve ser usada somente quando a recepção do byte é feita dentro de uma interrupção.

 

shell_callback: Esta função deve ser implementada por sua aplicação. Após a lib micro-shell tratar e separar as sintaxes do comando recebido, esta função é chamada para você poder tratar cada dado individualmente.

 

 

Rodando o Exemplo

 

No código de exemplo, implementamos um caso de uso onde esta biblioteca pode ser bem útil. O exemplo consiste em informar a sua aplicação IoT, a rede, e o host que deseja se conectar.

 

O código abaixo mostra a implementação de nossa aplicação dentro da callback ‘shell_callback”, a variável cmd é a string com o comando principal. A variável argc contém o número de argumentos recebidos e a variável argv contém a string dos argumentos já separados na forma de vetor.

 

 

A tabela abaixo mostra como o comando é recebido, armazenado e disponibilizado nas variáveis cmd e argv. Para este exemplo, o número de argumentos da variável argc é 4 (argv[0-3]).

 

cmd

argv[0]

argv[1]

argv[2]

argv[3]

Caractere de fim de pacote

rede

-w

@Casa

-pwd

123456789

\n ou \r

 

 

A figura abaixo mostra a troca de mensagens entre o microcontrolador e o usuário.

 

Troca de mensagens entre o usuário e a aplicação.

Ao enviar um comando com sintaxe errada podemos ver a aplicação informando a mensagens “(X) Sintax error”.

 

Conclusão

 

Neste artigo vimos como usar a lib micro-shell, suas principais vantagens e como usar suas principais funções para aquisitar e tratar diferentes tipos de comandos. Uma segunda opção a esta biblioteca é a lib CLI do FreeRTOS.

 

Se você gostou do artigo ou tem algo a acrescentar deixe seus comentários.

 

Código Fonte

 

No link abaixo segue o código fonte do exemplo mostrado em este artigo.

https://github.com/JorgeGzm/STM32-Micro-Shell

 

 

Referências


https://pt.wikipedia.org/wiki/Shell_(computa%C3%A7%C3%A3o)

https://os.mbed.com/users/uLipe/code/TEN_mbedos_simple_shell/file/1e8461adc480/shell.cpp/

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.

Jorge Guzman
Sou formado em engenharia da computação com pós-graduação em automação industrial e engenharia de software. Possuo experiência no desenvolvimento de hardware, firmware, distribuições Linux e software para sistemas embarcados. Sou adepto ao compartilhamento do conhecimento e totalmente contra a metodologia de desenvolvimento GHP (Go Horse Process) em projetos.

2
Deixe um comentário

avatar
 
2 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Wellington BianchiniMarco Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Wellington Bianchini
Membro

Parabéns pelo artigo!

Marco
Visitante
Marco

Um dos problemas muito peculiares em comunicação UART no uso de microcontroladores, perda de dados. Uma boa dica, parabéns .