cancel
Showing results for 
Search instead for 
Did you mean: 

Using H7RS with the VS code extension - bugs and fixes

efthym
Associate

I attended a workshop on the H7RS family (https://github.com/ST-TOMAS-Workshop/stm32h7s_workshop) and was given a nucleo board. Thanks a lot ST!
But when I tried to do the first step, specifically "1_external_memory" using VS code and the STM32 extension, I run into trouble. I managed to get through it, so as a thanks for the board, I describe the problems and my fixes below.
It is quite a long post but I hope it will save time and frustration for other people.

My development environment is
Linux - Ubuntu 22.04, CubeMX 6.12.0, CubeCLT 1.16.0,
STM32H7RS library 1.1.0, STM32 VS Code Extension 2.1.0,
Nucleo H7S3L8

I made a slight modification to the above tutorial as I started the cubeMX project from the nucleo board rather than the plain MCU in the workshop. I also got a newer STM32H7RS HAL library 1.1.0

Because I am using the VS code extension, I used CMake for code generation.
Then I imported the generated code into VS code as explained in the extension documentation, made the changes to the generated code (add a pin toggle in Appli/main and invalidate the caches in Boot/main), selected the Debug configuration and built the project.

The build fails. The generated "mx-generated.cmake" files for the application (under Appli) and for the Boot have the wrong path for the startup file. You have to manually fix the paths: just add "Core/" and make the "S" lowercase.

With the above fixes the build succeeds. Now continue to debugging. The VScode extension has already created a "Debug external memory - ST-Link" launch task, but trying that fails. The programmer says:
Error: Wrong external loader file: <projectPath>/ExtMemLoader/build/<proj>_ExtMemLoader.elf

To fix this requires multiple steps.
The immediate problem is that (although you provide a full path,) cubeProgrammer expects the external loader to be in a "ExternalLoader" directory under its "bin". It also expects a ".stdlr" extension; the file is just the same compiled ELF.
Minor problem: the cubeCLT is installed under /opt/st, so the above directory is not writeable by normal users. You can make the "ExternalLoader" directory writable if you are now worried about someone sabotaging your files there

  1. copy the file (ExtMemLoader/build/<name>.elf to /opt/st/stm32cubeclt_1.16.0/STM32CubeProgrammer/bin/ExternalLoader/<name>.stldr. Actually there is a "postbuild.sh" file under ExtMemLoader" which normally takes care of this, but it does not work with the CMake build option. More on this later.
  2. modify the .vscode/launch.json file to point to this file. You will find it under "serverArgs", "-el".

Try to start debugging again but you get the exact same error as before, with the original .elf file mention as a wrong external loader file.

To fix that you need to modify the .vscode/tasks.json file. Find a "-el" string in a list and use the same file (as in launch.json) as the next item on the list

Try once more. Now the error message changes: the external loader cannot be loaded.

The problem here is that there is something missing in the external loader compiled file. This was the most difficult obstacle in getting this tutorial to work in my environment.
The culprit is in the ExtMemLoader generated linker file "stm32h7rsxx_extmemloader_stm32cube.ld", specifically the line

 

KEEP(*stm32_device_info.o ( .rodata* ))

 

With CMake the object files do not get a simple .o extension. The extension is .c.obj so the above line skips the device_info section!
Just replace ".o" with ".*" which should also work for plain .o files for other build configurations.

Build again (may have to clear first) and copy the .elf file as an .stldr file in the right place.
Back to the Debuger and after a relatively long wait for the mass erase of the external flash memory, you get the debugger stopped at the main of the Boot application. You can set a breakpoint at the main of the Appli(cation) and you are good to go.

 

Extra stuff. Probably useful for fixing minor bugs in cubeMX/CMake

You can modify the postbuild.sh and mx-generated.cmake under ExtMemLoader to make the build process smoother. I don't know if it is worth the effort because you'd probably just need to build the external loader once and then just continue developing/debugging the application. Anyway here's how to do this.

In ExtMemLoader/mx-generated.cmake, you will find where postbuild.sh is called. For my environment I see a ${cubeide_cubeprogrammer_path} variable which was not replaced by cubeMX when it generated this file.
I simply added

 

set(cubeide_cubeprogrammer_path "/opt/st/stm32cubeclt_1.16.0/STM32CubeProgrammer/bin")

 

before the "add_custom_command"

There is a possibly related minor bug in cubeMX:
You cannot modify STM32CubeProgrammer Path, in Project Manager, Boot Path and Debug Authentication. The path under the cubeCLT it is not accepted. It requires a .exe file extension!

The postbuild.sh does not support CMake. I made a few changes trying to keep it as close to the original as I could. Though I have to say, I don't like it at all; it can/should be made better.

- First check the the STM32_PRG_PATH is set and where it points at. In my case I did a stand-alone installation of STM32CubeProgrammer and it ended up in my home directory. So this had to be changed to point to the cubeCLT version. Otherwise the external loader files will end up in the stand-alone version of the programmer while VS code will try to run from the cubeCLT programmer.
- In the middle of postbuild.sh, after the two existing loops which try to detect the IDE, add the following

 

for j in $(find "$projectdir" -name "CMakeLists.txt" 2>/dev/null); do
  CMAKEPROJ=true
done

 


- Move the "fi" to end the if [ "$STM32CUBE" = true ] before the
if [ -d "$cubeide_cubeprogrammer_path" ]; then
This was probably a mistake as the file intentation suggests that this was the original intention. Anyway with this change you do get an error message is the file cannot be copied in the programmer's directory.
- Add the following (after the "fi" and before the chech for the cubeide_cubeprogrammer_path), to support the CMake build. It is identical to that of CubeIDE, appart for the message. This can be done better..

 

if [ "$CMAKEPROJ" = true ]; then
  echo "CMAKE IDE is found!"
  extension=".elf"
  for j in $(find "$projectdir" -name "*$keyword*$extension" 2>/dev/null); do
    projectCopy="$j"
  done

  if [ "$cubeprog" = 1 ]; then
    for f in "$projectCopy"; do
      cp -a "$f" "$dest_dir/$(basename "${f%.*}")$new_ext"
    done
    if [ $? -eq 0 ]; then
      echo "File copied successfully under STM32CubeProgrammer."
    else
      echo "warning :: File copy failed under STM32CubeProgrammer please check that the folder exists or you have the right permission to copy the ExtMemLoader."
    fi
  fi
fi

 

Finally a suggestion for STM32 VS code extension:

There is a ${command:STM32VSCodeExtension.bootFlashExtMemLoaderTarget} variable available which could be used to set the correct path to the external loader after it has been copied into cube programmer ExternalLoaders directory. However it contains the .elf file extension. There should be a way to get the filename only and thus save a user-made modification to the launch.json file.

1 REPLY 1
CMYL
ST Employee

Hello @efthym 

 

Thank you for your important analysis. I shared your feedback with internal STM32 VS Code team.

(Submitted Ticket is 189230, this tracking number is for internal tracking)

 

Best regards