Depurando com a Black Magic Probe

- por Sergio Prado

Categorias: Ferramentas Tags: , ,

Há alguns dias escrevi um artigo introdutório sobre a Black Magic Probe. Nesta publicação irei utilizar a Black Magic Probe para depurar via JTAG um microcontrolador ARM Cortex-M3.

Para os testes utilizarei o STM32VLDISCOVERY, um kit de desenvolvimento da STMicroelectronics que inclui o microcontrolador STM32F100RBT6B, um ARM Cortex-M3 com 128KB de flash e 8KB de RAM.

O STM32VLDISCOVERY vem com um ST-LINK (depurador da ST) integrado ao kit de desenvolvimento. Para depurar com a Black Magic Probe é necessário isolar o ST-LINK do microcontrolador, removendo os resistores SB5, SB9 e SB11 indicados na imagem abaixo:

Basta então conectar a Black Magic Probe ao kit de desenvolvimento, conforme tabela abaixo:

SINAL    BMP   STM32VLDISCOVERY
TMS      2     PA13
TCK      4     PA14
TDO      6     PB3
TDI      8     PA15
RST      10    RST
PWR      1     3V3
GDN      3     GND

Os testes foram feitos em um PC com a distribuição Ubuntu 14.04 64 bits. Antes de começar, é recomendado instalar o GNU ARM Embedded Toolchain. No Ubuntu, isso pode ser feito com os comandos abaixo:

$ sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa
$ sudo apt-get update
$ sudo apt-get install gcc-arm-embedded

Para verificar se o toolchain foi instalado com sucesso, basta executar o GCC:

$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors 6-2017-q2-update) 6.3.1 20170215 (release) [ARM/embedded-6-branch revision 245512]
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Mais informações sobre o GNU ARM Embedded Toolchain estão disponíveis no README do projeto.

Para testar a depuração por JTAG, é necessário um firmware qualquer rodando no kit de desenvolvimento. Para isso, adaptei um código em C bastante simples disponível neste post:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/* File: main.c */
 
#define	STACK_TOP  0x20001000
 
void nmi_handler(void)
{
    for(;;);
}
 
void hardfault_handler(void)
{
    for(;;);
}
 
int main(void)
{
    int i = 0;
 
    for (;;) {
        i++;
    }
}
 
/* vector table */
unsigned int *myvectors[4]
__attribute__ ((section("vectors"))) = {
    (unsigned int *) STACK_TOP,
    (unsigned int *) main,
    (unsigned int *) nmi_handler,
    (unsigned int *) hardfault_handler
};

Este é o linker script que utilizei:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/* File: stm32.ld */
 
/* customized for STM32F100RBT6B */
MEMORY
{
    ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K
    rom (rx)  : ORIGIN = 0x08000000, LENGTH = 128K
}
 
SECTIONS
{
    .  = 0x0;         /* From 0x00000000 */
    .text :
    {
        *(vectors)    /* Vector table */
        *(.text)      /* Program code */
        *(.rodata)    /* Read only data */
    } >rom
 
    .  = 0x20000000;  /* From 0x20000000 */
    .data :
    {
        *(.data)      /* Data memory */
    } >ram AT > rom
 
    .bss :
    {
        *(.bss)       /* Zero-filled run time allocate data memory */
    } >ram AT > rom
}

E este é o Makefile:

1
2
3
4
5
6
7
8
9
10
CROSS_COMPILE := arm-none-eabi-
 
all:
	$(CROSS_COMPILE)gcc -I. -c -fno-common -O0 -g -mcpu=cortex-m3 -mthumb main.c
	$(CROSS_COMPILE)ld -Tstm32.ld -nostartfiles -o main.elf main.o
	$(CROSS_COMPILE)objcopy -Obinary main.elf main.bin
	$(CROSS_COMPILE)size main.elf
 
clean:
	rm -Rf main.elf main.o main.bin

Para compilar, basta executar o make:

$ make
arm-none-eabi-gcc -I. -c -fno-common -O0 -g -mcpu=cortex-m3 -mthumb main.c
arm-none-eabi-ld -Tstm32.ld -nostartfiles -o main.elf main.o
arm-none-eabi-objcopy -Obinary main.elf main.bin
arm-none-eabi-size main.elf
   text	   data	    bss	    dec	    hex	filename
     46	      0	      0	     46	     2e	main.elf

Agora vamos testar a depuração por JTAG com a Black Magic Probe.

Precisamos primeiro alimentar o kit de desenvolvimento, conectando-o à porta USB do PC.

Depois é só conectar a Black Magic Probe na interface USB do PC e abrir um terminal. Deverão ser criadas duas portas seriais, a primeira para acessar o servidor GDB da Black Magic Probe e a segunda para acessar uma interface serial genérica.

$ ls -l /dev/ttyACM*
crw-rw---- 1 root dialout 166, 0 Jun 19 18:23 /dev/ttyACM0
crw-rw---- 1 root dialout 166, 1 Jun 19 18:14 /dev/ttyACM1

Vamos iniciar a depuração. Execute o GDB, passando como parâmetro a imagem ELF do firmware gerado:

$ arm-none-eabi-gdb main.elf

O primeiro passo é se conectar à porta serial da Black Magic Probe com o comando target do GDB:

(gdb) target extended-remote /dev/ttyACM0
Remote debugging using /dev/ttyACM0

A Black Magic Probe implementa diversos comandos que podem ser acessados executando monitor no terminal do GDB. Podemos exibir estes comandos com o parâmetro help do monitor:

(gdb) monitor help
General commands:
	version -- Display firmware version info
	help -- Display help for monitor commands
	jtag_scan -- Scan JTAG chain for devices
	swdp_scan -- Scan SW-DP for devices
	targets -- Display list of available targets
	morse -- Display morse error message
	connect_srst -- Configure connect under SRST: (enable|disable)
	hard_srst -- Force a pulse on the hard SRST line - disconnects target
	tpwr -- Supplies power to the target: (enable|disable)
	traceswo -- Start trace capture

Executando apenas monitor, sem passar nenhum parâmetro, podemos visualizar a versão do firmware da Black Magic Probe:

(gdb) monitor
Black Magic Probe (Firmware v1.6) (Hardware Version 3)
Copyright (C) 2015 Black Sphere Technologies Ltd.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

Para procurar por dispositivos conectados na interface JTAG, podemos passar o parâmetro jtag_scan para o monitor:

(gdb) monitor jtag_scan
Target voltage: 3.0V
Available Targets:
No. Att Driver
1 STM32F1 medium density

Da mesma forma, para procurar por dispositivos conectados na interface SWD, podemos utilizar o comando “monitor swdp_scan“.

Após a identificação, basta se conectar ao dispositivo com o comando attach:

(gdb) attach 1
Attaching to program: /home/sprado/workspace/build/blackmagic/stm32/main.elf, Remote target
0x08000020 in main () at main.c:14
14 {

A partir deste momento, temos uma conexão estabelecida com o kit de desenvolvimento e podemos iniciar o processo de depuração.

A imagem do firmware pode ser gravada na memória flash com o comando load:

(gdb) load main.elf
Loading section .text, size 0x2e lma 0x8000000
Start address 0x8000000, load size 46
Transfer rate: 1 KB/sec, 46 bytes/write.

Para facilitar a depuração, podemos habilitar o modo TUI:

(gdb) tui enable

E rodar normalmente os comandos do GDB como start, break, print, next, etc.

A página wiki da Black Magic Probe tem um breve resumo dos comandos mais utilizados do GDB, e está disponível um manual bastante completo do GDB no sourceware.org.

Este pequeno depurador JTAG está se mostrando bastante estável e simples de utilizar, e com certeza já faz parte da minha caixa de ferramentas de teste e depuração.

Happy Hacking!

Sergio Prado

Sem Comentários

Nenhum comentário até agora... é a sua chance de ser o primeiro a comentar!

Faça um Comentário

Navegue
Creative Commons Este trabalho de Sergio Prado é licenciado pelo
Creative Commons BY-NC-SA 3.0.