GNU ARM Cross-toolchain – OpenOCD + GDB

gdb

Os artigos anteriores da série indicaram os passos a serem seguidos para compilação de um projeto, configuração das regiões de dados na memória e gravação do binário executável gerado na memória do microcontrolador. Ao longo da etapa de desenvolvimento de um projeto, é necessário que haja algum meio de depuração do código, mesmo que este seja um simples envio de dados seriais por um periférico do microcontrolador. Isso acaba não sendo prático pois esse método, para cada adição de um ponto de depuração, deve ser executado o seguinte ciclo: alteração de código, compilação e execução. A fim de reduzir esse ciclo, neste artigo é introduzido o depurador GDB, que permite o controle de execução da aplicação, podendo inserir breakpoints ao longo do seu código.

 

Antes de entrarmos em maiores detalhes, é necessário possuir uma cópia local do projeto disponível no GitHub. Caso não tenham sido realizados os passos listados nos artigos anteriores, é interessante que esses sejam executados de forma a tirar maior proveito dos conceitos apresentados a seguir.

 

Uma vez que o ambiente esteja criado corretamente, basta atualizar o projeto, tendo em vista que ele vem sofrendo alterações/modificações com o tempo. Execute os seguintes comandos:

 

 

 

 Por que depurar?

 

Uma vez que o binário executável seja gerado no dispositivo host, um PC, é necessário gravá-lo no dispositivo target e executá-lo. Isso foi feito no primeiro artigo desta série, e é o que ocorre na fase de produção de um produto. O microprocessador busca e executa as instruções da memória do sistema, interna ou externa, sem permitir que o estado interno do programa seja monitorado, o que atrapalha a etapa de desenvolvimento. Para isso foi criado um método de depuração do código de uma aplicação que é executada num ambiente target diferente do ambiente host, conhecido como depuração remota.

 

 

Depuração remota

 

Para a execução da depuração remota, são necessários dois ambientes: o host e o target. No primeiro deve ser executado um aplicativo front-end, depurador, o qual oferece a interface com o usuário. Já no sistema target, precisa existir um aplicativo back-end, também conhecido como debug monitor, que se comunique com o aplicativo front-end que é executado no sistema host. Esse meio de comunicação pode ser tanto uma conexão ethernet ou serial, isolando o controle de baixo nível com o microprocessador realizado pelo back-end.

 

Em sistemas bare-metal, ao invés de ser implementado um debug monitor no próprio dispositivo target, é comum executar esse aplicativo no próprio ambiente host, capaz de se comunicar com o dispositivo target de alguma forma, tal como USB. Como o host não possui suporte nativo à sinalização elétrica necessária para o acesso ao hardware a ser depurado, faz-se necessário que o ambiente target possua um hardware especial, chamado debug adapter. Esse dispositivo é capaz de receber comandos de baixo nível e realizar a depuração do microprocessador por meio de algumas interfaces, tal como JTAG e SWD.

 

Neste artigo é utilizado o depurador GDB, que é fornecido pelo pacote de instalação do cross-toolchain utilizado. Já o back-end servidor deve ser um aplicativo com suporte ao microprocessador utilizado (STM32F4), ao debug adapter do kit de desenvolvimento (ST-LINK/V2) e, principalmente, ao protocolo serial remoto (RSP) do GDB. O OpenOCD possui todas essas características, e já foi utilizado no artigo anterior. A configuração utilizada é exibida na figura abaixo.

 

remote_debug

 

 

OpenOCD

 

O aplicativo OpenOCD (Open On-Chip Debugger) tem como objetivo oferecer, para dispositivos embarcados, depuração, in-system programming e boundary-scan. Também oferece suporte a adaptadores que implementam os padrões JTAG e SWD. Deve-se levar em consideração que a interface SWD não oferece suporte à boundary-scan e, portanto, o foco deste artigo, usando o kit STM32F4Discovery, é somente depuração.

 

OpenOCD implementa dois servidores: um Telnet e outro GDB. Uma vez que esse aplicativo é executado, são aguardadas conexões de clientes a partir desses dois canais de comunicação e processados os comandos recebidos.

 

Para iniciar a depuração do projeto disponibilizado no GitHub, vamos precisar dos mesmos componentes que vínhamos utilizando até o momento. Ou seja, um PC host Linux, o kit STM32F4Discovery e um cabo USB.

 

O primeiro passo é iniciar o servidor GDB, o OpenOCD.

  

 

As mensagens abaixo devem ser exibidas. Neste momento o OpenOCD já iniciou o seu servidor GDB e está aguardando comandos do aplicativo cliente.

 

 

O passo seguinte é, em outro prompt do shell, inicializar o cliente GDB e indicar a aplicação a ser depurada.

 

 

As mensagens abaixo são exibidas. Os símbolos de debug e as seções de código e dados, contidos no arquivo executável no formato ELF, são lidos pelo depurador e, no final, é disponibilizado um prompt de comando do GDB.

 

 

Agora deve ser indicado que a aplicação a ser depurada não é nativa e encontra-se gravada em outro ambiente. Para isso, deve ser informado o meio de acesso remoto ao servidor GDB, o qual realiza a interface com o dispositivo target. Pelo fato desse aplicativo ser executado no ambiente host também, como ilustrado na figura anterior, é implementada a conexão com o cliente GDB por meio de socket localhost, usando a porta 3333. Portanto, execute o seguinte comando:

 

 

Caso exista algum programa gravado na memória do microprocessador, é dado início à sua execução. Mas neste momento é interessante que o dispositivo esteja no estado halt, em modo debug. Para isso, execute o próximo comando:

 

 

O resultado do comando acima deve ser o seguinte: 

 

 

Obs.: O comando monitor do GDB faz com que o restante do comando escrito seja executado pelo dispositivo servidor, que no caso é o OpenOCD.

 

Agora vamos apagar a memória interna do microprocessador.

 

 

Uma mensagem parecida como a seguinte é exibida.

 

 

Memória limpa! Falta a gravação do binário da aplicação.

 

 

Caso o comando tenha sido executado com sucesso, a saída a seguir é exibida:

 

 

Com o binário gravado na memória interna do microprocessador, executamos o comando reset.

 

 

Pronto para a depuração? Vamos criar um breakpoint na função main, a qual é chamada após a inicialização da biblioteca de runtime.

 

 

Se a seguinte mensagem aparecer, estamos indo bem!

 

 

Se for executado o comando continue, a execução da aplicação é retomada e, em seguida, paralizada assim que a função main for chamada.

 

 

Como esperado, o breakpoint parou a execução momentaneamente da aplicação.

 

 

Caso deseje depurar o código dentro da função SystemCoreClockUpdate, pode ser executado o comando step do GDB, o qual executa a próxima linha de código da aplicação depurada, que por sua vez está dentro dessa função. No entanto, caso queira executar essa chamada de função com um único comando, deve ser usado o comando next. Segue uma sequência de comandos next e step como exemplo:

 

 

Caso seja executado novamente o comando continue, a aplicação volta a ser executada, sem paradas desta vez.

 

 

A execução do programa é retomada. Como parar? Pode usar o comando Ctrl+C, o qual gera um signal SIGINT para o aplicativo GDB e, com isso, a aplicação é pausada.

 

Existem muito mais comandos para serem utilizados. A documentação do projeto GDB é um bom começo! Seguem alguns comandos bem bacanas para começar a se divertir com o GDB:

 

  • info locals: exibe o conteúdo das variáveis locais da função sendo executada;
  • disassemble: exibe o código Assembly gerado para a função sendo executada;
  • bt: exibe o backtrace da pilha, detalhando todas as chamadas às funções.

 

Dá trabalho depurar dessa forma, em linha de comando, certo? Num próximo artigo montaremos um ambiente com uma IDE open-source que realiza todo esse trabalho para a gente!

 

Bibliografia

 

GDB - GNU Project debugger

 

Outros artigos da série

<< GNU ARM Cross-toolchain – Configurando stack e heapGNU ARM Cross-toolchain – FreeRTOS + GCC + STM32F4Discovery - Parte 1 >>
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.

Henrique Rossi
Engenheiro eletricista com ênfase em eletrônica e pós-graduado em Engenharia de Software. Comecei um mestrado, mas o interrompi. Especialista na área de sistemas embarcados, com mais de 12 anos de experiência em desenvolvimento de firmware (sistemas baremetal e baseados em RTOS) e Linux Embarcado. Atualmente sou administrador do site Embarcados, trabalho num fabricante de Set-Top Box e atuo como consultor/desenvolvedor na área de sistemas embarcados.

9
Deixe um comentário

avatar
 
8 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Henrique RossiEduardo ScherrerAlgoritmos DSP com a placa STM32F4Discovery - Parte IGNU ARM Cross-toolchain – Eclipse + FreeRTOS + GCC - Parte 2Embarcados – Sua fonte de informações sobre Sistemas Embarcados GNU Cross-toolchain - Processo de build Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
trackback

[…] GNU ARM Cross-toolchain – OpenOCD + GDB » 23-01-2014 […]

trackback

[…] GNU ARM Cross-toolchain – OpenOCD + GDB […]

trackback

[…] GNU ARM Cross-toolchain – OpenOCD + GDB […]

trackback

[...] GNU ARM Cross-toolchain – OpenOCD + GDB [...]

trackback

[...] Pronto! Agora a aplicação bare-metal está migrada para uma versão com o FreeRTOS. Vamos compilá-la e depurá-la com o que aprendemos até aqui? Conecte a sua placa STM32F4Discovery no seu PC com o cabo USB e execute os seguintes comandos para compilar a aplicação e iniciar o servidor GDB, o OpenOCD: [...]

trackback

[...] GNU ARM Cross-toolchain – OpenOCD + GDB [...]

Eduardo Scherrer
Visitante
Eduardo C. Scherrer

Olá Henrique,

Acompanho o site dos embarcados e está muito bom, cada dia uma informação valiosa. Parabéns pelo trabalho.

Estou muito interessado na continuidade deste post, por se tratar de usar um microcontrolador com tanto poder, e claro, utilizando uma ferramenta fácil acesso (pelo menos financeiramente falando).

Eu já li em alguns lugares, se não me engano no blog do Sergio Prado. Sobre utilizar uma IDE para fazer todo este processo de codificação, depuração e gravação do microcontrolador. Você abordará este assunto como continuidade?
Teria algum lugar para indicar onde posso continuar estes passos.

Obrigado.
E mais uma vez parabéns pelo trabalho de todos.

Eduardo Scherrer

Henrique Rossi
Visitante

Olá Eduardo!

Muito obrigado pelo comentário! Esta série vai ter continuação sim, e muita!! 🙂

Um dos seguintes posts será sobre a criação do ambiente gráfico, usando uma IDE (Eclipse), mas estamos escrevendo um artigo sobre o uso do FreeRTOS 8.0 nesta placa.

Pode continuar acompanhando a série, que ela vai evoluir.

Grande abraço,
Henrique

trackback

[...] GNU ARM Cross-toolchain – OpenOCD + GDB [...]