ST-link printf to console with GDB and semihosting or ITM and ST Link Utility
This post will attempt to compile information that is found in various posts into single place.
Semihosting is using printf to the GDB console ie it will show up in system workbench / eclipse console while debugging when configured properly. This will only work in debug mode. At this point openOCD doesn't support displaying SWO trace data.
ITM uses printf and the CMSIS ITM _SendChar() function to output a message through the SWO line. The ST Link Utility is used to veiw these printf statements. ITM is considerably faster than semihosting.
This post assumes that you are familiar with how to use the ST cube and can import projects into system workbench / eclipse. The projects were completed using system workbench version 1.8, cube version 4.15, and the STM32F401C-DISCO board. The relevant part of the cube configuration is in the SYS peripheral.
Output to debug console using GDB
In the SYS peripheral debug should be set to Serial Wire. Trace Asynchronous SW works, but it reserves PB3 for SWO. If you chose the STM32F401C-DISCO board in the cube setup it will have the pin labeled SWO on PB3 regardless of the choice made in SYS peripheral. For GDB console output generate the cube project and import into eclipse.
- The linker needs to know to include librdimon: Project -> Properties -> C/C++ Build -> Settings -> MCU GCC Linker -> Linker flags set to -specs=nosys.specs -specs=nano.specs -specs=rdimon.specs -lc -lrdimon
- Project -> Properties -> Run/Debug Settings -> edit correct debug setting -> startup -> add monitor arm semihosting enable to initialization commands
- Add extern void initialise_monitor_handles(void); above main. I chose user code 0 section. You do not have to include stdio.h or stdlib.h when using a cube generated project and semihosting
- Add initialise_monitor_handles(); to the main loop before the while(1)
- Use printf as you would normally remembering that without the \n character it will not output to the console when debugging
Output to ST Link Utility using ITM
Make the project in the same way as for GDB console output. Serial wire or asynchronous SW can be chosen. If serial wire is selected than PB3 must be left unused. If PB3 is set to other GPIO functionality the ITM messages will not work.
ITM setup is very easy. Add the below code to your main.c. I chose user code 0 again.
int _write(int file, char *ptr, int len) { int DataIdx; for (DataIdx = 0; DataIdx < len; DataIdx++) { ITM_SendChar( *ptr++ ); } return len; }
From there printf using ITM can be used with ST Link Utility with no additional changes.
Of course the _write function can also used with a uart for printf functionality. I did not include that as it seems to be very well covered elsewhere. Hope this helps someone.