Semihosting is a mechanism for ARM targets to communicate input/output requests from application code to a host computer running a debugger. This mechanism could 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
- To set debugger options, choose Project>Options. In the Debugger category, click the Setup tab.
- Select Run to main and click OK. This will ensure that the debug session will start by running to the main function.
- The project is now ready to be built.
Step 2: Building the project
- Compile and link the project by choosing Project>Make or F7
- 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
- Choose "Semihosting_IAR" project -> "Options" -> "Debugger" -> "J-LINK/J-TRACE".
- Choose tab "J-LINK/J-TRACE" -> "Connection" tab -> "SWD".
- Start the project by choosing Project>Download and Debug.
- Choose View>Terminal I/O to display the output from the I/O operations.
Guide Semihosting for Keil uVision
NOTE: Keil supports Semihosting only for M3/M4 cores.
Step 1: Prepare code
Remove function fputc and fgetc is used to support KEIL in "fsl_debug_console.c" then add the following code to project:
#pragma import(__use_no_semihosting_swi)
volatile int ITM_RxBuffer = ITM_RXBUFFER_EMPTY;
struct __FILE
{
int handle;
};
FILE __stdout;
FILE __stdin;
int fputc(int ch, FILE *f)
{
return (ITM_SendChar(ch));
}
int fgetc(FILE *f)
{
while (ITM_CheckChar() != 1)
;
return (ITM_ReceiveChar());
}
int ferror(FILE *f)
{
return EOF;
}
void _ttywrch(int ch)
{
ITM_SendChar(ch);
}
void _sys_exit(int return_code)
{
label:
goto label;
}
Step 2: Setting up the environment
- In menu bar, choose Project>Options for target or using Alt+F7 or click
- Next, select "Target" tab and not select "Use MicroLIB".
- Next, select “Debug” tab, select “J-LINK/J-TRACE Cortex” and click “Setting button”.
- Next, select “Debug” tab and choose Port:SW, then select "Trace" tab, choose "Enable" and click OK
Step 3: Building the project
- Compile and link the project by choosing Project>Build Target or using F7
Step 4: Building the project
- Choose “Debug” on menu bar or Ctrl F5
- In menu bar, choose "Serial Window" and click to "Debug (printf) Viewer"
- Run line by line to see result in Console Window.
Guide Semihosting for KDS
NOTE: After the setting we can use "printf" for debugging
Step 1: Setting up the environment
- In menu bar, choose Project>Properties>C/C++ Build>Settings>Tool Settings.
- Select “Libraries” on “Cross ARM C Linker” and delete “nosys”.
- 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
- In menu bar, choose Project>Build Project.
Step 3: Starting semihosting
- In Debug configurations, choose "Startup" tab, tick “Enable semihosting and Telnet”. Press “Apply” and “Debug”.
- After click Debug, the Window same as below, run line by line to see result in Console Window.
Guide Semihosting for ATL
NOTE: Hardware jlink have to be used to enable semihosting
Step 1: Prepare code
Add the following code to project:
int _write(int file, char *ptr, int len)
{
int i=0;
for(i=0 ; i<len ; i++)
ITM_SendChar((*ptr++));
return len;
}
Step 2: Setting up the environment
- In menu bar, choose Debug Configurations. In tab "Embedded C/C++ Aplication" choose "Semihosting_ATL_xxx debug jlink".
- In tab "Debugger" setup like that:
- JTAG mode must be selected
- SWV tracing must be enabled
- Enter the Core Clock frequency. This is H/W 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.
- Click "Apply" and "Debug".
Step 3: Starting semihosting
- In the Views menu, expand the submenu SWV and open the docking view “SWV Console".
- Open the SWV settings panel by clicking on the Configure Serial Wire Viewer button in the SWV Console view toolbar.
- 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".
- Recommend not enabling other SWV trace functionalities at the same time, as this may over-use the SWO pin causing packet loss due to 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 together with other debug configurations and will remain effective until changed.
- Press the red Start/Stop Trace button to send the SWV configuration to the target board and enable SWV trace recoding. The board will not send any SWV packages until it is properly configured. The SWV Configuration must be resent, if the configuration registers on the target board are reset. Also, actual tracing will not start until the target starts to execute
- Start the target execution again by pressing the green Resume Debug button.
- The SWV console will now show the printf() output
Guide Semihosting for ARMGCC
Step 1: Setting up the environment
- Turn on "J-LINK GDB Server" -> Select suitable "Target device" -> "OK".
- Turn on "PuTTY". Setup like this :
- "Host Name (or IP address)" : localhost
- "Port" :2333
- "Connection type" : Telet.
- Click "Open".
- 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
-
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)
-
Run "build_debug.bat" to build project
Step 3: Starting semihosting
- Download the image and set like this:
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
- After the setting, press "enter", the PuTTY window will now show the printf() output.