Difference between revisions of "Host-based formatting"

From SEGGER Wiki
Jump to: navigation, search
(Host-based formatting)
(Host-based formatting)
Line 9: Line 9:
 
==Host-based formatting==
 
==Host-based formatting==
   
For MCUs with very small amounts of flash and RAM, debug messages delivered through semihosting can be an unacceptable burden, consuming most of the flash and RAM space of the target thereby leaving very little space for the application. For instance, MSP430 processors can have as little as 256 bytes of RAM and 1 KB of flash. Usually a PCB would be populated with a larger device for product development to enable larger debug builds to be programmed into the flash. However, some device families do not offer larger memory versions that could be used for development and, therefore, reducing the footprint of debug code is essential for the application to fit.
+
For MCUs with very small amounts of flash and RAM, debug messages delivered through semihosting can be an unacceptable burden, consuming most of the flash and RAM space of the target thereby leaving very little space for the application. For instance, MSP430 processors can have as little as 256 bytes of RAM and 1 KB of flash. Usually a PCB would be populated with a larger device for product development to enable larger debug builds to be programmed into the flash. However, some device families do not offer larg memory versions that could be used for development and, therefore, reducing the footprint of debug code is essential for the application to fit.
   
 
===Advantages===
 
===Advantages===

Revision as of 22:48, 3 July 2019

Host-based formatting is a technology that reduces the on-target code and data size associated with typical semihosting.

Classic semihosting

Many embedded system development tools offer support for Semihosting where a host computer system provides I/O and other services to an embedded target. Semihosting is typically used during product development and is not included as part of the embedded system's code when the product is released.

Typical semihosting provides very simple I/O functions such as reading and writing characters to the terminal and to files. Such an implementation requires target code on the embedded system that implements the C-based format specifications used in calls to printf and scanf. This code is typically bulky even after eliminating floating-point I/O: 2k to 4k of code can be brought into the application just to support printf which will not be present in the production code.

Host-based formatting

For MCUs with very small amounts of flash and RAM, debug messages delivered through semihosting can be an unacceptable burden, consuming most of the flash and RAM space of the target thereby leaving very little space for the application. For instance, MSP430 processors can have as little as 256 bytes of RAM and 1 KB of flash. Usually a PCB would be populated with a larger device for product development to enable larger debug builds to be programmed into the flash. However, some device families do not offer larg memory versions that could be used for development and, therefore, reducing the footprint of debug code is essential for the application to fit.

Advantages

Host-based formatting shifts the burden of formatting from the target system, where resources are limited, to the host system. The host system supports all formatting specification (such as width, precision, alignment, floating point, and so on) simply becuase it has ample resources to do so. The target footprint for printf, for instance, is no more than a few instructions to issue a semihosting call and have the debug agent perform the semihosting operation.

Implementation details

The following is the implementation of printf using the SEGGER Runtime Library using host-based formatting for semihosting:

int printf(const char *fmt, ...) {
  return __do_debug_operation(DEBOP_PRINTF, &fmt);
}

The debugger or host agent identifies the semihosting request from the target (see the [Semihosting] page for details) and proceeds to service the request. It will first identify the parameters of the semihosting call: the debug operation and the incoming C arguments. With access to all of memory through the debug probe it can find the address of the format string, read the format string from memory under debug control, and format the output "virtually" on the host, taking arguments from the target.

For instance, the call...

printf("There are %u bottles of beer on the %s", 99, "wall");

...would be processed, in detail, as follows:

  • Target calls printf with format string, additional arguments typically passed on processor stack.
  • Target requests a semihosting call.
  • Host recognizes call and proceeds to service it.
  • Host decodes the semihosting operation and identifies it as a printf request.
  • Host reads e.g. register R0 to find the address of the format string.
  • Host reads the format string from target memory into host memory, up to and including the terminating null character.
  • Host starts formatting the string, sending "There are" to the console.
  • Host recognizes %u formatting code and reads an unsigned value from the processor stack under debug control.
  • Host formats the argument, 99, and writes "99" to the console.
  • Host contrinues and copies " bottles of beer on the " to the console.
  • Host recognizes %s formatting code and reads an pointer value from the processor stack under debug control.
  • Host reads string using that pointer as a base and copies "wall" to the console.
  • Host finds end of control string and writes an "OK" result to e.g. register R0.
  • Host restarts program execution on the target.

The semihosting call is now complete.