platform-ststm32 icon indicating copy to clipboard operation
platform-ststm32 copied to clipboard

Add support for multiple ST-Link adapters

Open jcw opened this issue 4 years ago • 8 comments

I've set up a Raspberry Pi as build farm for STM32 µC boards. The problem is that the ST-Link interfaces on these boards all look the same, apart from the serial number, exposed in the USB descriptors. For OpenOCD, which is the default upload tool, an extra parameter needs to be specified (hla_serial <serialnum>).

Attached is a platformio.ini file which properly uploads and connect to the matching serial port. It works, but it's messy, and I need to specify the board type again, even though PIO already has that info in its board definition file. Also included is a main.cpp, to test the builds / uploads (which will obviously fail at some point, without these exact same boards present).

blink.zip

It would be useful to streamline this all a bit more, perhaps with a new upload_serial config parameter. For the serial connection, a second simplification would be to use this same serial number to match the proper port (in minicom?) when monitor_port is not set. That way, all you'd need to pick a specific ST-Link would be to add upload serial = ....

(see also my forum post on this topic)

jcw avatar Aug 18 '21 12:08 jcw

Yep, a known issue. We still have not found the best solution for it. hla_* has multiple options -> https://openocd.org/doc/html/Debug-Adapter-Configuration.html The same story with other on-chip debuggers, J-Link, etc.

Nevertheless, PlatformIO allows you to override variables in runtime. So, let use dynamic variables and post script:

platformio.ini

[env]
platform = ststm32
framework = cmsis
monitor_speed = 115200
lib_deps = jeeh
extra_scripts = post:extra_script.py

[env:f103]
board = nucleo_f103rb
build_flags = -Wno-format -DSTM32F1
custom_hla_serial = 066DFF525257775087154313
monitor_port = /dev/serial/by-id/usb-STMicroelectronics_STM32_STLink_${env:f103.custom_hla_serial}-if02

extra_script.py

Import("env")

f_index = env.get("UPLOADERFLAGS", []).index("-f")
hla_serial = env.GetProjectOption("custom_hla_serial", None)
if f_index > 0 and hla_serial:
    env["UPLOADERFLAGS"].insert(f_index, ["-c", f"hla_serial {hla_serial}"])

Should we add an example to https://docs.platformio.org/en/latest/projectconf/advanced_scripting.html?

ivankravets avatar Sep 08 '21 16:09 ivankravets

Should we add an example to https://docs.platformio.org/en/latest/projectconf/advanced_scripting.html?

Would it make sense to integrate this into the core? E.g., if upload_protocol = stlink and upload_port is set explicitly and matches the serial number format, automatically inject the -c hla_serial <serial> command. Or instead of upload_port, support a hla_serial = .. option by standard.

maxgerhardt avatar Sep 29 '21 10:09 maxgerhardt

Yes, I think we can parse upload_protocol. Need to discuss possible formats https://openocd.org/doc/html/Debug-Adapter-Configuration.html

ivankravets avatar Sep 29 '21 13:09 ivankravets

Been a while, I'm going to investigate the extra_script.py approach. But there is still one issue with this - the names for ST-Link v2.1 and v3 differ:

monitor_port = /dev/serial/by-id/usb-STMicroelectronics_STM32_STLink_0670FF504955857567192657-if02
monitor_port = /dev/serial/by-id/usb-STMicroelectronics_STLINK-V3_004200283137510739383538-if02

One option would be to look at the devices which are currently present, and look for a match on their path names, perhaps something like this - untested:

p = os.listdir(f'/dev/serial/by-id/usb-STM*_${sernum}-if02')[0]

... with as added benefit that you wouldn't have to specify the full serial number, just enough to disambiguate.

jcw avatar Apr 26 '22 23:04 jcw

The following works (note the findex+2):

Import("env")
try:
    findex = env.get("UPLOADERFLAGS").index("-f")
    sernum = env.GetProjectOption("custom_sernum")
    env["UPLOADERFLAGS"].insert(findex+2, ["-c", f"hla_serial {sernum}"])
except:
    pass

I'm trying to also auto-generate the proper monitor port setting for Linux, given that all the info is present when custom_sernum has been specified, but I can't quite figure out how/where to set this. I imported projenv and looked at its Dump(), but there's no mention of a monitor_port.

What I'm after, is to make everything upload and connect with just these settings for each attached ST-Link board:

[env:l412]
board = nucleo_l412kb
build_flags = ${env.build_flags} -DSTM32L4
custom_sernum = 0668FF575051717867043125

I can figure out how to scan the /dev/serial/by_id/ area in extra_script.py to find the exact path, but is there a way to generate the monitor port choice in the post:extra_script.py ?

Another approach would be for PIO to allow specifying a wildcard in its monitor_port setting:

custom_sernum = 0668FF575051717867043125
monitor_port = /dev/serial/by_id/usb-STM*${this.custom_sernum}-if02

Although that's slightly less convenient, because you then still have to specify that extra line for each board.

jcw avatar Apr 27 '22 11:04 jcw

(re-opened, as this is actually still an issue)

As described here, there's a simplication possible:

monitor_port = hwgrep://0668FF575051717867043125

Which in the above context can then be written as follows (and moved to the [env] section):

monitor_port = hwgrep://${this.custom_sernum}

That also addresses the ST-Link v2 vs v3 issue, as either of them will now match.

jcw avatar Jun 07 '23 19:06 jcw

There is a related feature request https://github.com/platformio/platformio-core/issues/4460

Please vote ( 👍 ) for it.

ivankravets avatar Jun 08 '23 12:06 ivankravets

Okay, vote added. Not sure it's the same thing, but I suppose a filter for vid/pid is similar to a filter for a serial number. The key issue for me is specifying the serial number once, and using it for both uploads & serial monitor connections.

jcw avatar Jun 08 '23 21:06 jcw