System Workbench for STM32

Semihosting with OpenSTM32 and STM32F446RE Nucleo

How can I implement semihosting for printf in OpenSTM32? I’m using STM32F446Re nucleo board (ST Link included) using provided OpenOCD.

you need to:

  1. add “-specs=rdimon.specs -lc -lrdimon” to (Project -> Properties -> C/C++ Build -> Settings -> MCU GCC Linker -> Linker flags)
  2. add extern void initialise_monitor_handles(void); above main
  3. add initialise_monitor_handles(); at the beggening og main function
  4. use printf, putc, puts to output messages via semihosting

Another thing you need to add “monitor arm semihosting enable” to intitialization commands in your debug configuration

If I do that I get “multiple definition of `initialise_monitor_handles’” error (syscalls.c redefine it). If I remove syscalls.c from the build (right click on file -> Resource configurations -> Exclude from Build) I get “undefined reference to `initialise_monitor_handles()’”.

Any tip here?

try “-specs=nosys.specs -specs=rdimon.specs -lc -lrdimon” in (Project -> Properties -> C/C++ Build -> Settings -> MCU GCC Linker -> Linker flags)
have tried this (adding “-specs=nosys.specs” to linker flags & without syscalls.c)
I did that in the first place, but the error occurred. Can’t figure out why though

Can you copy the Linker command and output from the Console View?


arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -L”path/to/lib1” -L”path/to/lib2” -L”path/to/lib3” -L”path/to/lib4” -specs=nano.specs -specs=rdimon.specs -lc -lrdimon -T”path/to/myproject\LinkerScript.ld” -Wl,-Map=output.map -Wl, -gc-sections -fno-exceptions -fno-rtti -o “gateway.elf” @”objects.list” -llib1 -llib2 -llib3 -llib4

I deleted library folder paths and name because I shouldn’t publish those names. If I put syscalls.c on build path I get this:

src/syscalls.o: In function `initialise_monitor_handles’:
D:.../src/syscalls.c:72: multiple definition of `initialise_monitor_handles’
c:/ac6/systemworkbench/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.7.0.201602121829/tools/compiler/bin/../lib/gcc/arm-none-eabi/5.2.1/../../../../arm-none-eabi/lib/armv7e-m/fpu\librdimon_nano.a(rdimon-syscalls.o):syscalls.c:(.text.initialise_monitor_handles+0x0): first defined here

and then repeated for every function in syscalls.c, followed by undefined reference to `initialise_monitor_handles()’ in main.cpp

Your project is in C++. The C functions from libraries should be declared in extern “C” to be used in C++.

Replace :
extern void initialise_monitor_handles(void);
extern “C” void initialise_monitor_handles(void);

Hope it works,

Thanks! This helped me.

I needed this to work in the QEMU and the corresponding options to enable semihosting in the emulator are:

“C:\Program Files\GNU ARM Eclipse\QEMU\2.8.0-201612271623-dev\bin\qemu-system-gnuarmeclipse.exe” -verbose -verbose -board STM32F4-Discovery -nographic -d unimp,guest_errors -semihosting --image myimage.elf

Don’t forget to have \n when using printf or it won’t show up, as below:
printf(“%x\n”, test0); // print out variable test0 on the debug console.

puts() doesn’t need \n