Programming STM32 using Standard Peripheral Library and free tools – Part #2: Flashing with OpenOCD

The second part of this tutorial is all about flashing your STM32 device. We use OpenOCD to erase and flash the microcontroller.


Here is the complete project Part #2: Flashing with OpenOCD available for download. Extract it to your Home folder, so that you get the following result:

+- <GCCDevelopment>
   +- <STM32F10x_StdPeriph_Lib_v3.5.0> 
   +- <Scripts>
   +- <Blinky>

Setting up OpenOCD

First, we need some prerequisites. Open a terminal window and type:

> sudo apt install openocd
> sudo apt install libnet-telnet-perl

The necessity of OpenOCD is self-explaining. The libnet-telnet-perl module is part of Perl. We need it in conjunction with xterm (should already be installed) which is a terminal emulator used by OpenOCD.

OpenOCD uses boards, interfaces and devices for configuration purposes. I have written some scripts which can handle all that configurations. They can all easily be called from within the new makefile:

# Project dependencies
PROJECT := Blinky
BOARD := board/olimex_stm32_h103.cfg

# Build tools
CC = ~/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/arm-none-eabi-gcc
OBJCOPY = ~/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/arm-none-eabi-objcopy

# Compiler options
CFLAGS = -ggdb -O0 -Wall -Wextra -Warray-bounds -mlittle-endian
CFLAGS += -mthumb -mcpu=cortex-m3 -mthumb-interwork

# Linker file / options
LFLAGS = -T$(wildcard *.ld)
LFLAGS += --specs=nano.specs --specs=nosys.specs
LFLAGS += -Wl,-Map -Wl,$(PROJECT).map

# Directories to be searched for header files
INCLUDE = -I../STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport 
INCLUDE += -I../STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/inc

# Object files to be created
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c)) $(patsubst %.s, %.o, $(wildcard *.s))

# Add Standard Peripheral Library to the build configuration

# Build targets
.PHONY: all
all: $(PROJECT).elf

%.o: %.c
	$(CC) $(INCLUDE) $(DEFS) $(CFLAGS) -c $< -o $@

%.o: %.s
	$(CC) $(INCLUDE) $(DEFS) $(CFLAGS) -c $< -o $@

	$(OBJCOPY) -O binary $(PROJECT).elf $(PROJECT).bin

.PHONY: clean
	rm -rf *.o *.bin *.elf *.map

.PHONY: openocd
	@bash ../Scripts/openocd.bsh ../Scripts/ $(BOARD)

.PHONY: erase
	perl ../Scripts/

.PHONY: flash
	perl ../Scripts/ ../$(PROJECT)/$(PROJECT).bin

The scripts are located in their own folder. The new development environment structure now looks like this (I use version v3.5.0 of the Standard Peripheral Library):

+- <GCCDevelopment>
   +- <STM32F10x_StdPeriph_Lib_v3.5.0>
   +- <Scripts>
      +- openocd.bsh
      +- openocd_ports.cfg
   +- <Blinky>

The openocd.bsh script is a bash script. It looks for OpenOCD to be installed and validates the configuration parameters. Also the JTAG interfaces are involved here. I have pre-installed the Olimex ARM-USB-TINY-H JTAG device and the Segger J-LINK. But you can add many more easily. Take a look at openocd.bsh for more insight.

Openocd_ports.cfg simply configures the telnet connection used by OpenOCD. The Perl scripts and performs the programming tasks.

Programming your device

The programming of your device is nothing more than calling make with the correct parameter to run the desired script.

First of all, you must build your project to get the binary file for flashing:

> make

As a result, you can find the Blinky.bin file in the project folder.

The next step is to start the OpenOCD server. Just type

> make openocd

After a couple of seconds, the server is started. Once the server is running, you don’t have to start it again.

You can now flash your device by typing

> make flash

If you want to erase the device memory, you can simply type

> make erase

Installing OpenOCD and using it for flashing is not that difficult. All you need are some scripts to configure OpenOCD in the right way. Some additional scripts that can be called from within the makefile will do the trick.

In the third part of this tutorial, the Blinky example will be improved by an advanced folder structure. This structure does not handle all the sources in a single directory. Also the object files and binaries are placed in their own folder.

Leave a Reply

Your email address will not be published. Required fields are marked *

− 4 = 2