ARM Cortex M Semihosting - nhivp/vnos GitHub Wiki

What is semihosting?

Semihosting is a mechanism that enables code running on an ARM target to communicate and use the Input/Output facilities on a host computer that is running a debugger.

  • Provide a interface for debugging with host
  • Can be used to debug in exception handler
  • Can use this mechanism to enable functions in C library, such as printf() and scanf(), to use a screen and keyboard on host instead of having a screen and keyboard on the target system.

Semihosting operations

The semihosting operations are requested by using the SVC number.

  • Semihosting operations are requested using a single SVC number, leaving the other numbers available for use by the application or operating system. The SVC number used for semihosting depends on the target architecture or processor:

    • SVC 0x123456: In ARM state for all architectures.
    • SVC 0xAB: In ARM state and Thumb state, excluding ARMv6-M and ARMv7-M. This behavior is not guaranteed on all debug targets from ARM or from third parties.
    • BKPT 0xAB: For ARMv6-M and ARMv7-M, Thumb state only.
  • The available semihosting operation numbers passed in R0 are allocated as follows:

    • angel_SWIreason_EnterSVC (0x17)
    • angel_SWIreason_ReportException (0x18)
    • SYS_CLOSE (0x02)
    • SYS_CLOCK (0x10)
    • SYS_ELAPSED (0x30)
    • SYS_ERRNO (0x13)
    • SYS_FLEN (0x0C)
    • SYS_GET_CMDLINE (0x15)
    • SYS_HEAPINFO (0x16)
    • SYS_ISERROR (0x08)
    • SYS_ISTTY (0x09)
    • SYS_OPEN (0x01)
    • SYS_READ (0x06)
    • SYS_READC (0x07)
    • SYS_REMOVE (0x0E)
    • SYS_SEEK (0x0A)
    • SYS_SYSTEM (0x12)
    • SYS_TICKFREQ (0x31)
    • SYS_TIME (0x11)
    • SYS_TMPNAM (0x0D)
    • SYS_WRITE (0x05)
    • SYS_WRITEC (0x03)
    • SYS_WRITE0 (0x04)

Sample code

void main() 
{
    int SYS_WRITEC = 0x03;
    int SYS_WRITE0 = 0x04;
    register int reg0 asm("r0");
    register int reg1 asm("r1");
    char outchar = '_';

    // A 'NOP' so we can 'see' the start of the folllowing svc call
    asm volatile("mov r0,r0");

    outchar = '!';
    reg0 = SYS_WRITEC;
    reg1 = (int)&outchar;
    asm("svc 0x00123456");

    // A 'NOP' so we can 'see' the start of the folllowing svc call
    asm volatile("mov r0,r0");
    reg0 = SYS_WRITEC;
    outchar = '\n';
    reg1 = (int)&outchar;
    asm("svc 0x00123456");

    // A 'NOP' so we can 'see' the start of the folllowing svc call
    asm volatile("mov r0, r0");

    reg0 = SYS_WRITE0;
    reg1 = (int)&"Print this to my jtag debugger\n";
    asm("svc 0x00123456");
}

Remarks

  • Instruction
    • Corext-M1 or Cortex-M3: bkpt
    • Cortex-M4: svc

Reference