SEGGER Semihosting

From SEGGER Wiki
Revision as of 11:14, 5 September 2019 by Johannes (talk | contribs) (Interface)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search


SEGGER Semihosting is a standard for Semihosting, defined by SEGGER and compatible to an older standard defined by ARM.

File structure of reference implementation

The reference implementation is provided as a ZIP file, containing a complete project for SEGGER Embedded Studio. The relevant sources are 3 files which are completely generic, so can be compiled on any system using any C- compiler:

  • SEGGER_SEMIHOST.h - Interface definition
  • SEGGER_SEMIHOST.c - Implementation of the Semihosting interface functions
  • SEGGER_SEMIHOST_Generic.c - Implementation of the SEGGER_SEMIHOST_X_Request routine to call SEGGER_SEMIHOST_DebugHalt

The reference project is available for download here: sources

Implementation

All public functions can be called by the application. They usually package the parameters, then call SEGGER_SEMIHOST_X_Request(), which either implements some kind of a breakpoint / halt / Supervisor call instruction (if available for the target) or simply call SEGGER_SEMIHOST_DebugHalt(), which is a function that the debugger automatically sets a break point on. So a typical call stack for a simple hello world application would be as follows:

main()
  SEGGER_SEMIHOST_Writef()
    SEGGER_SEMIHOST_X_Request()
      SEGGER_SEMIHOST_DebugHalt()

The implementation of the functions is quite simple, which means the code overhead of Semihosting is very small:

SEGGER_SEMIHOST_Writef

/*********************************************************************
*
*       SEGGER_SEMIHOST_Writef()
*
*  Function description
*    Write a formatted string to debug channel on the host system.
*    The string is formatted on the host.
*
*  Parameters
*    pFormat:   Pointer to string to be formatted and printed.
*    aArg:      Arguments
*
*  Return value
*     = -1: Error.
*    >=  0: OK. Number of bytes printed.
*
*  Additional information
*    int myprintf(const char* s, ...) {
*      va_list List;
*    
*      va_start(List, s);
*      SEGGER_SEMIHOST_Writef(s, &List);
*      va_end(List);
*    
*      return 0;
*    }
*    
*/
int SEGGER_SEMIHOST_Writef(const char* pFormat, va_list* pArg) {
  SEGGER_SEMIHOST_PARA  aPara[2];
  int                   r;

  aPara[0].cpC = pFormat;
  aPara[1].pV  = (void*)pArg;
  r = SEGGER_SEMIHOST_X_Request(SYS_WRITEF, aPara);

  return r;
}

SEGGER_SEMIHOST_X_Request()

/*********************************************************************
*
*       SEGGER_SEMIHOST_X_Request()
*
*  Function description
*    Notify the debugger host about the semihosting request
*
*  Parameters
*    Op:         Operation.
*    pPara:      Pointer to parameter block.
*
*  Return value
*    Operation-specific return value, set by the debugger in R0.
*/
int SEGGER_SEMIHOST_X_Request(int Op, SEGGER_SEMIHOST_PARA* pPara) {
  int r0;

  r0 = SEGGER_SEMIHOST_DebugHalt((int)Op, (int)pPara);

  return r0;
}

SEGGER_SEMIHOST_DebugHalt()

/*********************************************************************
*
*       SEGGER_SEMIHOST_DebugHalt()
*
*  Function description
*    Dummy call for generic implementation.
*    The debugger may set a breakpoint on this function, 
*    handle the semihosting request,
*    and return to the caller.
*
*  Return value
*    Return parameter r0 if debugger is not connected.
*/
int __attribute__((noinline)) SEGGER_SEMIHOST_DebugHalt(int r0, int r1) {
  (void)r1;   // Avoid unused parameter warning
  return r0;
}

Interface

The below is an exert from SEGGER_SEMIHOST.h, containg the API of the the SEGGER implementation.

int SEGGER_SEMIHOST_Open        (const char* sFilename, int Mode, int LenFilename);
int SEGGER_SEMIHOST_Close       (int hFile);
int SEGGER_SEMIHOST_WriteC      (char c);
int SEGGER_SEMIHOST_Write0      (const char* s);
int SEGGER_SEMIHOST_Write       (int hFile, const char* pBuffer, int NumBytesToWrite);
int SEGGER_SEMIHOST_Writef      (const char* pFormat, va_list* pArg);
int SEGGER_SEMIHOST_Read        (int hFile, char* pBuffer, int NumBytesToRead);
int SEGGER_SEMIHOST_ReadC       (void);
int SEGGER_SEMIHOST_IsTTY       (int hFile);
int SEGGER_SEMIHOST_Seek        (int hFile, int Pos);
int SEGGER_SEMIHOST_FLen        (int hFile);
int SEGGER_SEMIHOST_TmpName     (char* pBuffer, int hFile, int pNumBytesName);
int SEGGER_SEMIHOST_Remove      (const char* pPath, int NumBytesPath);
int SEGGER_SEMIHOST_Rename      (const char* pFileName, int NumBytesFileName, const char* pNewName, int NumBytesNewName);
int SEGGER_SEMIHOST_Clock       (void);
int SEGGER_SEMIHOST_Time        (void);
int SEGGER_SEMIHOST_System      (const char* pCommand, int NumBytesCommand);
int SEGGER_SEMIHOST_Errno       (void);
int SEGGER_SEMIHOST_GetCmdLine  (char* pBuffer, char** psCmdLine, int* pNumBytesCmdLine);
int SEGGER_SEMIHOST_Elapsed     (unsigned long long* pTicks);
int SEGGER_SEMIHOST_HeapInfo    (char* pDataBlock);
int SEGGER_SEMIHOST_TickFreq    (void);
int SEGGER_SEMIHOST_Exit        (int ExitCode);
int SEGGER_SEMIHOST_IsConnected (void);
int SEGGER_SEMIHOST_X_Request   (int Op, SEGGER_SEMIHOST_PARA* pPara);