Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This guide uses a STM32 Nucleo development board to flash to an STM32 series microcontroller. The Nucleo acts as a SWD (Serial Wire Debug) programmer for the main microcontroller, which should be some STM32 series MCU on your PCB.

Prerequisite

Make sure you have set up your development environment as per Setting up an Embedded Development Environment.

SWD Interface

(resources: Introduction to JTAG and the Test Access Port (TAP), SWD – ARM’S ALTERNATIVE TO JTAG, STM Nucleo-64 UM1724 User Manual)

...

  • stlink (software package) is a tool developed by STMicroelectronics to interface with an ST-LINK device (see the STLink repository for more information) for programming and debugging purposes.
  • OpenOCD runs a GDB server, which allows us to debug remote targets via GDB. It also lets us write to flash with some extra configuration (see https://pfeerick.github.io/InfiniTime/doc/openOCD.html)

Currently, the OpenOCD GDB server is used to debug, while st-flash (one of the several tools in the stlink package) is used to flash code. We previously used st-flash and st-util (both from the stlink package) as our flashing tool and debugging tool respectively, but OpenOCD provided performance benefits over stlink's tools specifically for the GDB server. In the future, perhaps flashing via openocd could be implemented (see https://github.com/lhr-solar/Controls/issues/314)

...

in order to consolidate tooling.

Nevertheless, the Controls/BPS Makefiles are set up with make flash as a target, which will run st-flash and flash code onto the target device. Note that the Linux system you are running on must recognize your ST-LINK device as connected (an easy way to verify this is to run lsusb and see if it appears in the listed devices). If running Linux natively, this is simple, but WSL2 or a VM may require additional steps (see https://learn.microsoft.com/en-us/windows/wsl/connect-usb to set up USBIP on WSL2).

The st-flash command that the Makefile currently runs is as follows:

st-flash write $(BUILD_DIR)/$(TARGET).bin 0x8000000 

This tells st-flash to write to flash memory starting at address 0x0800 0000 (which is the beginning of flash memory in the STM32F413; see RM0090).

Image Added

Note that the $(TARGET).bin file is used to flash, because we are not flashing the .elf file (executable and loadable format) but rather the binary file directly (since the .elf file will include lots of extra information not necessary for flashing).

Steps to flash

  1. Connect the SWD interface on the Nucleo to your circuit board via jumper wires. Specifically, connect 3.3V, GND, SWDIO, and SWCLK.
  2. Ensure that the CN2 jumpers are removed from the Nucleo board.
  3. Plug in a USB A to USB mini-B connector into the Nucleo. This should provide power to the Nucleo and you should be able to see a green light.
  4. Power your board. For leaderboards this is most likely 12V power; for peripheral boards this may be 5V power.
  5. Verify via lsusb that your device is listed on your Linux environment. You may have to do some extra steps to get the device to be recognized by Linux if using WSL2, as specified in the link above.
  6. Compile your code via your Makefile. This should be simply calling make leader or make stm32f413  or whatever your desired target is as per specified in your Makefile. It may differ from system to system, but understanding how to compile your code is crucial.
    1. Verify that in your build output directory (will most likely be called Objects) you can see the build artifacts: specifically the (TARGET).bin file that you wish to flash.
  7. Run make flash and watch your firmware flash to your device. This will call the st-flash script as specified above.
  8. Press the reset button on the board to reset the MCU and your code should start running.

Steps to debug

  1. Run openocd in a terminal session on your Linux machine. If it detects your device it will stall and tell you that a GDB server has been started on port 3333.
  2. Open a second terminal session on your Linux machine and run gdb-multiarch Objects/(TARGET).elf . This is a version of gdb that widely supports many different architectures, and is the desired version ever since ARM deprecated their custom version provided by their toolchain (arm-none-eabi-gdb).
    1. Note that the elf file we compiled is specified as an input to gdb, since the elf file holds debug information along with the binary itself that is necessary for GDB to recognize the firmware's symbols.
  3. Now you should be in the GDB environment. Run target extended-remote :3333  to connect to the GDB server started in step 1.
  4. You should be able to debug and step through your code via GDB commands (for a full cheatsheet, see here).

Filter by label (Content by label)
showLabelsfalse
max5
spacesLHRSOLAR
showSpacefalse
sortmodified
reversetrue
typepage
cqllabel = "kb-how-to-article" and type = "page" and space = "LHRSOLAR"
labelskb-how-to-article

...