Cannot Get Semihosting To Print (STM32F4, OpenOCD)

Asked by fpgaminer

When I try to use semihosting to simply print to the console, my program compiles fine, and runs without breakpoints/exceptions/crashes, but nothing is sent to the console. This is with:

* arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.7.3 20121207 (release) [ARM/embedded-4_7-branch revision 194305]
* openocd 0.6.1
* STM32F4DISCOVERY

My link flags include "--specs=nano.specs --specs=rdimon.specs -lc -lc -lrdimon"

I run OpenOCD, and then connect GDB to it to load the program to flash and run it. I enable semihosting by issuing the command "monitor arm semihosting enable". The program's stdout is printed to neither OpenOCD nor GDB.

However, if I implement semihosting myself:

void dbg_write_str(const char *msg)
{
#ifdef __arm__
 // Manual semi-hosting, because the GCC ARM Embedded's semihosting wasn't working.
 for (; *msg; ++msg)
 {
  // Moves a pointer to msg into r1, sets r0 to 0x03,
  // and then performs a special breakpoint that OpenOCD sees as
  // the semihosting call. r0 tells OpenOCD which semihosting
  // function we're calling. In this case WRITEC, which writes
  // a single char pointed to by r1 to the console.
  __asm__ ("mov r1,%0; mov r0,$3; BKPT 0xAB" :
                                             : "r" (msg)
                                             : "r0", "r1"
  );
 }
#else
 printf ("%s", msg);
#endif
}

That works just fine, and I see output in OpenOCD's console. I haven't looked at rdimon's code yet. Does it implement semihosting correctly or am I doing something wrong?

Thank you.

Question information

Language:
English Edit question
Status:
Expired
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
chengbin (can-finner) said :
#1

semihosting has been used elsewhere, so I would expect it is implemented correctly in newlib/newlib-nano. Could you check against which version of library you are linking by adding "-v" in linking command line?

Thanks.

Revision history for this message
fpgaminer (fpgaminer) said :
#2

Thank you for replying. I should note that the startup code I'm using doesn't call out to any external functions. Do any functions need to be called before printf/puts/etc will work correctly in this scenario? I know 'initialise_monitor_handles' needs to be called for the file related functions to work, but printf is supposed to work without it.

I took a quick look at the disassembled output to look for bkpt instructions. A few are in there, besides my own, presumably from librdi. However I didn't see any that explicitly called the 0x03 semihosting function, which is OUTPUTC.

Here's what -v added to the output:

Using built-in specs.
Reading specs from /opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/lib/nano.specs
rename spec link to nano_link_backup
Reading specs from /opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/lib/rdimon.specs
rename spec link to old_link
COLLECT_GCC=arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/lto-wrapper
Target: arm-none-eabi
Configured with: /home/build/work/GCC-4-7-build/src/gcc/configure --target=arm-none-eabi --prefix=/home/build/work/GCC-4-7-build/install-native --libexecdir=/home/build/work/GCC-4-7-build/install-native/lib --infodir=/home/build/work/GCC-4-7-build/install-native/share/doc/gcc-arm-none-eabi/info --mandir=/home/build/work/GCC-4-7-build/install-native/share/doc/gcc-arm-none-eabi/man --htmldir=/home/build/work/GCC-4-7-build/install-native/share/doc/gcc-arm-none-eabi/html --pdfdir=/home/build/work/GCC-4-7-build/install-native/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-lto --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-newlib --with-headers=yes --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/home/build/work/GCC-4-7-build/install-native/arm-none-eabi --build=i686-linux-gnu --host=i686-linux-gnu --with-gmp=/home/build/work/GCC-4-7-build/build-native/host-libs/usr --with-mpfr=/home/build/work/GCC-4-7-build/build-native/host-libs/usr --with-mpc=/home/build/work/GCC-4-7-build/build-native/host-libs/usr --with-ppl=/home/build/work/GCC-4-7-build/build-native/host-libs/usr --with-cloog=/home/build/work/GCC-4-7-build/build-native/host-libs/usr --with-libelf=/home/build/work/GCC-4-7-build/build-native/host-libs/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='GNU Tools for ARM Embedded Processors' --with-multilib-list=armv6-m,armv7-m,armv7e-m,armv7-r
Thread model: single
gcc version 4.7.3 20121207 (release) [ARM/embedded-4_7-branch revision 194305] (GNU Tools for ARM Embedded Processors)
COMPILER_PATH=/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/:/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/:/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/bin/
LIBRARY_PATH=/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/armv7e-m/:/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/lib/armv7e-m/:/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../arm-none-eabi/lib/armv7e-m/:/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/:/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/:/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/lib/:/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../arm-none-eabi/lib/
COLLECT_GCC_OPTIONS='-g' '-Wall' '-Wno-missing-braces' '-std=c99' '-I' '../include' '-I' 'src' '-mthumb' '-mcpu=cortex-m4' '-mfloat-abi=soft' '-I' '../libraries/STM32F4xx_StdPeriph_Driver/inc' '-I' '../libraries/CMSIS/ST/STM32F4xx/Include' '-I' '../libraries/CMSIS/Include' '-g' '-L../build' '-v' '-T' 'stm32f4_flash.ld' '-o' 'build/main.elf'
 /opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/collect2 --sysroot=/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../arm-none-eabi -X -lrdimon -o build/main.elf /opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/armv7e-m/crti.o /opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/armv7e-m/crtbegin.o /opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/lib/armv7e-m/rdimon-crt0.o -L../build -L/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/armv7e-m -L/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/lib/armv7e-m -L/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../arm-none-eabi/lib/armv7e-m -L/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3 -L/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc -L/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/lib -L/opt/gcc-arm-none-eabi-4_7-2012q4/bin/../arm-none-eabi/lib build/src/main.o build/src/aes.o build/src/base58.o build/src/drbg.o build/src/ecdsa.o build/src/finite_field.o build/src/hmac.o build/src/pbkdf2.o build/src/random.o build/src/ripemd160.o build/src/sha256.o build/src/keychain.o build/src/system_stm32f4xx.o build/src/startup_stm32f4xx.o ../build/libstrong-arm.a -lstrong-arm -Map build/main.map -lc_s -lc_s -lrdimon --start-group -lgcc -lc_s --end-group /opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/armv7e-m/crtend.o /opt/gcc-arm-none-eabi-4_7-2012q4/bin/../lib/gcc/arm-none-eabi/4.7.3/armv7e-m/crtn.o -T stm32f4_flash.ld

Revision history for this message
Joey Ye (jinyun-ye) said :
#3

Hi,

You verbose message looks no problem. I suspect it is the similar issue as https://answers.launchpad.net/gcc-arm-embedded/+question/231856

Please try either add "\n" to end of your message, or add to begin of your main: setvbuf(stdout, NULL, _IONBF, 0);

Thanks,
Joey

Revision history for this message
fpgaminer (fpgaminer) said :
#4

Adding "\n" did not help. Calling setvbuf caused the program to crash. I suspect there are initialization calls to newlib-nano that need to be made (my startup code does nothing except the normal memory zero-ing and bringing the MCU online), but I'm not sure what.

Thank you.

Revision history for this message
Joey Ye (jinyun-ye) said :
#5

> Thank you for replying. I should note that the startup code I'm using doesn't call out to any external functions. Do any functions
> need to be called before printf/puts/etc will work correctly in this scenario? I know 'initialise_monitor_handles' needs to
> becalled for the file related functions to work, but printf is supposed to work without it.
Initialization of semihosting is required, and is done in standard libc initializer _mainCRTStartup, which calls 'initialise_monitor_handles' to do the real work. So if your startup code doesn't call the former, it should call the latter. Also _mainCRTStartup cleans up BSS region, which your startup code should do the same.

Generally I'd recommend you call this standard initializer after your startup code, which doesn't increase code size too much.

> I took a quick look at the disassembled output to look for bkpt instructions. A few are in there, besides my own, presumably
> from librdi. However I didn't see any that explicitly called the 0x03 semihosting function, which is OUTPUTC.
Printf doesn't use 0x3 for output, it uses 0x5, WRITE instead.

- Joey

Revision history for this message
fpgaminer (fpgaminer) said :
#6

Thank you for the help Joey, I appreciate it. For now, I'm going to stop working on this problem; it's not worth the effort to solve.

For reference, I added a call to _mainCRTStartup, but it just seems to run forever.

Revision history for this message
Launchpad Janitor (janitor) said :
#7

This question was expired because it remained in the 'Open' state without activity for the last 15 days.