Flash it

Flashing is the process of moving our program into the microcontroller’s (persistent) memory. Onceflashed, the microcontroller will execute the flashed program every time it is powered on.

In this case, our led-roulette program will be the only program in the microcontroller memory.By this I mean that there’s nothing else running on the microcontroller: no OS, no “daemon”,nothing. led-roulette has full control over the device.

Onto the actual flashing. First thing we need is to do is launch OpenOCD. We did that in theprevious section but this time we’ll run the command inside a temporary directory (/tmp on *nix;%TEMP% on Windows).

Make sure the F3 is connected to your laptop and run the following commands on a new terminal.

  1. $ # *nix
  2. $ cd /tmp
  3. $ # Windows
  4. $ cd %TEMP%
  5. $ # Windows: remember that you need an extra `-s %PATH_TO_OPENOCD%\share\scripts`
  6. $ openocd \
  7. -f interface/stlink-v2-1.cfg \
  8. -f target/stm32f3x.cfg

NOTE Older revisions of the board need to pass slightly different arguments toopenocd. Review this section for the details.

The program will block; leave that terminal open.

Now it’s a good time to explain what this command is actually doing.

I mentioned that the F3 actually has two microcontrollers. One of them is used as aprogrammer/debugger. The part of the board that’s used as a programmer is called ST-LINK (that’s whatSTMicroelectronics decided to call it). This ST-LINK is connected to the target microcontrollerusing a Serial Wire Debug (SWD) interface (this interface is an ARM standard so you’ll run into itwhen dealing with other Cortex-M based microcontrollers). This SWD interface can be used to flashand debug a microcontroller. The ST-LINK is connected to the “USB ST-LINK” port and will appear asa USB device when you connect the F3 to your laptop.

Flash it - 图1

As for OpenOCD, it’s software that provides some services like a GDB server on top of USBdevices that expose a debugging protocol like SWD or JTAG.

Onto the actual command: those .cfg files we are using instruct OpenOCD to look for a ST-LINK USBdevice (interface/stlink-v2-1.cfg) and to expect a STM32F3XX microcontroller(target/stm32f3x.cfg) to be connected to the ST-LINK.

The OpenOCD output looks like this:

  1. Open On-Chip Debugger 0.9.0 (2016-04-27-23:18)
  2. Licensed under GNU GPL v2
  3. For bug reports, read
  4. http://openocd.org/doc/doxygen/bugs.html
  5. Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
  6. adapter speed: 1000 kHz
  7. adapter_nsrst_delay: 100
  8. Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
  9. none separate
  10. Info : Unable to match requested speed 1000 kHz, using 950 kHz
  11. Info : Unable to match requested speed 1000 kHz, using 950 kHz
  12. Info : clock speed 950 kHz
  13. Info : STLINK v2 JTAG v27 API v2 SWIM v15 VID 0x0483 PID 0x374B
  14. Info : using stlink api v2
  15. Info : Target voltage: 2.919073
  16. Info : stm32f3x.cpu: hardware has 6 breakpoints, 4 watchpoints

The “6 breakpoints, 4 watchpoints” part indicates the debugging features the processor hasavailable.

I mentioned that OpenOCD provides a GDB server so let’s connect to that right now:

  1. $ <gdb> -q target/thumbv7em-none-eabihf/debug/led-roulette
  2. Reading symbols from target/thumbv7em-none-eabihf/debug/led-roulette...done.
  3. (gdb)

NOTE: <gdb> represents a GDB program capable of debugging ARM binaries.This could be arm-none-eabi-gdb, gdb-multiarch or gdb depending on yoursystem — you may have to try all three.

This only opens a GDB shell. To actually connect to the OpenOCD GDB server, use the followingcommand within the GDB shell:

  1. (gdb) target remote :3333
  2. Remote debugging using :3333
  3. 0x00000000 in ?? ()

By default OpenOCD’s GDB server listens on TCP port 3333 (localhost). This command is connecting tothat port.

After entering this command, you’ll see new output in the OpenOCD terminal:

  1. Info : stm32f3x.cpu: hardware has 6 breakpoints, 4 watchpoints
  2. +Info : accepting 'gdb' connection on tcp/3333
  3. +Info : device id = 0x10036422
  4. +Info : flash size = 256kbytes

Almost there. To flash the device, we’ll use the load command inside the GDB shell:

  1. (gdb) load
  2. Loading section .vector_table, size 0x188 lma 0x8000000
  3. Loading section .text, size 0x38a lma 0x8000188
  4. Loading section .rodata, size 0x8 lma 0x8000514
  5. Start address 0x8000188, load size 1306
  6. Transfer rate: 6 KB/sec, 435 bytes/write.

And that’s it. You’ll also see new output in the OpenOCD terminal.

  1. Info : flash size = 256kbytes
  2. +Info : Unable to match requested speed 1000 kHz, using 950 kHz
  3. +Info : Unable to match requested speed 1000 kHz, using 950 kHz
  4. +adapter speed: 950 kHz
  5. +target state: halted
  6. +target halted due to debug-request, current mode: Thread
  7. +xPSR: 0x01000000 pc: 0x08000194 msp: 0x2000a000
  8. +Info : Unable to match requested speed 8000 kHz, using 4000 kHz
  9. +Info : Unable to match requested speed 8000 kHz, using 4000 kHz
  10. +adapter speed: 4000 kHz
  11. +target state: halted
  12. +target halted due to breakpoint, current mode: Thread
  13. +xPSR: 0x61000000 pc: 0x2000003a msp: 0x2000a000
  14. +Info : Unable to match requested speed 1000 kHz, using 950 kHz
  15. +Info : Unable to match requested speed 1000 kHz, using 950 kHz
  16. +adapter speed: 950 kHz
  17. +target state: halted
  18. +target halted due to debug-request, current mode: Thread
  19. +xPSR: 0x01000000 pc: 0x08000194 msp: 0x2000a000

Our program is loaded, let’s debug it!