on
2021-01-13
08:20 AM
- edited on
2024-06-18
01:36 AM
by
Laurids_PETERSE
Semihosting can be used to enable code running on STM32 to communicate with the host computer during a debug session. This makes it possible to use host computer I/O (for example keyboard, display, or file system) instead of having such input/output resources on the embedded system during development.
To use semihosting with STM32CubeIDE some updates are needed to be done in the project. A debugger supporting semihosting is also required. This article guides on how to enable semihosting when using OpenOCD, ST-LINK and STM32 devices.
Note1: ST-LINK GDB server does not support semihosting!
Note2: Please consult SEGGER documentation if semihosting with SEGGER J-LINK is preferred.
Remove default <syscalls.c> file from build if this file is included in STM32CubeIDE project.
Add the following two lines in beginning of main.c to include <stdio.h> and to use initialise_monitor_handles() prototype.
#include <stdio.h>
extern void initialise_monitor_handles(void);
Add a call to initialise_monitor_handles() function in the beginning of main() function and some variables to be used for semihosting.
int main(void)
{
/* USER CODE BEGIN 1 */
initialise_monitor_handles();
char s[50];
char *p;
FILE *fp;
p=s;
Add some semihosting commands into main() function. Example: Using scanf, printf, fopen, fclose, and fprintf.
/* Infinite loop */
/* USER CODE BEGIN WHILE */
printf("Hello, World!\n");
fp=fopen("c:\\dev\\mytest.txt", "w");
while (1)
{
printf("Enter string:\n");
scanf("%s", p);
printf("\nReceived string: ");
printf(p);
printf("\n");
fprintf(fp,p);
fprintf(fp,"\n");
fclose(fp);
HAL_Delay(500);
fp=fopen("c:\\dev\\mytest.txt", "a");
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
In Libraries add “rdimon” library.
In Miscellaneous add Other flags “-specs=rdimon.specs”
The project is now updated to use semihosting. Build the project.
Create a new debug configuration for the project or update an existing one. Make sure that OpenOCD is used.
Note: ST-LINK GDB server does not support semihosting.
Add “monitor arm semihosting enable” initialization command in Debug Configurations - Startup tab.
The Debug Console view is used for semihosting input/output and when debugging it will ask to enter strings…
Example: Entering “TEST” and “123456”
Open On-Chip Debugger 0.10.0+dev-01288-g7491fb4 (2020-10-27-17:36) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections Info : STLINK V2J37M26 (API v2) VID:PID 0483:374B Info : Target voltage: 3.244649 .. .. semihosting is enabled target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x08000860 msp: 0x20018000, semihosting configuring PLL Info : Unable to match requested speed 8000 kHz, using 4000 kHz Info : Unable to match requested speed 8000 kHz, using 4000 kHz Info : Padding image section 0 at 0x08000194 with 12 bytes target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x08000a04 msp: 0x20018000, semihosting Hello, World! Enter string: TEST Received string: TEST Enter string: 123456 Received string: 123456 Enter string:
Stop the debug session to analyze the log file.
The program opens and writes to the file c:\dev\mytest.txt. Open the <mytest.txt> file and information from the debug session can be seen.
why so easy? All it took was half a day...
Hi,
I use STM32CubeIDE Version: 1.12.1. I can't build my project:
>>>
09:36:11 **** Incremental Build of configuration Debug for project CPU_Rotomat_MP0N ****
make -j12 all
arm-none-eabi-g++ "../Src/main.cpp" -mcpu=cortex-m7 -std=gnu++14 -g3 -DUSE_HAL_DRIVER -DMP0N -DSTM32F767xx -DUSE_FULL_LL_DRIVER -DDEBUG -c -I../Inc -I../Drivers/CMSIS/Include -I../Drivers/CMSIS/Device/ST/STM32F7xx/Include -I../Drivers/STM32F7xx_HAL_Driver/Inc -I../Drivers/STM32F7xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/LwIP/src/include -I../Middlewares/Third_Party/LwIP/system -I../Drivers/BSP/Components/lan8742 -I../Middlewares/Third_Party/LwIP/src/include/netif/ppp -I../Middlewares/Third_Party/LwIP/src/include/lwip -I../Middlewares/Third_Party/LwIP/src/include/lwip/apps -I../Middlewares/Third_Party/LwIP/src/include/lwip/priv -I../Middlewares/Third_Party/LwIP/src/include/lwip/prot -I../Middlewares/Third_Party/LwIP/src/include/netif -I../Middlewares/Third_Party/LwIP/src/include/compat/posix -I../Middlewares/Third_Party/LwIP/src/include/compat/posix/arpa -I../Middlewares/Third_Party/LwIP/src/include/compat/posix/net -I../Middlewares/Third_Party/LwIP/src/include/compat/posix/sys -I../Middlewares/Third_Party/LwIP/src/include/compat/stdc -I../Middlewares/Third_Party/LwIP/system/arch -Og -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wall -fstack-usage -fcyclomatic-complexity -MMD -MP -MF"Src/main.d" -MT"Src/main.o" --specs=nano.specs -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -o "Src/main.o"
arm-none-eabi-g++ -o "CPU_Rotomat_MP0N.elf" @"objects.list" -lrdimon -mcpu=cortex-m7 -T"D:\workspace_STM32CubeIDE_1.10_Test\CPU_Rotomat_MP0N\STM32F767BITx_FLASH.ld" --specs=nosys.specs -Wl,-Map="CPU_Rotomat_MP0N.map" -Wl,--gc-sections -static -specs=rdimon.specs --specs=nano.specs -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -lstdc++ -lsupc++ -Wl,--end-group
c:\st\stm32cubeide_1.10.0\stm32cubeide\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.win32_1.0.200.202301161003\tools\arm-none-eabi\bin\ld.exe: ./Src/main.o: in function `main':
D:/workspace_STM32CubeIDE_1.10_Test/CPU_Rotomat_MP0N/Debug/../Src/main.cpp:290: undefined reference to `initialise_monitor_handles()'
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:87: CPU_Rotomat_MP0N.elf] Error 1
"make -j12 all" terminated with exit code 2. Build might be incomplete.
09:36:13 Build Failed. 3 errors, 0 warnings. (took 2s.580ms)
<<<
What's going wrong?
Hi,
I've checked with a c-project, everything is working fine. But with my c++-project it isn't linking.
I think the problem is calling a c-function from a cpp-file, but where can I place
#ifdef __cplusplus
extern "C" {
#endif ?
Has anybody an idea?
I have the same question / problem as @juergen.mader
Ok, it’s simple : just put it around the forward declaration
#ifdef __cplusplus
extern "C"
{
#endif
void initialise_monitor_handles(void);
#ifdef __cplusplus
}
#endif /* extern "C" */