Neste artigo explicaremos o que é a biblioteca RTT (Real Time Transfer) da SEGGER e como ela pode nos ajudar, durante o período de desenvolvimento, a transmitir dados críticos em tempo real sem prejudicar o desempenho de nossa aplicação. Usaremos o Kit SMT32F429 Discovery e a IDE Atollic para mostrar como usar a lib RTT. Este artigo é uma continuação do artigo Convertendo ST-Link em um J-link.
RTT
A biblioteca RTT (Real Time Transfer) possibilita transferir dados em alta velocidade entre o Host (PC) e o target (microcontrolador). Esta tecnologia não usa nenhum pino adicional do microcontrolador como uma UART, conexão SWO ou semihost; ela se dá apenas entre uma região de memória RAM do microcontrolador e o J-Link. A lib RTT armazena as strings de saída nessa região de memória usando uma rotina de memcpy; posteriormente essas strings são enviadas ao J-Link via SWD ou JTAG (Protocolos de debug).
A velocidade máxima de envio de dados depende do tamanho do buffer e da taxa de comunicação do J-Link com o microcontrolador. Abaixo podemos ver que o RTT gasta 1 microssegundo para enviar 82 caracteres com o microcontrolador rodando a 168 MHz; em contraponto, a conexão SWO gasta 120 microsegundos, e a conexão semihost gasta 10,7 milisegundos.
Bem rápido né!
A biblioteca RTT usa em torno de 500 Bytes de ROM e 24 Bytes ID + 24 Bytes por canal para o bloco de controle na RAM. Cada canal requer uma quantidade de memória para o buffer. Os tamanhos recomendados são 1 kByte para canais ascendentes e 16 a 32 Bytes para canais descendentes, dependendo da carga de entrada / saída.
Principais funções da biblioteca
A biblioteca disponibiliza diversas funções para enviar e receber dados, as principais são:
- Função SEGGER_RTT_init: Inicializa a estrutura do bloco de controle RTT ao usar somente destinos de RAM.
- Função SEGGER_RTT_printf: Com ela é possível transmitir mensagens formatadas; ela suporta o print dos seguintes tipos de argumentos:
- %c: char
- %d: signed integer
- %u: unsigned integer
- %x: hexadecimal
- %s: string
- %p: ponteiro
Ex:
SEGGER_RTT_printf (0, "Hello World %s", "from SEGGER!\r\n");
- Função SEGGER_RTT_Write (é uma segunda opção para transmitir dados).
Ex:
uint8_t payload[30], len; len = sprintf(payload, “%s”, “Hello World from SEGGER!\r\n”); SEGGER_RTT_Write (0, payload, len);
- Função SEGGER_RTT_Read: Com ela é possível receber mensagens.
Para ver mais detalhes de todas as funções acesse o manual da biblioteca RTT no capítulo 14.
Porte da biblioteca RTT
Neste exemplo estaremos usando o ambiente Ubuntu/Linux 16.04, o kit Discovery STM32F429 e a IDE de desenvolvimento Atollic.
Acesse a pasta J-Link e procure o arquivo SEGGER_RTT_V634h.tgz.
Após descompactar a pasta e ter acesso ao seu conteúdo, criaremos uma pasta chamada Application e dentro dela enviaremos os arquivos necessários para rodar a lib RTT em nossa aplicação. Os arquivos app_rtt.c e app_rtt.h conterão as funções app_rtt_run_ex1 e app_rtt_run_ex2 com os exemplos contidos na pasta Examples.
Crie um projeto simples e adicione a pasta Application ao seu projeto. Na função main realize a chamada das nossas 2 funções de exemplo: app_rtt_run_ex1 e app_rtt_run_ex2.
Acessando os dados enviados ao Host
Existem 3 formas de acessar os dados enviados pelo microcontrolador ao Host, são elas: via conexão Telnet; página web com J-Link Web control panel; e usando o software J-Link RTT Viewer (funciona apenas em máquinas Windows). Nesta etapa usaremos somente o exemplo da função app_rtt_run_ex1.
1 – Telnet
Durante o período de debug usando o J-Link acesse a aba Terminal do Atollic e crie uma conexão Telnet como mostra a figura abaixo:
Inicie o debug. Abaixo executamos a aplicação app_rtt_run_ex1(). Esta função usa o exemplo contido no arquivo Main_RTT_PrintfTest.c. Na figura abaixo podemos ver os dados sendo recebidos via conexão Telnet.
2 – J-Link Web Control Panel
Uma segunda forma de receber os dados do RTT é via browser. Acessando o endereço 127.0.0.1:19080 na aba RTT podemos visualizar os mesmos dados sendo recebidos.
3 – J-Link RTT Viewer (funciona somente em ambiente Windows)
Realize o download do arquivo JLink_Windows_V635g.exe no site da Segger. Após instalar o pacote você terá acesso às ferramentas disponibilizadas pela SEGGER para serem usadas com o J-Link. Estamos usando uma versão lite do J-Link, portanto alguns recursos podem ser limitados.
Também é possível customizar o formato de saída das mensagens como mostra a imagem abaixo, para mais informações acesse o link.
Extra: Redirecionando a saída de conexão Telnet a uma porta serial Virtual
Vão existir momentos nos quais vamos querer ver a variação de um sinal na forma de gráficos, e infelizmente nenhuma das situações acima vai nos possibilitar isso. Uma forma de fazê-lo é usar o SerialPlot, mas como jogar a saída e entrada de uma conexão Telnet a uma conexão serial? Felizmente para resolver isso podemos usar a ferramenta socat.
Instale o pacote socat:
$ sudo apt-get install socat
Nesta parte focaremos na função app_rtt_run_ex2, ela transmitirá dados aleatórios gerados pelo RNG do microcontrolador.
void app_rtt_run_ex2(RNG_HandleTypeDef *rng)
{
float value = 0;
uint16_t len = 0;
uint8_t payload[20];
SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
while(1)
{
value = (HAL_RNG_GetRandomNumber(rng) & 0x0000FFFF) * M_PI;
len = sprintf((char*)payload, "%.2f\n", value);
SEGGER_RTT_Write(0, (const char*)payload, len);
HAL_Delay(20);
}
}
Infelizmente como vimos acima a função SEGGER_RTT_printf não suporta a formatação %f usada para imprimir variáveis do tipo float. Para resolver isso habilitamos esse recurso no compilador e usaremos a função sprintf.
Para habilitar o recurso adicione o comando -u _printf_float nas propriedades de compilação do projeto como mostra a figura abaixo.
Agora, durante o período de debug, execute o comando abaixo para redirecionar a saída da conexão Telnet à porta serial virtual /dev/ttyS1.
$ sudo socat -d -d pty,link=/dev/ttyS1,raw,echo=0,waitslave tcp:127.0.0.1:19021
Em seguida abra outro terminal e libere os recursos de escrita e leitura para seu usuário na porta ttyS1.
$ sudo chmod 777 /dev/ttyS1
Feito isso, estabeleça uma conexão na porta /dev/ttyS1 usando o SerialPlot. A imagem abaixo mostra os dados aleatórios gerados e transmitidos via RTT e recebidos via SerialPlot.
Conclusão
Neste artigo explicamos um pouco como funciona a biblioteca RTT da SEGGER, como adicioná-la e usá-la em um projeto usando o Kit SMT32F429 discovery e a IDE Atollic. Vimos 3 formas diferentes de receber esses dados e como redirecionar a saída Telnet para uma porta serial virtual.
Vantagens:
- É uma ferramenta confiável para transmitir dados críticos em tempo real;
- A velocidade de transmissão via RTT é muito maior comparada à uma transmissão via UART, SWO ou semihost.
Desvantagens:
- Ela só pode ser usada em modo de debug com o J-Link;
- Dependendo do número de canais criados há um consumo considerável de memória RAM. (Neste artigo usamos o canal default zero para transmitir os dados);
- Por estarmos usando uma versão limitada do J-Link para os kits da ST alguns recursos dos softwares também são limitados.
Extra:
Durante escrita deste artigo percebi a existência de um arquivo chamado JLinkARM.dll na pasta JLink_V635g. Lendo mais a respeito eu vi que a SEGGER possui um SDK que nos possibilita usar essa dll em suas aplicações C#, C++, Visual Basic, etc. Ela nos permite criar aplicações de gravação e leitura da flash e RAM, visualizar variáveis em run time durante o debug, e até mesmo ferramentas de automação de testes e validação. Para mais informações acesse o link.
Código fonte:
https://github.com/JorgeGzm/STM32-RTT
Saiba mais
Debug Remoto na Raspberry Pi através do Plugin Pydev do Eclipse
Utilizando a UART da FRDM-K64F com o componente fsl_debug_console
Referências:






















