Manual
do
Maker
.
com
Particularmente estou dando os primeiros passos com openOCD, do qual pretendo escrever alguns artigos. Ainda assim, é tanta coisa que não dará pra abordar tudo, mas vamos ver o suficiente para usá-lo satisfatoriamente.
O propósito é utilizá-lo como interface para o JLink e então usar o GDB para fazer debug. O GDB é o que já usamos para debug no Linux tradicionalmente, a diferença está no modo de utilizá-lo, mas nem é tanta diferença também.
Os detalhes que podem ser úteis para um trabalho universitário podem ser vistos no about. Basicamente, o OpenOCD (Open On-Chip Debugger) é uma ferramenta que faz interface de depuração, programação in-system e testes boundary-scan em dispositivos embarcados.
Vou enfatizar mais vezes: São os primeiros passos com OpenOCD porque são "meus" primeiros passos. Se você já conhece a ferramenta e quiser auxiliar com dicas, comentem no instagram ou youtube (links ao final do artigo).
O OpenOCD não faz tudo sozinho. Ele é uma interface intermediária a um dispositivo, e a escolha desse dispositivo deve levar em consideração alguns parâmetros.
O foco do OpenOCD é JTAG. Se precisa interfacear com um dispositivo JTAG, está no caminho certo. Outros meios de transporte são o SPI e o SWD, por exemplo.
O Raspberry Pi Pico tem uma interface SWD, assim como a BluePill, que serão as MCUs mais utilizadas em artigos posteriores.
O dispositivo pode ter diferentes tensões, sendo 1.8V, 2.8V, 3.3V ou 5V. O JTAG JLink é o que utilizaremos em nossos primeiros passos com OpenOCD nos artigos, sendo que ele suporta uma boa série da familia ARM, entre eles, o Cortex-M0 (RP Pico) e o Cortex-M3 (BluePill). Seu nível lógico é 3v3.
O JLink tem um conector de 20 pinos. Existem outros tipos de comunicação, mas confesso só ter visto ethernet e USB. No caso do JLink, a conexão é USB.
O JLink é um JTAG para a família ARM, por isso ele tem o chamado "clock adaptativo" - o RTCK.
Diversos dongles USB são baseados no FTDI ("Future Technology Devices International"), conhecido como FT2232. Em meados de 2012, uma nova variante surgiu - o FT2232H. Os dispositivos JTAG que usam FT2232H ou FT232H podem suportar clock adaptativo.
O FT2232H possui dois canais de comunicação, e um deles pode ser usado como interface UART, ao mesmo tempo que a outra é usada para fazer depuração. Algumas placas de desenvolvimento integram o FT2232 como uma solução de depuração de baixo custo usando USB-Serial.
O OpenOCD usa um interpretador Tcl conhecido como Jim-Tcl. Essa linguagem de programação oferece um interpretador de comandos simples e extensível.
Podemos usar Tcl como comandos simples sem precisar aprender muito sobre Tcl, ou então podemos escrever programas para automatizar as tarefas.
Se tem interesse em se aprofundar no assunto, o site do Jim-Tcl é a melhor opção para aprender Tcl. O site não tem SSL, mas também não há importância nisso.
As configurações do OpenOCD são scripts Jim-Tcl. O interpretador de comandos do OpenOCD é hoje uma mistura de Jim-Tcl e do interpretador de comandos original do projeto OpenOCD.
Podemos digitar diversos comandos por linha de comando através de telnet ou via monitor do GDB.
Se não forem passados parâmetros através das flags -f (para indicar arquivos de configuração) ou -c (para indicar comando por linha), o OpenOCD tentará ler o arquivo openocd.cfg. Podemos passar mais de um arquivo de configuração, como veremos ao executar o OpenOCD com a RP Pico.
Mais uma vez: são os primeiros passos com OpenOCD, e posso cometer alguns erros (como penso que o fiz), mas coloquei a coisa pra funcionar e já me motivou um bocado.
Por padrão o arquivo é procurado no diretório corrente (se não indicado), então no diretório de scripts e o último lugar importante, no home do usuário, no diretório oculto do programa (~/.openocd).
No melhor dos casos, teremos dois scripts para fazer a interação com um dispositivo através de um JTAG. A linha de comando para iniciar o OpenOCD para depurar uma Raspberry Pi Pico deve ser algo como:
openocd -f interface/blackmagic.cfg -f target/rp2040.cfg
No caso, passamos os dois arquivos de configuração necessários: o primeiro é o adaptador e o segundo é a placa alvo. Repare que a diferença está não apenas no nome do arquivo, mas também no diretório base. Se compilou o OpenOCD conforme o artigo "Como programar a Raspberry Pi Pico no Linux", deverá existir em seu home o diretório pico/openocd. Dentro dele temos o diretório tcl e dentro deste último diretório, temos os diretórios interface e board.
Se quiser saber quais são os JTAGs suportados, basta listar o diretório interface e para as placas, liste o diretório boards.
Para fazer o primeiro teste, optei por algo mais simples ainda, que foi utilizar o JLink no STM32F103, como feito com o firmware Black Magic Probe em um BluePill. A linha de comando é parecida, mas tive que fazer algumas modificações em ambos os arquivos. O processo está descrito mais adiante.
Já vimos que podemos executá-lo com linha de comando ou passando arquivos de configuração. Quando iniciado, ele inicia como um servidor, mas ele pode executar algumas ações sem iniciar como um servidor também.
A conexão ao OpenOCD quando está sendo executado como um servidor pode se ser feita através de Telnet, GDB ou RPC. Podemos criar programas que façam interface com esses canais, mas vamos focar primeiramente no padrão, para que saibamos como agir em caso de alguma anomalia.
Se a configuração padrão não for suficiente, se algo der errado, como detectar um problema? Bem, ao tentar interfacear com um dispositivo, sendo uma anomalia simples (por exemplo, ausência de comandos no arquivo de configuração ou typo), podemos utilizar a flag -d para ter uma saída detalhada da execução do comando e assim facilitar a identificação de um problema na tentativa de conexão.
Se o dispositivo alvo não estiver configurado corretamente, o JTAG poderá ficar irresponsivo até que o alvo esteja devidamente configurado, por exemplo, através dos comandos do monitor, no GDB, em um arquivo ~/.gdbinit.
Não é exatamente "do" OpenOCD, mas "para" o OpenOCD. O arquivo de configurações do usuário engloba todas as partes do projeto em um só lugar. Idealmente, o arquivo de configuração já deve vir pronto, como por exemplo, os do próprio OpenOCD, ou de algum vendedor de placas ou JTAGs.
Existem 3 outros tipos de configuração que n ão são parte do usuário:
O melhor caso é quando incluímos apenas 2 arquivos: interface e board. Nesse caso, eles manipulam todas as coisas necessárias.
No arquivo de interface temos a indicação do adaptador JTAG que, no meu caso, será o JLINK. O segundo arquivo será a especificação da placa, que se encarregará de ajustar o TAP e alvos GDB. Se fôssemos incluí-los em um script, usaríamos a palavra reservada source dessa maneira:
source [find interface/olimex-jtag-tiny.cfg]
source [find board/csb337.cfg]
Vou exemplificar a configuração que fiz no arquivo interface/jlink.cfg nesses primeiros passos com OpenOCD, e continuar com informações técnicas que considero importantes em outro artigo.
Ao conectar o JTAG no computador, consultei os eventos do sistema com o comando dmesg. A partir dele vi que o JLink havia sido reconhecido adequadamente:
Então comecei a testar a inicialização do dispositivo. Primeiramente, com o comando openocd -f interface/jlink.cfg:
Repare que houve "1" erro, apesar de 3 linhas informando. A mensagem claramente mostra o parâmetro que deve ser adicionado ao arquivo jlink.cfg para resolver o problema. Adicionei então o valor adapter speed 4000 ao arquivo e executei novamente o mesmo comando:
Agora faltou o quê? Repare na mensagem: passamos por vários pontos e o erro informa que faltou indicar o transport. Ainda deu as opções possíveis. Como poderia ser mais fácil?
Adicionei então o parâmetro tranport select swd, já que SWD é o que utilizaremos tanto no Raspberry Pi Pico como no BluePill (STM32F103).
O arquivo ficou assim:
adapter driver jlink
adapter speed 4000
transport select swd
E a execução sucedeu sem problemas. Mas ainda faltam algumas coisinhas.
Antes de seguir, fiz um teste de conexão com telnet:
Ok, conectou sem problemas!
Agora quero me conectar ao BluePill, como fizemos no artigo de "Comandos GDB para usar com BluePill". Dentro de boards temos a stm32f1x.cfg para esse propósito, mas também precisará de uma pequena modificação. O comando ficou assim:
sudo openocd -f interface/jlink.cfg -f target/stm32f1x.cfg \ -c "telnet_port 4444"
Haverá um erro relacionado aos argumentos. O que fiz para esse debug foi usar -disable no lugar dos argumentos, mas não é a melhor opção. O ideal é executar o debug no OpenOCD (com a flag -d) e verificar onde exatamente está o erro. Mas o que queria era comprovar que o JLink funcionaria.
Faltou alguma coisa no parâmetro porque o comportamento ficou "esquisito". Não consegui carregar os símbolos, mas consegui executar com breaks. Para usar watch, precisei fazer um cast no tipo:
Isso já é o suficiente para os primeiros passos com OpenOCD, mas há muito pela frente.
Na documentação oficial do OpenOCD você encontrará mais de 170 páginas de configurações e instruções. É realmente esclarecedor, recomendo a leitura (em inglês). Como fico ansioso com coisas divertidas como essa, até o momento li só 30 páginas. Tem muita coisa ainda e talvez ainda aborde de outra maneira o OpenOCD!
Estou aprendendo sobre JTAG agora, gatinhando ainda. Foi bastante fácil utilizar o firmware do Black Magic Probe no BluePill para programar outro STM32F103. Já para fazer o debug com o JLink é um pouco mais difícil, tem coisas que ainda não tenho o conceito, mas devagar chegamos lá. Esse JTAG Jlink você encontra na Shopee.
Revisão: Ricardo Amaral de Andrade
Inscreva-se no nosso canal Manual do Maker no YouTube.
Também estamos no Instagram.
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.