Semihosting with Kinetis Design Studio

Semihosting is a technique to do printf() debugging through an active debug connection. So instead using a physical connection like RS-232 or USB CDC, the connection to the host machine is through the debugger. This post is about enabling and using semihosting with gcc and newlib/newlib-nano in Freescale Eclipse based Kinetis Design Studio (KDS) using the GNU ARM Eclipse plugins.

Semihosting Console View with output

Semihosting Console View with output

Stack and Heap Size

Printf() and the like use a lot of stack (typically a KByte, or even more). So in your project, make sure you have enough stack and heap allocated. With a Processor Expert project, you can increase the stack and heap size in the CPU component, ‘Build options’ tab. I recommend at least 0x400 for stack and 0xc00 for the heap:

Build Options Heap Size

Build Options Heap Size in Processor Expert CPU component

If not using Processor Expert, then you need to check and update your linker file: There needs to be a __HeapBase and __HeapLimit symbol in it.

._user_heap_stack :
  {
    . = ALIGN(4);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    __heap_addr = .;
    __HeapBase = .;
    . = . + __heap_size;
    __HeapLimit = .;
    . = . + __stack_size;
    . = ALIGN(4);
  } > m_data

The __heap_size and __stack_size are defined like this for me:

__heap_size = 0x0C00;                  /* required amount of heap  */
__stack_size = 0x0400;                 /* required amount of stack */

Debugger Settings

In the debugger settings, you need to have support for semihosting enabled. I’m showing here the settings for Segger J-Link in the GNU ARM Eclipse plugins.

Enable ‘Allocate console for semihosting and SWO’ in the debugger tab:

Allocate Console for Semihosting

Allocate Console for Semihosting

In the ‘Startup’ tab, check the ‘Enable semihosting’ box:

Enable Semihosting

Enable Semihosting

💡 At the time of this post, semihosting is not yet supported by the P&E GDB Eclipse plugin, but I’m told that should be supported soon. The GNU ARM Eclipse OpenOCD debug panel have similar settings.

ARM Semihosting Option in OpenOCD

ARM Semihosting Option in OpenOCD

Usage in Application

To use printf(), make sure you include

#include <stdio.h>

Below is a simple test routine which writes 2000 characters in a loop:

int i;

for(i=0;i<100;i++) {
  printf("Hello world!013456\r\n"); /* 20 characters */
}
printf("***FINISHED***\n"); /* 2000 characters finished */

Code and Data Size

Using printf() is not for free (see “Why I don’t like printf()“). Without using printf(), I have this code size (see “text, data and bss: Code and Data Size Explained” for reading the numbers):

arm-none-eabi-size --format=berkeley "semi.elf"
   text          data          bss          dec          hex       filename
   4196            44          4164          8404          20d4       semi.elf

With the above calls to printf() added, I get:

arm-none-eabi-size --format=berkeley "semi.elf"
   text          data          bss          dec          hex       filename
  10076          2152          4396       16624          40f0       semi.elf

So this adds a lot of code and data overhead.

The above code size is with newlib and Kinetis Design Studio. Newlib is not ideal for embedded applications, so there is a newlib-nano which has a smaller footprint. For this I need to add the

-nanolibc

option to the linker settings:

nanolibc option in the GNU ARM Eclipse linker settings

nanolibc option in the GNU ARM Eclipse linker settings

With this, the footprint is still high, but reduced compared to standard newlib:

arm-none-eabi-size --format=berkeley "semi.elf"
   text          data          bss          dec          hex       filename
   7056          712          4348       12116          2f54       semi.elf

Printing Floating Point

By default, printing floating point is *not* enabled in newlib by default. To enable floating point printing, I need to add

-u _printf_float

to the linker options:

-u printf_float linker option

-u _printf_float linker option

❗ In KDS, adding -u _printf_float adds about 7 KByte of code! So do not add it if you do not really need printing of float numbers.

With this, I can print float and doubles like

double d = 3.51;
...
printf("double: %f\r\n", d);

❗ To my knowledge, 64bit integer (long long) printing is *not* supported in newlib-nano.

Debugging

When debugging, there is now a ‘Semihosting and SWV’ entry in the debug view:

Debug view with semihosting

Debug view with semihosting

Clicking on that entry will show the semihosting Console view:

Semihosting Console View with output

Semihosting Console View with output

That ‘subview’ of the Console view is accessible with a small sub-menu too:

Console view with menu to open semihosting subview

Console view with menu to open semihosting subview

Summary

I usually avoid to use printf() at any price. But sometimes libraries come with it, and sometimes I need to jump over my shadow. Then printf() can be useful sometimes, even if it comes with a high price in code size, RAM usage and stack usage.

Happy Semihosting 🙂

47 thoughts on “Semihosting with Kinetis Design Studio

  1. For Cortex-M3/M4 projects generated with the GNU ARM Eclipse plug-ins you have even more options, you can select the output stream to be the semihosting STDOUT or DEBUG channel, and you can run the same code without the debugger connected, since the low level routine can detect when the debugger is not active and just return.

    Also the name is distinct, you use trace_printf() for tracing, which allows printf() to be re-targetted to any other stream (for example a socket) to meet any application requirements.

    Like

  2. > Semihosting is a technique to do printf() debugging through an active debug connection.

    To be correct, this is only one of the features of semihosting. With advanced GDB servers like J-Link, you can use all the features specified in the ARM semihosting documentation, including reading/writing files from the host machine, getting the current time, passing a command line, getting the exit code back, etc.

    These features are very useful for writing unit tests, that need to return the test results (usually as an XML file to be parsed by a continuous integration server, like Hudson/Jenkins).

    When creating projects with the GNU ARM Eclipse plug-ins, it is possible to choose from three options:
    – full semihosting (all POSIX read/write routed to host),
    – re-targetting (read/write routed to application device) and
    – no POSIX calls.

    In addition to this, the trace_printf() can be routed to:
    – ARM SWO,
    – semihosting STDOUT (a buffered device, lines displayed at n)
    – semihosting DEBUG (an unbuffered device, characters displayed one at a time).

    Like

  3. I saw this was available in GNU ARM toolchain eclipse plugin with Jlink firmware from a while ago, wrote a post about it: 2014/03/debugging-arm-freescale-microcontrollers-with-j-link-gdb-server-and-gnu-arm-toolchain-gdb-with-semihosting-in-linux/ . Nice to know we can do this in KDS. I got the KDS better version but havent tested much, been into Physics lately.

    Like

  4. Pingback: Tutorial: Nordic Semiconductor nRF24L01+ with the Freescale FRDM-K64F Board | MCU on Eclipse

  5. Pingback: printf() and scanf() with GNU ARM Libraries | MCU on Eclipse

  6. Pingback: printf() for the FRDM-K64F Board and Kinetis Design Studio | MCU on Eclipse

  7. Pingback: Semihosting with GNU ARM Embedded (LaunchPad) and GNU ARM Eclipse Debug Plugins | MCU on Eclipse

  8. Hello!
    I’m trying to use semihosting to print stuff with P&E GDB (OpenSDA) in a FRDM-KL25Z board. (I could’nt manage to make prints using virtual serial port or other solutions). However I can only print a string with 103 characters. More than this (103,104, etc) it gives me an error (something weird, related to a SIGTRAP signal) and I can continue execution, and with even more (128, which is what I want) it simply doesn’t print anything. Do you think this is related to still poor support of semihosting by P&E debugger or with semihosting limitations?

    Your website is great for any student working with Freescale microcontrollers, congratulations!

    Like

    • Hi Daniel,
      thanks :-). I have not printed very long strings. But indeed, there is naturally a buffer limit inside semihosting. Are you sending that 104 character string with now \r\n in between (no line feeds)? I have not tried your case yet, but it could be as well the library provided in KDS. Have you seen the same thing with the Segger connection too?

      Like

  9. Hello Erich,
    I tried this solution with FRDM-KL25Z, GDB PE Micro Interface Debugging (OpenSDA USB). I followed carefully all the steps (heap size, enable semihosting, include ) starting from scratch with a new KDS project with PE.
    But it prints to the console only the first character of each string. With your example, instead of Printing “Hello world!” 100 times and then “*** FINISHED ***!” in the console view I see just 100 lines with only “H” and then the “*” of the last string. What can be the reason?
    Thank you in advance for your help.

    Like

      • Thank you Erich. Yes, the \r\n is present at the end of the string: I used the exact code you gave as an example:
        int i;
        for(i=0;i<100;i++) {
        printf("Hello world!013456\r\n"); /* 20 characters */
        }
        printf("***FINISHED***\n"); /* 2000 characters finished */

        But in the console I get just:
        H
        H
        … (100 times)
        H
        *
        Strange behaviour…
        If I find the reason I will post it here.
        Thanks again!
        Cheers,
        Vittorio

        Like

  10. Pingback: Installing and using Kinetis Design Studio version 2 in Linux >> Karibe Muriuki

  11. I tried out semihosting with the latest PE opensda firmware for KL05Z and it only prints the first character. I saw this is already discussed on another post on this blog, but for k64F board, and a physical serial port. I tried adding the isatty() function and adjusting stack and heap, no success.
    Also, the serial port interface does not work for the KL05Z board with the latest PE firmware in Linux. Its enumerated well as /dev/ttyACM0, but it doesnt work. I am writing a summary of what works here: 2015/03/installing-and-using-kinetis-design-studio-version-2-in-linux

    Like

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

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

  14. Dear Erich
    I changed the stack size and heap size as given here for my boot loader project. But it is throwing these errors while building.
    c:/freescale/kds_2.0.0/toolchain/bin/../lib/gcc/arm-none-eabi/4.8.0/../../../../arm-none-eabi/bin/ld.exe: Bootloader.elf section `._user_heap_stack’ will not fit in region `m_data’
    c:/freescale/kds_2.0.0/toolchain/bin/../lib/gcc/arm-none-eabi/4.8.0/../../../../arm-none-eabi/bin/ld.exe: region `m_data’ overflowed by 352 bytes
    collect2.exe: error: ld returned 1 exit status
    make: *** [Bootloader.elf] Error 1

    How to rectify it ?
    Thanks
    Ganesh R

    Like

    • Hi Ganesh,
      You are allocating more RAM than you have available on your system. You need to reduce the amount of RAM allocated in the linker file for stack and heap by 352 bytes.

      Erich

      Like

      • Hi Erich,
        This is exactly where I got my doubt. You have written in this article, ” I recommend at least 0x400 for stack and 0xc00 for the heap “.. In my project, when I opened the Build options tab, the stack size and heap size were 0x100 by default. After reading through this article I increased my stack and heap size to 0x400 and 0xc00 respectively. When I built the code, I got the errors which I already quoted in my first comment. Now from your reply to comment, If I have to reduce the stack and heap size by 352 bytes (0x160 in hex), do you mean,
        New Stack Size => 0x0400 – 0x160 = 2A0
        New Heap Size => 0x0c00 – 0x160 = AA0

        I changed the stack and heap sizes to these values and the code built fine. But I don’t know whether this is correct ?
        Have I rectified the error correctly ?

        Like

      • Oh .. So is it enough if I reduce the heap size by 0x160. So my new size should be
        New Stack Size : 0x400
        New Heap Size: 0xc00 – 0x160 = 0xAA0
        have I understood it correctly now ?

        Like

  15. Hello,
    I am using CodeWarrior for MCU Version: 10.6.4 and I cannot find any checkbox to enable semihosting. In my case the setting windows are not the same as in the discription above (e.g. I cannot find a startup tab).
    I have an example code in which semihosting is used and it works fine. I also found the “-D__SEMIHOSTING” flag in the build options of the C compiler (under “all options:” this field is not editable). So I tried to enable semihosting in another example project by adding the phrase “-D__SEMIHOSTING” in the “others flag” field. However, then there is this error when I want to build the project: “undefined reference to ‘sys_exit'” in “__arm_end.c”
    So, how can i enable semihosting? Where are the settings hidden?
    I would be most grateful for any help.

    Like

    • Hi Andreas,
      I believe I have never used Semihosting with the CodeWarrior tools. And I do not recommend it as it is very, very slow because of the way it is done in the CodeWarrior libraries (I remember something with only few hundred bytes per second). And the panels are different because Kinetis Design Studio is using GDB, while CodeWarrior is using a proprietary debugger.
      Erich

      Like

  16. Hi Erich,
    I’m attempting to use semihosting under P&E Multilink. I have followed the steps P&E outline for enabling their part of it, and have followed your instructions(which they link to). When I try to debug my target program I get the branch showing “Semihosting Console”, but when I click on it, although the Console switches to “P&E Semihosting Console”, the debug Resume/Suspend etc. are greyed out. If I then reclick on Thread #1, the Resume etc. come back to life, but the Semihosting Console disappears.
    This is a totally bare metal project, if that makes any difference…

    Like

    • Hi John,
      double clicking on the ‘semihosting’ entry in the call stack opens the console with that view. And yes, if you don’t have the current (code) tread selected, then you cannot step/etc. This is how it is implemented with the GNU ARM Eclipse plugins and to me this is in alingment with how Eclipse thread debugging works. The Semihosting ‘thread’ is just shown there to have an easy way to switch to the console view with the semihosting output.
      As for the semihosting console disapearing: you can ‘pin’ the console view to whatever you want.

      Like

      • Thanks for the very prompt reply. I have now “pinned” the Semihosting Console, but nothing appears in it, so I guess I’m doing something else wrong, or missing some other part of the puzzle.

        Like

  17. OK, I have it working now. I changed the -specs=nosys.specs to -specs=rdimon.specs
    It maybe that I’m using a later set of tools?
    Good tip also, on one of your pages, about finding the SemiHosting Console by using the Display selected console” icon.
    Many thanks, I’m not sure that I’d be able to make any progress with Kinetis if is wasn’t for your blogs and advice. Whatever NXP are paying you it’s not enough.

    John

    Like

  18. I’m not using any SDK, by the way. When I say bare metal I mean bare metal. Stupid as it may sound, I’m writing everything from scratch, using some of the SDK files for a bit of guidance now and again. I’m wondering if SDK_DEBUGCONSOLE=0 as you mention on another page could be the trick…

    Like

    • Hi John,
      ah, ok. Some (mostly myself too) are using ‘bare metal’ for ‘without RTOS’. But to the essence, real bare metal is not using the SDK, I agree with you.
      The SD_DEBUGCONSOLE=0 is used with the SDK to disable the debug console code, as it overwrites some of the low level rxchar/txchar methods used by printf. If these overwrites are in place, semihosting does not work.

      Like

      • Thanks again for all the replies.
        Semihosting working fine now, apart from having to open the Semihosting Console view every time. I can live with that – need to get on with writing code. While I agree, in principle, with the maxim “Give me six hours to chop down a tree and I’ll spend the first four sharpening the axe”, there comes a time when you have to get some results!

        Like

  19. Hello,

    I’m doing a project with some simple image acquisition and processing in an STM32 microcontroller. I’ve been using ARM semihosting technology for debugging with standard C library fopen/fwrite functions for logging the data of the pictures on the host computer for purposes of debugging but I find it quite slow since I have sometimes to log data for RGB565 320×240 pictures (153 600 bytes), and it takes quite some time to write the data to the file on PC. As so I’m asking if you have another recomendation or alternative for debugging this kind of data (maybe using ITM SWO output?). Thank you for your attention.

    Best regards,

    Like

  20. I love the whole blog and found it super helpful for learning how to use JTAG debugging. I typically use M0 processors (like the SAMD21G or SAMD11D that don’t have SWO. Does semi-hosting work on these types of devices?

    Like

    • Semihosting depends on the debug connection and capability of the debug probe, and does not depend on SWO. Using a terminal connection with SWO is using a different technology, but does not need a direct involvement of the debug probe

      Like

What do you think?

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