Tools – Getting a grip on Semi-hosting

Semi-hosting is a debugging capability supported by ARM processors that allows the embedded target to access i/o capabilities on a host PC through the debugging interface. The i/o capabilities are most often used with printf to transmit text data to a virtual terminal within the debugging environment but it can also be used for file access and for keyboard input.

Semi-hosting capabilities are usually implemented through a special library that interfaces with the standard C libraries. In many cases, the library is included in the development environment by default. For example, in the Renesas Synergy(TM) platforms e2 Studio, the –specs=rdimon.specs option is included by default which includes the hooks for using semi-hosting. All a developer needs to do is include the standard library and all printf statements in their module are redirected through the semi-hosting facilities.

At the lowest levels, semi-hosting is implemented in the ARM core by triggering either the SWI instruction (Software Interrupt), which has been replaced by the SVC instruction (Supervisory Call). On some parts, the BKPT instruction might also be used. When the instruction is executed, the processor stops executing the application and waits for the debugger to access the processor and retrieve the contents that need to be transferred to the host.

Semi-hosting at the surface seems like a great idea. Not all embedded targets have the i/o capabilities to connect a keyboard, screen or a file system. Semi-hosting provides the ability to have this functionality through the host environment and use the debugger to transfer the data. However, there are several major problems with semi-hosting that make it a capability that I avoid at nearly all costs.

First, semi-hosting is ridiculously slow. The fact that the CPU is halted and the debugger must access the core, transfer to the host and then resume operation causes a delayed execution which can be tens of milliseconds! This is longer than most system tick durations and can wreak havoc on the softwares real-time performance. For example, below is a screen shot I took to measure the time it takes to print “Hello World!\r\n” over semi-hosting. As you can see, it took over 60 milliseconds!

Second, when semi-hosting is enabled, the processor halts and waits for the debugger. If the debugger is not attached to the system, the processor will halt indefinitely! This means that semi-hosting can only be used during debugging and a developer must compile out their semi-hosting capabilities for production. Otherwise, their device may hang-up on their end-user as it waits for a debugger to retrieve information and resume operation. This blocking behavior is disappointing but a fact developers need to live with.

Finally, semi-hosting is not deterministic. The execution times can vary widely and potentially drive developers crazy as they try to track down strange behaviors in their software that are really stemming from using semi-hosting. In a real-time application, determinism is critical and anything that can affect this should be avoided at all costs.

Semi-hosting is a really neat feature that can certainly be helpful to developers in many instances. However, in most cases, I’ve found it to be more of a problem than an asset. All the same, it’s important for us developers to understand the tools and capabilities that are available to us. I would still recommend that you take an hour or so to explore the semi-hosting capabilities that exist in your toolchain and understand how they effect timing and your ability to develop your system.

Share >

4 thoughts on “Tools – Getting a grip on Semi-hosting

  1. Which is why you should become familiar with Arm’s ITM, DWT and ETM debug features (available in many SoC implementations using Arm) and their its ability to send information out the trace port. You can send 186 to 32 bits of information by simply writing to a register with a single instruction. The one restriction is that the addresses are privileged; however, many embedded applications run in privileged mode all the time. The following article from IAR goes into more detail . These features are accessible from other vendor tools as well. You would also be aware of this by taking a course in Arm processor architecture for software design.

  2. We had same concern with printf slowness and decided to develop our own semi-hosting system. As David said, it is possible to have an HelloWorld event sent through SWO (DWT) in a STM32F103 microcontroller running at 72MHz,and it takes only 150ns of the microcontroller execution time (time needed to write a integer). Of course, send it via UART (SWO) takes a lot more time but DWT fortunately have a FIFO.
    Segger also have a free tool called SystemView for their JLink emulator.

  3. I just loved the Segger RTT over my little asset, J-Link Edu. It took 16.75 us to print the following string “Hello World Segger RTT\n” from my STM32F030F4 mcu, runs at 48 MHz.

  4. Another option that I’ll be posting at a later date is to use the ITM if it’s available on the part. A simple text statement such as “LED On!” or “LED Off!” takes ~5 microseconds using J-Link On-board (OB).

    Thanks for the comments!

Leave a Reply

Your email address will not be published. Required fields are marked *

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