Openocd meets a NUCLEO-F030R8 board

[Edit: newer versions of openocd (0.8) support the stlink-v2-1 on the nucleo board without the changes described below]

STMicroelectronics recently announced a new line of mbed compatible development boards at a great price (~$10.32).  The four “NUCLEO” boards support a range of Cortex M0, M3, low power M3, and an M4 STM32 chips with more boards to come in the future (see announcement link below). This post assumes you are used to working with the STM32FX Discovery boards and openocd. Knowing how to build openocd from source wouldn’t hurt either.

New Features

I snapped up one of the NUCLEO-F030 Cortex-M0 boards before they all disappeared from mouser.com and it arrived with the UPS man yesterday.  These boards combine a programming device with a target user chip. The new firmware on the programming side of the NUCLEO board adds some long sought after missing features from the normal Discovery STLink-V2 versions. The NUCLEO board presents itself as a a composite USB device.  In addition to the normal STLink-V2 interface, added are a CDC ACM device and a Mass Storage Device. The CDC ACM device shows up as a Serial Virtual COM Port and the Mass Storage Device provides drag and drop firmware loading to the target MCU.

Issues with openocd

The first thing I did was boot up windows even though my main operating system is linux.  The device shows up as a removable disk drive with one file named mbed.htm. Opening that file with a browser takes you to the http://mbed.org login page. I created a userid and noticed that the first thing they want you to do is to upgrade the firmware on the NUCLEO board.  I installed the new firmware and then rebooted into linux. I was hoping that I would be able to use the stock openocd with some minor configuration file changes. Unfortunately that didn’t happen. The new firmware shows up with a different VID/PID and the USB endpoint addresses have changed.

Let’s fix openocd

The new NUCLEO composite USB device has a new VID:PID combo 0483:374b . I noticed that the STLink-V2 portion of the device appeared to be very similar to the standard STLink-V2 one only differing in the endpoint addresses. I crossed my fingers and made the following simple modifications to the openocd source and recompiled. In addition, I created two new configuration files that describe the board and its interface, nucleo.cfg and a stlink-v2-1.cfg. I was happily surprised when I fired up openocd and it worked on the first shot.

This patch applied to the openocd github source code changes the stlnk_usb.c code so it works only with the nucleo board:

diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c
index e9d13d5..c754df0 100644
--- a/src/jtag/drivers/stlink_usb.c
+++ b/src/jtag/drivers/stlink_usb.c
@@ -46,9 +46,15 @@
 #define STLINK_READ_TIMEOUT 1000

 #define STLINK_NULL_EP     0
+#if 0
 #define STLINK_RX_EP       (1|ENDPOINT_IN)
 #define STLINK_TX_EP       (2|ENDPOINT_OUT)
 #define STLINK_TRACE_EP    (3|ENDPOINT_IN)
+#else
+#define STLINK_RX_EP       (1|ENDPOINT_IN)
+#define STLINK_TX_EP       (1|ENDPOINT_OUT)
+#define STLINK_TRACE_EP    (2|ENDPOINT_IN)
+#endif  
 #define STLINK_SG_SIZE     (31)
 #define STLINK_DATA_SIZE   (4096)
 #define STLINK_CMD_SIZE_V2 (16)

 

Create a new configuration file for the NUCLEO-F030R8 board:

# This is an Nucleo-F030R8 board with a single STM32F030R8T6 chip.
# 

source [find interface/stlink-v2-1.cfg]

set WORKAREASIZE 0x2000
source [find target/stm32f0x_stlink.cfg]

# use hardware reset, connect under reset
reset_config srst_only srst_nogate

 

and also a new interface file with the proper VID/PID for the stlink-v2-1 firmware:

#
# STMicroelectronics ST-LINK/V2-1 in-circuit debugger/programmer
#

interface hla
hla_layout stlink
hla_device_desc "ST-LINK/V2"
hla_vid_pid 0x0483 0x374b

 

How to run it:

With those changes in place, compile and install openocd and copy the config files into the destination scripts directory. Execute openocd and see if it finds your board and connects to it. In one window run:

# openocd -f board/nucleo.cfg
Open On-Chip Debugger 0.8.0-dev-00350-g6c74255 (2014-02-20-11:42)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.sourceforge.net/doc/doxygen/bugs.html
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : This adapter doesn't support configurable speed
Info : STLINK v2 JTAG v19 API v2 SWIM v3 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 3.241334
Info : stm32f0x.cpu: hardware has 4 breakpoints, 2 watchpoints

in another window use arm-none-eabi-gdb to connect to the openocd gdb server:

$ arm-none-eabi-gdb -ex 'target extended-remote :3333'
GNU gdb (GNU Tools for ARM Embedded Processors) 7.4.1.20130913-cvs
Copyright (C) 2012 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=i686-linux-gnu --target=arm-none-eabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Remote debugging using :3333
0x00000000 in ?? ()
(gdb) monitor reset init 
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0xc1000000 pc: 0x080000d0 msp: 0x20002000
(gdb) monitor flash info 0
#0 : stm32f1x at 0x08000000, size 0x00010000, buswidth 0, chipwidth 0
	#  0: 0x00000000 (0x400 1kB) not protected
	#  1: 0x00000400 (0x400 1kB) not protected
	#  2: 0x00000800 (0x400 1kB) not protected
	#  3: 0x00000c00 (0x400 1kB) not protected
	#  4: 0x00001000 (0x400 1kB) not protected
	#  5: 0x00001400 (0x400 1kB) not protected
	#  6: 0x00001800 (0x400 1kB) not protected
	#  7: 0x00001c00 (0x400 1kB) not protected
	#  8: 0x00002000 (0x400 1kB) not protected
	#  9: 0x00002400 (0x400 1kB) not protected
	# 10: 0x00002800 (0x400 1kB) not protected
	# 11: 0x00002c00 (0x400 1kB) not protected
	# 12: 0x00003000 (0x400 1kB) not protected
	# 13: 0x00003400 (0x400 1kB) not protected
	# 14: 0x00003800 (0x400 1kB) not protected
	# 15: 0x00003c00 (0x400 1kB) not protected
	# 16: 0x00004000 (0x400 1kB) not protected
	# 17: 0x00004400 (0x400 1kB) not protected
	# 18: 0x00004800 (0x400 1kB) not protected
	# 19: 0x00004c00 (0x400 1kB) not protected
	# 20: 0x00005000 (0x400 1kB) not protected
	# 21: 0x00005400 (0x400 1kB) not protected
	# 22: 0x00005800 (0x400 1kB) not protected
	# 23: 0x00005c00 (0x400 1kB) not protected
	# 24: 0x00006000 (0x400 1kB) not protected
	# 25: 0x00006400 (0x400 1kB) not protected
	# 26: 0x00006800 (0x400 1kB) not protected
	# 27: 0x00006c00 (0x400 1kB) not protected
	# 28: 0x00007000 (0x400 1kB) not protected
	# 29: 0x00007400 (0x400 1kB) not protected
	# 30: 0x00007800 (0x400 1kB) not protected
	# 31: 0x00007c00 (0x400 1kB) not protected
	# 32: 0x00008000 (0x400 1kB) not protected
	# 33: 0x00008400 (0x400 1kB) not protected
	# 34: 0x00008800 (0x400 1kB) not protected
	# 35: 0x00008c00 (0x400 1kB) not protected
	# 36: 0x00009000 (0x400 1kB) not protected
	# 37: 0x00009400 (0x400 1kB) not protected
	# 38: 0x00009800 (0x400 1kB) not protected
	# 39: 0x00009c00 (0x400 1kB) not protected
	# 40: 0x0000a000 (0x400 1kB) not protected
	# 41: 0x0000a400 (0x400 1kB) not protected
	# 42: 0x0000a800 (0x400 1kB) not protected
	# 43: 0x0000ac00 (0x400 1kB) not protected
	# 44: 0x0000b000 (0x400 1kB) not protected
	# 45: 0x0000b400 (0x400 1kB) not protected
	# 46: 0x0000b800 (0x400 1kB) not protected
	# 47: 0x0000bc00 (0x400 1kB) not protected
	# 48: 0x0000c000 (0x400 1kB) not protected
	# 49: 0x0000c400 (0x400 1kB) not protected
	# 50: 0x0000c800 (0x400 1kB) not protected
	# 51: 0x0000cc00 (0x400 1kB) not protected
	# 52: 0x0000d000 (0x400 1kB) not protected
	# 53: 0x0000d400 (0x400 1kB) not protected
	# 54: 0x0000d800 (0x400 1kB) not protected
	# 55: 0x0000dc00 (0x400 1kB) not protected
	# 56: 0x0000e000 (0x400 1kB) not protected
	# 57: 0x0000e400 (0x400 1kB) not protected
	# 58: 0x0000e800 (0x400 1kB) not protected
	# 59: 0x0000ec00 (0x400 1kB) not protected
	# 60: 0x0000f000 (0x400 1kB) not protected
	# 61: 0x0000f400 (0x400 1kB) not protected
	# 62: 0x0000f800 (0x400 1kB) not protected
	# 63: 0x0000fc00 (0x400 1kB) not protected
STM32F05x - Rev: 2.0
(gdb)

 

If all is well, openocd will start up, connect to your NUCLEO board and then allow a gdb client to interact with it.

Good Luck!

Links

http://www.st.com/web/en/press/p3526 – NUCLEO announcement
https://github.com/ntfreak/openocd – openocd source
http://mbed.org – online ARM compiler and framework collaboration site
http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259997?icmp=nucleo-ipf_pron_pr-nucleo_feb2014 – NUCLEO-F030R8 board

Leave a Reply