Semihosting with GNU ARM Embedded (LaunchPad) and GNU ARM Eclipse Debug Plugins

In “Semihosting with Kinetis Design Studio” I used printf() to exchange text and data between the target board and the host using the debug connection. Kinetis Design Studio (KDS) has that semihosting baked into its libraries. What about if using the GNU ARM Embedded (launchpad) tools and libraries (see “Switching ARM GNU Tool Chain and Libraries in Kinetis Design Studio“)? Actually it requires two more steps, but is very easy too.

Semihosting Output

Semihosting Output

There are three things to be in place to use semihosting with the GNU ARM Embedded (Launchpad) libraries:

  1. Option in the GNU linker settings
  2. Enabling semihosting in the debugger settings
  3. Initializing the GNU libraries

Linker Option

To enable semihosting for the GNU ARM Embedded (Launchpad) libraries, I need to add

--specs=rdimon.specs

to the linker options:

💡 To get to the Tool Settings, go to the project properties. Select the project, use the menu Project > Properties > C/C++ Build > Settings.

Linker Option to Enable Semihosting

Linker Option to Enable Semihosting

In case I’m using newlib-nano and want to use printf() and/or scanf() with floating point support, I need to pull in some symbols explicitly with the linker options ‘u’:

  -u _scanf_float
  -u _printf_float

Debugger Settings

In the GNU ARM Eclipse plugins, I need to enable semihosting.

Segger J-Link

For Segger J-Link, I enable the console in the launch configuration:

Allocated Semihosting Console for Segger

Allocated Semihosting Console for Segger

Additionally I enable semihosting options in the startup options of the debugger:

Enabled Semihosting in the Startup Options for Segger

Enabled Semihosting in the Startup Options for Segger

P&E Multilink

For P&E the following settings are used:

Semihosting Settings for PnE

Semihosting Settings for PnE

Settings for OpenOCD

The following settings are used for OpenOCD:

OpenOCD Semihosting Settings

OpenOCD Semihosting Settings

Initializing the GNU Libraries

If you would now try to use semihosting with running the debugger, you probably will get error messages like this (e.g. from Segger J-Link):

WARNING: Semihosting command SYS_FLEN failed. Handle is 0.
WARNING: Semihosting command SYS_WRITE failed. Handle is 0.
WARNING: Semihosting command SYS_WRITE failed. Handle is 0.
WARNING: Semihosting command SYS_WRITE failed. Handle is 0.

The reason is that the semihosting needs to be enabled by the application. I need to call initialise_monitor_handles() before I’m using printf():

extern void initialise_monitor_handles(void); /* prototype */

int main(void) {
  initialise_monitor_handles(); /* initialize handles */
  for (;;) {
    printf("hello world!\r\n");
  }
}

With this, I can use printf() and scanf() through a debugger connection 🙂

Semihosting Printf Output

Semihosting Printf Output

Summary

While I don’t like printf() for many reasons, sometimes it is useful to exchange data with the host. Using semihosting no physical connection is required, as the communication goes through the debugger. It is somewhat intrusive, and adds code and data overhead, but the GNU ARM Embedded (launchpad) libraries (both newlib and newlib-nano) have semihosting built-in. It is a matter to enable it in the linker and debugger settings, and to initialize the handles in the application.

Happy Semihosting 🙂

30 thoughts on “Semihosting with GNU ARM Embedded (LaunchPad) and GNU ARM Eclipse Debug Plugins

  1. Did you try the “Freescale Kinetis KLxx C/C++ Project” template available in GNU ARM Eclipse plug-ins? It automatically configures all these details, the semihosting code is in source code, plus it adds a new namespace of functions, prefixed with trace_, like trace_printf(), trace_puts(), to completely separate (and so enable/disable) the tracing code from the rest of the project.

    Liked by 1 person

  2. Best way is use semihosting from cocox. 1 *c & *.h file and 1 asembly file. Only add too project and use. It’s better becouse uses only minimal resourses and don,t nedded use start as entry point. Minimal integration to program.

    Like

  3. Pingback: STM32F4 – Unit Testing with CppUTest or GoogleTest [Part I.] | Iztok's HW/SW Sandbox

  4. Pingback: Semihosting with GNU ARM Embedded (Launchpad) and Kinetis Design Studio | MCU on Eclipse

  5. Hi Erich,

    I’ve read your three posts about semihosting and am trying to enable it in KDS. I’m using the P&E Multilink USB debugger hardware. I’m pretty new to Kinetis and especially KDS, so I don’t intimately know how to get to all of the relevant dialog windows, and at last count I think there are something like 131,000 dialog windows in KDS/Eclipse. I may be off by a few thousand. Your posts are very helpful, but their helpfulness to a KDS/Eclipse newbie are limited by the fact that all of your steps jump right to the window where you make setting changes, without any explanation of how you navigate to that window.

    For example, even though I managed to find the “Enable semihosting”checkbox in my P&E debugger’s Startup tab (step 2), I’m stuck on step 1: I cannot find this “Tool Settings” tab in order to set the linker options. I feel like gone everywhere & right-clicked on everything looking for whatever “properties” item will open the magic portal to that tab, but I still haven’t been able to find it.

    Can you please give me a hint where I can find that tab/window?

    Thanks,
    -Mark Minich

    Like

    • Hi Mark,
      I appologize, but you will see after a while: once you get used to to things, you will simply skip the very basic steps, because (wrongly) assuming that everyone would know. Kind of thing on using your host (Windows/Linux/…) machine too: no need to explain that there is e.g. ‘mouse click left’ for a context menu. So yeah, your point taken, but you always can ask questions, right 🙂
      To your question: the ‘Tool Settings’ Tab is inside the project properties: select the project root folder, then use the ‘Properties’ menu. Use Project > Properties > C/C++ Build > Settings. I will add more information to the post about this, just in case.
      Thanks!

      Like

      • Thanks Erich!

        After finding that window & adding the linker option “-specs=rdimon.specs”, I rebuilt and got the error “rdimon-crt0.o: In function `_start’: (.text+0xdc): undefined reference to `__end__'”.

        I lost the link to where I found this fix, but it was for semihosting in Eclipse in general, unrelated to Freescale, KDS, or ProcessorExpert: In KDS, I went to Project Explorer -> my project -> Project_Settings -> Linker_Files -> ProcessorExpert.ld, and edited that file. The file header says “This component module is generated by Processor Expert. Do not modify it.” But I’m not sure how I’m supposed to resolve this problem without editing the file. Down near the bottom of the file is a “PROVIDE ( _end = . );”. I merely added after it (in accordance with the suggestion in the web posting I read) the following: “PROVIDE ( __end__ = . );”. After adding that line & rebuilding, printf() now outputs text to the KDS console pane.

        Any ideas how I should fix that issue for in KDS or ProcessorExpert in a way that doesn’t violate the statement in the file header (“This component module is generated by Processor Expert. Do not modify it.”)?

        Like

        • Yes, KDS 3.0.0 freshly downloaded & installed just a few days ago, on a fresh project for a custom board with a MKL26Z128VFM4. I added Processor Expert components for all of my hardware, but other than that, I haven’t customized any code in the project other than what I’ve described, and the only thing I’ve added to main() is a loop to flash a GPIO LED and printf(“printf() works!\n”). It seems to me that with such a simple out-of-the-box setup, I shouldn’t be running into compiler/linker problems with semihosting, and it doesn’t make sense that I should have to turn off Processor Expert code generation in order to preserve the workaround. For that matter, it seems like the workaround itself should be unnecessary. I’m unsure of your relationship with Freescale; should I contact Freescale with a bug report or something?

          Like

        • Hello,
          I have not seen such a problem? Semihosting is not enabled by default in the GNU ARM Embedded (launchpad) libraries in KDS v3.0.0, so you need to add the -specs=rdimon.specs to the linker flags, and that’s it?

          Like

        • Well, I don’t know what the “GNU ARM Embedded (launchpad) libraries” are; is that what you get with a plain vanilla install of KDS? I just installed KDS, started a new project, selected my processor, set up Processor Expert devices matching my previous CodeWarrior project, added a simple loop in main() to flash the LED, built, and it ran. (Why didn’t I just import my already-working CodeWarrior project? Because when I did that and tried to build, it complained that it couldn’t find “make”, so I figured I’d just create a KDS project from scratch and see if that could find “make”, which it did.) After that, I added #include >stdio.h<, printf(“Hi\n”);, checked “Enable semihosting” in my debugger settings, and added “-specs=rdimon.specs” in C/C++ Build – Settings – Tool Settings – Miscellaneous – Other linker flags. Then I rebuilt & got the “rdimon-crt0.o: In function `_start’: (.text+0xdc): undefined reference to `__end__'” error.

          Like

        • The GNU ARM Embedded (launchpad) are the GNU tools for ARM, produced by ARM. They come with the plain vanilla installation of Kinetis Design Studio v3.0.0.
          If you import a CodeWarrior project, there is a CodeWarrior project converter (but actually I don’t trust these converters: better to create a new project as you did).
          I definitely do not have your errors. As for reference, I have posted just tonight an article about semihosting with KDS v3.0.0 (I used the FRDM-K64F board), maybe this is helpful:

          Semihosting for Kinetis Design Studio V3.0.0 and GNU ARM Embedded (launchpad)

          Like

        • OK, thanks… I’m using a custom board with a MKL26Z128VFM4 microcontroller with only a few I/O pins. It’s a project created from scratch in KDS, and it would be really difficult to have one that’s less customized than this one, and I’m still getting that error unless I add that line in the linker file. The code looking for “__end__” is in the function named “_start()”, for which Eclipse says there is no source code to display. The only way I was even able to see _start()’s instructions was by changing the initial breakpoint in the debugger setup from main to _start. I’m not sure where Eclipse or the compiler is getting the code for _start, but it sure didn’t get it from me. Since adding the line “PROVIDE ( __end__ = . );” to that linker file would help me and wouldn’t break anything else even if it didn’t need it, it would be nice if Freescale would just add that line. Or else figure out why my _start() is looking for __end__ instead of _end and tell me how to fix that.

          Like

        • Usually, the _start() function is called at the end of the startup code. _start() will initialize the library and calls then main(). Typically, it expects as well _exit() somewhere, as from there the global (C++) destructors will be called. This is usually not needed for Embedded Systems, so you might add an empty _exit() instead.

          Like

        • It’s not complaining about the lack of _exit(). It’s only complaining about the lack of __end__.

          Like

        • Strange, I have not seen this. Would you mind sending me your project to the email address noted on the About page of this blog so I might have a look?

          Erich

          Like

  6. Pingback: Semihosting for Kinetis Design Studio V3.0.0 and GNU ARM Embedded (launchpad) | MCU on Eclipse

  7. Pingback: Why I am not a fan of ARM’s Semihosting feature | bitknitting

  8. Hi Erich..I’m usink JLink on FRDM-K64F,and with another project the printf works
    I followed all the steps in my projects,no compilation error.I followed all the steps,in Properties,Debugger,and linker file,but no way..to print anything.
    The odd thing is .that if i dont add the initialise_monitor_handles(); in my code,i dont’ have the massage “WARNING: Semihosting command SYS_FLEN failed. Handle is 0.”.
    The port appears in my control Panel,but printf has no effect.
    Thanks for this and all articles.
    Diego

    Like

    • Hi Diego,
      Semihosting always have been a struggle, and it depends and changes from one version of the GNU toolchain to another. I believe you have linked with the wrong libraries. You can check if there is any printf() in your linker map file?

      Like

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.