-
Notifications
You must be signed in to change notification settings - Fork 8
Using an STLink Dongle and GDB with your BlackIce II
When you want to develop new code for the STM32 processor on your BlackIce board, you'll quickly want to use a debugger, GDB.
This page describes what you need and how to do this.
Debugging on embedded systems follows the following plan:
-
On your PC, you run the debugger itself. This is almost always GDB.
Note that you need to run a version of GDB that understands the CPU architecture of the embedded CPU. In our case, we're running the ARM version of GDB:
arm-none-eabi-gdb
.GDB doesn't know anything about how to connect to the target system. It translates highlevel user commands like setting breakpoints, stepping through code, etc into lower level commands that are still pretty high level (e.g. write this byte to that memory address on the embedded system.)
These lower level commands must be interpreted by the so-called GDB server.
-
OpenOCD.
This is the GDB server. It's a translater of the low level commands in two ways. It knows how to talk to a hardware debug dongle, like the STLink dongle, and it knows how to translate the low level commands for a particular CPU.
-
Hardware Debug Dongle
This is the physical interface that connects your PC to your embedded system. Very often, it has a USB connector on one side, and a generic wire interface on the other, that can plug into the embedded hardware. (Instead of USB, a UART or Ethernet port is possible as well, but less common.)
The STM32 on the BlackIce board uses the ARM proprietary Single Wire Debug (SWD) protocol, which uses... two wires: SWCLK and SWDIO.
In order to drive them, you need an STLink v2 dongle. You can buy an original one (with some features that you don't need) from ST for around $20, or you can buy a much cheaper clone on the web. They are absolutely everywhere and go for as low as $1.80 on AliExpress (with 50 days of delivery time) or $6 on your local web retailer.
They look like this:
As mentioned before, OpenOCD is the glue that links GDB to the hardware dongle and the embedded CPU.
New CPUs come out all the time, and the STM32L4xx is not very old, so you need a fairly recent version of OpenOCD.
It's best to just download the source code, and compile it.
git clone git://git.code.sf.net/p/openocd/code openocd
cd ./openocd
./configure --prefix=/usr/local
make
sudo make install
Note: you will probably need to install a bunch of libraries.
Plug in your STLink dongle, and run the following command:
sudo openocd -f /usr/local/share/openocd/scripts/interface/stlink.cfg -f /usr/local/share/openocd/scripts/target/stm32l4x.cfg
You should see something like this:
Open On-Chip Debugger 0.10.0+dev-00362-g78a4405 (2018-03-22-05:41)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 500 kHz
adapter_nsrst_delay: 100
none separate
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : clock speed 480 kHz
Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 3.229552
Error: init mode failed (unable to connect to the target)
in procedure 'init'
in procedure 'ocd_bouncer'
Ignore the error at the bottom: we haven't connected our STLink dongle to the BlackIce board yet! The important part is that OpenOCD is communicating correctly with the STLink dongle.
You will see the pinout of the dongle connector printed on the dongle casing itself. And, usually, there'll be a cable included with 4 wires.
Connect them as follows:
- SWDIO: from pin 2 on the dongle to pin 11 on the RPi connector of your board
- SWCLK: from pin 6 on the dongle to pin 7 on the RPi connector
- GND: from pin 4 on the dongle to pin 9 on the RPi connector
- GND: from pin 3 on the dongle to pin 25 on the RPi connector
Do NOT connect the 3.3V or 5V pins. The STLink dongle is not strong enough to power the BlackIce board!
Use an additional USB cable and plug it into one of the USB ports of the BlackIce board.
With everything wired up, we can now restart openocd again. And if all goes well, you should see this:
ubuntu@ubuntu-xenial:~/projects/libopencm3-examples/examples/stm32/l4/other/usb_cdcacm$ sudo openocd -f /usr/local/share/openocd/scripts/interface/stlink.cfg -f /usr/local/share/openocd/scripts/target/stm32l4x.cfg
Open On-Chip Debugger 0.10.0+dev-00362-g78a4405 (2018-03-22-05:41)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 500 kHz
adapter_nsrst_delay: 100
none separate
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : Unable to match requested speed 500 kHz, using 480 kHz
Info : clock speed 480 kHz
Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 3.229552
Info : stm32l4x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections
Success! The STM32 CPU has been successfully identified!
We don't have GDB running yet, but OpenOCD also has a console mode through which you can issue all kinds of management commands.
In a different terminal windows, so the following:
telnet localhost 4444
You should see this:
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
>
There are tons of commands. You'll get a list of them if you type 'help'.
Probably the most interesting part is the one where you can read and write to the flash memory of the STM32. That's right! You don't need to switch the DFU jumper on the BlackIce board anymore to access the flash.
Here's how you can dump the current contents of the flash:
> dump_image dump.bin 0x08000000 0x1ffff
dumped 131071 bytes in 3.969067s (32.249 KiB/s)
And here's now you could reflash the iceboot
firmware:
First halt the CPU:
> reset halt
adapter speed: 500 kHz
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0800018c msp: 0x20010000
Then flash the binary:
> flash write_image erase /home/ubuntu/projects/BlackIce-II/firmware/iceboot/iceboot.raw 0x08000000
auto erase enabled
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x20000050 msp: 0x20010000
block write succeeded
wrote 40960 bytes from file /home/ubuntu/projects/BlackIce-II/firmware/iceboot/iceboot.raw in 3.677231s (10.878 KiB/s)
>
Make sure that you have iceboot
compiled, and flash it using the instructions above.
Now do the following:
cd ~/BlackIce-II/firmware/iceboot
arm-none-eabi-gdb -ex "target remote localhost:3333" ./output/iceboot.elf
OpenOCD is ready to accept low level GDB commands on port 3333, so we're telling GDB to connect to that. And GDB uses ELF files to learn the variables and functions that are compiled in your binary. So we specify that as well.
You will see something like this:
GNU gdb (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 8.0.50.20171128-git
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./output/iceboot.elf...done.
Remote debugging using localhost:3333
Reset_Handler () at ../Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/gcc/startup_stm32l433xx.s:81
81 ldr sp, =_estack /*_estack Atollic update: set stack pointer */
(gdb)
Let's set a breakpoing at main:
(gdb) br main
Breakpoint 1 at 0x80012b4: file main.c, line 95.
And run the program:
(gdb) c
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.
Breakpoint 1, main () at main.c:95
95 HAL_Init();
(gdb)
There we have it! We've successfully taken over control of the controller. We can run program, set breakpoints and inspect variables!