Using multiple ST-Link devices

And getting around their weird serial numbers


Recently I discovered a very useful patch to openocd: the command "hla_serial". The patch is now merged into master (2014/09/22), so just get the latest revision from git and compile:
git clone git://repo.or.cz/openocd.git
cd openocd
./bootstrap
./configure --enable-maintainer-mode --enable-stlink
make
sudo make install

This is quite straightforward for a recent linux distro, compiling on windows usually is more tricky. I'm using cygwin on win7, mingw and libusbx-1.0.12-win to create a native 32 bit windows binary. Since cygwin pkg-config doesn't know about libusbx, you'll have to tell configure that manually:
  • Get libusbx-1.0.12-win.7z from sourceforge
  • unzip and move the contents to $HOME/openocd/libusbx-1.0.12-win/
  • cd openocd
    git clone git://repo.or.cz/openocd.git
    cd openocd
    ./bootstrap
    export LIBUSB1_CFLAGS="-I$HOME/openocd/libusbx-1.0.12-win/include/libusbx-1.0/ -DHAVE_LIBUSB_ERROR_NAME"
    export LIBUSB1_LIBS="-L$HOME/openocd/libusbx-1.0.12-win/MinGW32/static/ -lusb-1.0"
    ./configure --enable-maintainer-mode --host=i686-w64-mingw32 --prefix= --enable-stlink
    make bindir="bin" pkgdatadir=
    Replace "32" by "64" and "bin" by "bin-x86" to create a 64-bit windows binary.

    According to the usual procedure, this will show up in the next release of openocd (0.9.0). At some point Freddie Chopin might provide binaries for windows. Check for releases later than 22.09.2014.

    Using a test setup with two ST nucleo boards, everything works fine: Find the serial number of the first embedded stlink (e.g. use lsusb -v) and create a config file for openocd like this one. Then create the config file for the second board. Now you are able to address each board individually using its config file. Note the only difference between the two files is the serial number of the embedded stlink.

    Another way is to supply the serial number as an additional parameter:
    openocd -f board/st_nucleo_f103rb.cfg -c "hla_serial "066EFF534951775087194310""
    This way, you won't have to create new or modify the supplied configuration files. You'll have to add options to set the gdb port etc. if you want to run more than one instance of openocd.

    Things start to get interesting when you use the standalone ST-Link/V2:
    Imagine a test setup like this one:

    This is basically a homemade dev board with two STM32F103CB chips, one of them connected to the LCD module, the other isn't, but e.g. acquires some analog values. I want to read the value at the LCD. The controllers are connected using a SPI port. So I have to implement something like this:

  • Controller 1 acquires the value using the ADC
  • Controller 1 fills its SPI data buffer with the aquired value
  • Controller 2 initiates the SPI transfer an reads the value from controller 1
  • Controller 2 finally displays the value in human readable form using the LCD module

  • This is just intended as a example, this isn't the real purpose of this hardware.
    So I have to write code and debug 2 controllers to get this task done. As I'm a lazy person, I do not want to switch debuggers between the two controllers or whatever. I want to use 2 debuggers and address them by their config files, as I did with the nucleo boards above. Using this setup, I can write all the neccessary steps to compile and flash the controllers into one common Makefile. The development turnaround cycle gets then really simple:
  • Edit the code using your favourite editor
  • type "make" and watch everything done automatically
  • While creating and testing the necessary config files, I've noticed that the standalone ST-Links use serial numbers containing unreadable characters. Look at the output of lsusb -v to see what I mean. Well, it's still possible to put such a serial number into a openocd config file, and here is the second one. Basically you'll have to convert the strange characters to a "\xnn" notation, where 'nn' is the hexadecimal value of the char. I did this manually here, it depends on your console or file viewer how easy this task will be.
    Note that you won't be able to use them both at the same time by starting two instances of openocd and gdb. To accomplish this, you'll have to specify different port numbers for openocd like I did in this config file with port numbers.

    Having done that, I discovered that connecting to the st-link works only once. After the first usage, the st-link magically changes its serial number to "000000000001". See the lsusb -v output. Someone posted this problem at the code review page of openocd, to be honest, I didn't test this before, but I was able to reproduce the behaviour here. It's of no use to create config files with that serial number, since both st-link will have the same serial after their first usage. You can power cycle the ST-Links to restore the serial, but this is not the intended way I want to use them.

    And now, just keep calm and get your update from the ST website. Update the ST-Link devices to the lastest version (V2.J21.S4), even if the updater reports this version for your ST-Link before the update. I had this once, but cannot reproduce, since the old version is gone after updating and you cannot read out the STM32 chip inside the ST-Link. You might have to use the evil (windows) to update the adapters, I didn't try wine, since a windows box was available.

    Having successfully updated the ST-Link/V2 devices, my setup works as intended. The strange serial numbers are still there, but at least they are constant now and do not change any more while using the stlink.

    Look here for some of my logs and config files that I created while testing the setup.

    Look here: The STM32 files for my other STM32 related pages. ... und ein Zaehlpixel hab ich auch :-)