How to flash STM32 from iMX8MP using OpenOCD?

I am using Hummingboard Pulse evaluation board + IMX8MP SOM with Yocto Kirkstone.

I need to flash stm32 mcu from iMX8MP. I am using custom yocto image with openocd already installed.

Here is my openocd.cfg file:

source [find interface/imx-native.cfg]
transport select swd
 
set CHIPNAME stm32f103c8
source [find target/stm32f1x.cfg]
 
# did not yet manage to make a working setup using srst
#reset_config srst_only
reset_config  srst_nogate
 
adapter srst delay 100
adapter srst pulse_width 100
 
init
targets
reset halt
program firmware.elf verify
reset
shutdown

After running command openocd, I get the following error:

root@lite-unit-openocd:~/openocd# openocd
Open On-Chip Debugger 0.11.0 (2023-11-09-16:23)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : imx_gpio GPIO JTAG/SWD bitbang driver
Info : imx_gpio mmap: pagesize: 4096, regionsize: 131072
Bus error

Mcu is currently connected to pins on connector J9 : 55 - SWCLK1 and 59 - SWDIO1.
From SOM schematic I can see that pin 59 is not connected to J9 connector.

My questions are:

  • which pins of the SOM can be used for swd?
  • which pin names to use in imx-native.cfg file?

imx-native.cfg file:

# SPDX-License-Identifier: GPL-2.0-or-later

#
# Config for using NXP IMX CPU
#
# This is best used with a fast enough buffer but also
# is suitable for direct connection if the target voltage
# matches to host voltage and the cable is short enough.
#
#

adapter driver imx_gpio

# For most IMX processors 0x0209c000
imx_gpio_peripheral_base 0x0209c000

# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET
# These depend on system clock, calibrated for IMX6UL@528MHz
# imx_gpio_speed SPEED_COEFF SPEED_OFFSET
imx_gpio_speed_coeffs 50000 50

# Each of the JTAG lines need a gpio number set: tck tms tdi tdo.
# Example configuration:
# imx_gpio_jtag_nums 6 7 8 9

# SWD interface pins: swclk swdio
# Example configuration:
imx_gpio_swd_nums 1 6

# imx_gpio_trst_num 10
# reset_config trst_only

# imx_gpio_srst_num 11
# reset_config srst_only srst_push_pull

# or if you have both connected,
# reset_config trst_and_srst srst_push_pull

Are you using openocd from our repository that is patched to work with the iMX8 SOCs? GitHub - SolidRun/openocd: SolidRun's OpenOCD Mirror However this was originally tested with the iMX8MQ SOCs, I would have to verify if it is also correct for the iMX8MP

Build fails at make.

I do:

git clone https://github.com/SolidRun/openocd

cd openocd

./bootstrap

./configure --enable-imx_gpio

make

Error log:

In file included from ./src/flash/common.h:21,
                 from src/flash/nor/core.h:25,
                 from src/flash/nor/imp.h:22,
                 from src/flash/nor/jtagspi.c:22:
src/flash/nor/jtagspi.c: In function 'jtagspi_write_enable':
./src/helper/log.h:130:9: error: 'status' may be used uninitialized in this function [-Werror=maybe-uninitialized]
  130 |         log_printf_lf(LOG_LVL_ERROR, __FILE__, __LINE__, __func__, expr)
      |         ^~~~~~~~~~~~~
src/flash/nor/jtagspi.c:262:18: note: 'status' was declared here
  262 |         uint32_t status;
      |                  ^~~~~~
src/flash/nor/jtagspi.c: In function 'jtagspi_wait':
src/flash/nor/jtagspi.c:249:29: error: 'status' may be used uninitialized in this function [-Werror=maybe-uninitialized]
  249 |                 if ((status & SPIFLASH_BSY_BIT) == 0) {
      |                     ~~~~~~~~^~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[2]: *** [Makefile:3312: src/flash/nor/jtagspi.lo] Error 1
make[2]: Leaving directory '/home/root/test/openocd'
make[1]: *** [Makefile:4223: all-recursive] Error 1
make[1]: Leaving directory '/home/root/test/openocd'
make: *** [Makefile:1981: all] Error 2

It most likely needs a patch for the newer gcc version that has turned those warnings into errors. Just add “-Wmaybe-uninitialized” to your CFLAGS variable.

Thanks for your quick response. Where do I find CFLAGS variable? I found it in make file and appended

Werror=maybe-uninitialized

to it.

CFLAGS = -g -O2 -Werror=maybe-uninitialized

Command make still produces the same error.

pflander to compile, disable treating warnings as errors (-Werror) with the --disable-werror configure option:

./configure --enable-imx_gpio --disable-werror

Thanks. Compile process goes further, but still finishes with an error:

/usr/lib/gcc/aarch64-poky-linux/11.3.0/../../../../aarch64-poky-linux/bin/ld: src/.libs/libopenocd.a(libocdjtagdrivers_la-bitbang.o):/home/root/test/openocd/src/jtag/drivers/bitbang.h:60: multiple definition of `bitbang_swd'; src/.libs/libopenocd.a(libocdjtagdrivers_la-imx_gpio.o):/home/root/test/openocd/src/jtag/drivers/bitbang.h:60: first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:2939: src/openocd] Error 1
make[2]: Leaving directory '/home/root/test/openocd'
make[1]: *** [Makefile:4223: all-recursive] Error 1
make[1]: Leaving directory '/home/root/test/openocd'
make: *** [Makefile:1981: all] Error 2

Did you run configure command without cleaning the previous build results?

Can you try:

git clean -xxdf
./bootstrap
./configure --enable-imx_gpio --disable-werror
make -j$(nproc --all)

It seems you get a linker error because of some previous build artifacts. For me it builds with the instructions above.

Here the working solution:

Yocto recipe:

DEPENDS += "libgpiod"
EXTRA_OECONF = "--enable-linuxgpiod --enable-imx_gpio --enable-sysfsgpio --disable-stlink --disable-ti-icdi --disable-ulink --disable-usb-blaster-2 --disable-vsllink --disable-xds110 --disable-osbdm --disable-opendous --disable-aice --disable-usbprog --disable-rlink --disable-armjtagew --disable-cmsis-dap --disable-kitprog --disable-usb-blaster --disable-presto --disable-openjtag --disable-jlink --disable-werror"
SRC_URI += " \
    file://0001-Port-SolidRun-openocd-patch-ea85b35.patch \
    file://0002-SolidRun-Add-Documentation-for-Building-OpenOCD.patch \
"
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"

Openocd.cfg

adapter driver linuxgpiod

linuxgpiod_gpiochip 2
linuxgpiod_swd_nums 20 23

transport select swd

set CHIPNAME stm32l412

source [find target/stm32l4x.cfg]

reset_config srst_nogate

adapter srst delay 100
adapter srst pulse_width 100

init
targets
reset halt
program firmware.elf verify
reset
shutdown