MCUXpresso SDK API Reference Manual  Rev. 0
NXP Semiconductors
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
Semihosting

Semihosting is a mechanism for ARM targets to communicate input/output requests from application code to a host computer running a debugger. This mechanism can be used, for example, to enable functions in the C library, such as printf() and scanf(), to use the screen and keyboard of the host rather than having a screen and keyboard on the target system.

Guide Semihosting for IAR

NOTE: After the setting both "printf" and "scanf" are available for debugging.

Step 1: Setting up the environment

  1. To set debugger options, choose Project>Options. In the Debugger category, click the Setup tab.
  2. Select Run to main and click OK. This ensures that the debug session starts by running the main function.
  3. The project is now ready to be built.

Step 2: Building the project

  1. Compile and link the project by choosing Project>Make or F7.
  2. Alternatively, click the Make button on the tool bar. The Make command compiles and links those files that have been modified.

Step 3: Starting semihosting

  1. Choose "Semihosting_IAR" project -> "Options" -> "Debugger" -> "J-Link/J-Trace".
  2. Choose tab "J-Link/J-Trace" -> "Connection" tab -> "SWD".
  3. Start the project by choosing Project>Download and Debug.
  4. Choose View>Terminal I/O to display the output from the I/O operations.

Guide Semihosting for Keil µVision

NOTE: Keil supports Semihosting only for Cortex-M3/Cortex-M4 cores.

Step 1: Prepare code

Remove function fputc and fgetc is used to support KEIL in "fsl_debug_console.c" and add the following code to project.

#pragma import(__use_no_semihosting_swi)
volatile int ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* used for Debug Input */
struct __FILE
{
int handle;
};
FILE __stdout;
FILE __stdin;
int fputc(int ch, FILE *f)
{
return (ITM_SendChar(ch));
}
int fgetc(FILE *f)
{ /* blocking */
while (ITM_CheckChar() != 1)
;
return (ITM_ReceiveChar());
}
int ferror(FILE *f)
{
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch)
{
ITM_SendChar(ch);
}
void _sys_exit(int return_code)
{
label:
goto label; /* endless loop */
}

Step 2: Setting up the environment

  1. In menu bar, choose Project>Options for target or using Alt+F7 or click.
  2. Select "Target" tab and not select "Use MicroLIB".
  3. Select “Debug” tab, select “J-Link/J-Trace Cortex” and click “Setting button”.
  4. Select “Debug” tab and choose Port:SW, then select "Trace" tab, choose "Enable" and click OK.

Step 3: Building the project

  1. Compile and link the project by choosing Project>Build Target or using F7.

Step 4: Building the project

  1. Choose “Debug” on menu bar or Ctrl F5.
  2. In menu bar, choose "Serial Window" and click to "Debug (printf) Viewer".
  3. Run line by line to see result in Console Window.

Guide Semihosting for KDS

NOTE: After the setting use "printf" for debugging.

Step 1: Setting up the environment

  1. In menu bar, choose Project>Properties>C/C++ Build>Settings>Tool Settings.
  2. Select “Libraries” on “Cross ARM C Linker” and delete “nosys”.
  3. Select “Miscellaneous” on "Cross ARM C Linker”, add “-specs=rdimon.specs” to “Other link flages” and tick “Use newlib-nano”, and click OK.

Step 2: Building the project

  1. In menu bar, choose Project>Build Project.

Step 3: Starting semihosting

  1. In Debug configurations, choose "Startup" tab, tick “Enable semihosting and Telnet”. Press “Apply” and “Debug”.
  2. After clicking Debug, the Window is displayed same as below. Run line by line to see the result in the Console Window.

Guide Semihosting for ATL

NOTE: J-Link has to be used to enable semihosting.

Step 1: Prepare code

Add the following code to the project.

int _write(int file, char *ptr, int len)
{
/* Implement your write code here. This is used by puts and printf. */
int i=0;
for(i=0 ; i<len ; i++)
ITM_SendChar((*ptr++));
return len;
}

Step 2: Setting up the environment

  1. In menu bar, choose Debug Configurations. In tab "Embedded C/C++ Aplication" choose "Semihosting_ATL_xxx debug J-Link".
  2. In tab "Debugger" set up as follows.
    • JTAG mode must be selected
    • SWV tracing must be enabled
    • Enter the Core Clock frequency, which is hardware board-specific.
    • Enter the desired SWO Clock frequency. The latter depends on the JTAG Probe and must be a multiple of the Core Clock value.
  3. Click "Apply" and "Debug".

Step 3: Starting semihosting

  1. In the Views menu, expand the submenu SWV and open the docking view “SWV Console". 2. Open the SWV settings panel by clicking the "Configure Serial Wire Viewer" button in the SWV Console view toolbar. 3. Configure the data ports to be traced by enabling the ITM channel 0 check-box in the ITM stimulus ports group: Choose "EXETRC: Trace Exceptions" and In tab "ITM Stimulus Ports" choose "Enable Port" 0. Then click "OK".
  2. It is recommended not to enable other SWV trace functionalities at the same time because this may over use the SWO pin causing packet loss due to a limited bandwidth (certain other SWV tracing capabilities can send a lot of data at very high-speed). Save the SWV configuration by clicking the OK button. The configuration is saved with other debug configurations and remains effective until changed.
  3. Press the red Start/Stop Trace button to send the SWV configuration to the target board to enable SWV trace recoding. The board does not send any SWV packages until it is properly configured. The SWV Configuration must be present, if the configuration registers on the target board are reset. Also, tracing does not start until the target starts to execute.
  4. Start the target execution again by pressing the green Resume Debug button.
  5. The SWV console now shows the printf() output.

Guide Semihosting for ARMGCC

Step 1: Setting up the environment

  1. Turn on "J-LINK GDB Server" -> Select suitable "Target device" -> "OK".
  2. Turn on "PuTTY". Set up as follows.
    • "Host Name (or IP address)" : localhost
    • "Port" :2333
    • "Connection type" : Telet.
    • Click "Open".
  3. Increase "Heap/Stack" for GCC to 0x2000:

Add to "CMakeLists.txt"

SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} --defsym=__stack_size__=0x2000")

SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} --defsym=__stack_size__=0x2000")

SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} --defsym=__heap_size__=0x2000")

SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} --defsym=__heap_size__=0x2000")

Step 2: Building the project

  1. Change "CMakeLists.txt":

    Change "SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} –specs=nano.specs")"

    to "SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} –specs=rdimon.specs")"

    Replace paragraph

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fno-common")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -ffunction-sections")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fdata-sections")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -ffreestanding")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fno-builtin")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -mthumb")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -mapcs")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -Xlinker")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} --gc-sections")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -Xlinker")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -static")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -Xlinker")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -z")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -Xlinker")

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} muldefs")

    To

    SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} --specs=rdimon.specs ")

    Remove

    target_link_libraries(semihosting_ARMGCC.elf debug nosys)

  2. Run "build_debug.bat" to build project

    Step 3: Starting semihosting

    1. Download the image and set as follows.
      cd D:\mcu-sdk-2.0-origin\boards\twrk64f120m\driver_examples\semihosting\armgcc\debug
      d:
      C:\PROGRA~2\GNUTOO~1\4BD65~1.920\bin\arm-none-eabi-gdb.exe
      target remote localhost:2331
      monitor reset
      monitor semihosting enable
      monitor semihosting thumbSWI 0xAB
      monitor semihosting IOClient 1
      monitor flash device = MK64FN1M0xxx12
      load semihosting_ARMGCC.elf
      monitor reg pc = (0x00000004)
      monitor reg sp = (0x00000000)
      continue
    2. After the setting, press "enter". The PuTTY window now shows the printf() output.