Depurando com a Black Magic Probe
- por Sergio Prado
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!