SEGGER Semihosting
SEGGER Semihosting is a standard for Semihosting, defined by SEGGER and compatible to an older standard defined by ARM.
Contents
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, the 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);