Library 46- Debug STM32F4 device with SWO feature
All Cortex-M4 devices have feature to output different data for debugging. This can be used instead of one USART available in STM32F4 to display data to user when something is going wrong and you want use debug.
STM32F4 has SWD (Serial Wire Debug) option for programming/debugging. All STM32 boards, which have ST-Link on board, uses this option. For programming, only clock and data lines are required. Full SWD also enables you to output something from MCU which debugging. This is called SWV (Serial Wire Viewer) using SWO (Serial Wire Output) output.
ST-Link on STM32 boards has this input, if SWO from MCU is connected to ST-Link by default, check schematics. Some boards (like F429-Discovery) needs solder bridge if you want to enable connection.
If you are using external programmer/debugger (Keil ULINK2, Keil ULINK Pro, Segger J-Link, etc), then you should check if they have SWO option, but every serious debugger should have this!
This feature is enabled only when MCU is in debug mode. In production (non debug) mode, SWV will not work.
To get this to work, you have to make sure for some things. First is that you need to specify real CPU clock so trace will be synchronous (like baudrate in USART).
In Keil uVision this can be simple set:
- Open “Options for Target” -> “Debug” tab
- Select your debugger, if you are working with STM32F4-Discovery, select ST-Link
- Make sure you have updated version
- Use STM32 ST-Link Utility to update to newest version
- Click on “Settings”, new window will open
- In “Trace” tab make sure you have settings the same as on picture below
- Set CPU clock to match your clock
- Go to application, compile it and press “Start/Stop Debug Session” (Red button)
- Make sure, you have enabled option “Debug information” under “Options for Target” -> “Output”
- To start program in real time, press F5. Program will be in real time speed and you will watch your data on SWO pin in Keil uVision
If you don’t have Keil uVision, you can still use SWO feature. In ST-Link Utility, open “ST-LINK” -> “Printf via SWO Viewer”, set your frequency and hit “Start”. MCU will be reset, in debug mode and SWO will work if it is enabled.
This can be also used if your IDE does not feature debugging mode!
I’ve tested this feature on some boards:
- STM32F429-Discovery: worked without any problem, SB9 solder bridge required before to be soldered
- STM32F4-Discovery: worked without any problem
- STM32-Nucleo:
- F401: didn’t worked, I always got error that memory cannot be read, but physical connection is there by default
- F411: didn’t worked, I always got error that memory cannot be read, but physical connection is there by default
Library
Features
- Enables SWO functionality on STM32F4
- Printf like output style
- Can be completely disabled when not using debug mode
Dependencies
- CMSIS
- STM32F4xx
- TM
- TM STDIO
- defines.h
- attributes.hattributes.h 0.85 KB
- TM STDIO
- stdio.h
STM32F4 programming/debugging pins
SWD | STM32F4 | Description |
---|---|---|
SWCLK | PA14 | Clock for programming, necessary if you want to program/debug MCU |
SWDIO | PA13 | Data input and output, necessary if you want to program/debug MCU |
SWO | PB3 | Data pin from MCU for trace view (Serial Wire Viewer), optional and recommended |
On initialize, SWO peripheral is enabled on pin PB3. When you are in debug mode and want to display some data, you can do with print function in my library. But then, you want to completely disable this debugging mode. One option will be to everywhere in your project delete lines when you display something to SWO.
Second option, is to set one define I’ve made in library. If you enable this define and set debug to 0, then all functions becomes defines with empty content and compiler will just throw them out. They will be in your code, but will not affect to size/speed of your code.
If you want disable debug mode (when in completely production mode), you can do it with define in defines.h file:
1 2 |
//Disable debug mode, convert all functions into empty define statements #define SWO_DEBUG_ENABLED 0 |
You can also leave debug active, it still won’t work if you are not in debug mode, but functions will be there, compiled and will take some time when it will try to print something.
If you don’t need debug mode (project done and in production) then you should use define above, or delete all function calls for SWO you have in your project.
Functions and enumerations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
/** * Initialize SWO debug output * * Function prepares SWO on MCU for output data to debugger * * If debugging mode is enabled, then this is a function. * if not, then function becomes simple define statement without content */ #if SWO_DEBUG_ENABLED == 1 /* Debugging enabled, initialize functionality */ extern void TM_SWO_Init(void); #else /* Do nothing here, compiler will throw out this statement because it is empty */ #define TM_SWO_Init() #endif /** * Format and output data to the SWO output * This function acts similar to printf except that custom stream is used * * Parameters: * - args...: * Parameters are like printf. First parameter is string, * then you can use unlimited parameters according to string to be formatted * * No return * Defined as macro * * If debugging mode is enabled, then this is a function. * if not, then function becomes simple define statement without content */ #if SWO_DEBUG_ENABLED == 1 /* Format and output data to the SWO output with stream */ #define TM_SWO_Printf(args...) { fprintf(&TM_SWO_File, ## args); } #else /* Do nothing here, compiler will throw out this statement because it is empty */ #define TM_SWO_Printf(args...) #endif |
Example
- Every 500ms, new time is displayed to SWO output in your debug console.
- If you have any problems and you are not sure if this is working or not, then you ST-Link Utility and it’s Printf via SWO feature to see if communication is even working
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
/** * Keil project example for SWO debug feature * * Before you start, select your target, on the right of the "Load" button * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 * @packs STM32F4xx Keil packs version 2.2.0 or greater required * @stdperiph STM32F4xx Standard peripheral drivers version 1.4.0 or greater required */ /* Include core modules */ #include "stm32f4xx.h" /* Include my libraries here */ #include "defines.h" #include "tm_stm32f4_delay.h" #include "tm_stm32f4_disco.h" #include "tm_stm32f4_swo.h" int main(void) { SystemInit(); /* Initialize SWO output */ TM_SWO_Init(); /* Leds init */ TM_DISCO_LedInit(); /* Delay init */ TM_DELAY_Init(); /* Print via SWO, debug purpose */ TM_SWO_Printf("Hello from MCU via SWO\n"); while (1) { /* Toggle LEDs */ TM_DISCO_LedToggle(LED_ALL); /* Print via SWO */ TM_SWO_Printf("%d\n", TM_DELAY_Time()); /* Delay some time */ Delayms(500); } } |
Project is available on Github, download library below.
Recent comments