Acronyms

  • Serial Wire Debug (SWD): a debugging protocol devised by ARM for use in Cortex-M family, which replaced the old JTAG debugging interface customarily used for ARM7/9 architectures.
  • Serial Wire Output (SWO): a pin/line which extends from the microcontroller’s processor (ITM unit, to be exact) to the debugger circuitry on the board.
  • Serial Wire Viewer (SWV): a “data trace feature” on the MCU processor which requires only the one SWO pin to send data to the debugger

Note that the following is only applicable to MCUs with ARM Cortex M3/M4/M7+ processors. We can use printf by using Serial Wire Output, or SWO line to interface with SWD.

Our discovery board contains a microcontroller - the STM32F407G MCU, which in turns contains an ARM Cortex M4 processor. The board also includes an on-board debugger circuitry, called the ST-Link. Through the debug circuitry, the PC communicates with the board: it is used to program the internal flash memory (sometimes just called flashing) of the microcontroller, read memory addresses of the microcontroller, make processor run and stop, etc. We use ST-Link with PC through a USB connection. A pin called the SWO pin runs from the processor to the debugger. printf works through SWO pin.

Inside the processor, we can find the Instrumentation Trace Macrocell Unit (ITM unit). This feature is only available in Cortex M3+ processors.

The ITM is an optional application-driven trace source that supports printf style debugging to trace OS and application events, and can generate diagnostic system information.

The ITM unit contains a data buffer/register that is FIFO. The FIFO happens to be connected to the SWO pin - remember how SWO connects to the debugger? When we write our message into FIFO, it can be captured using our debugger and consequently be transmitted to our computer. Not all IDEs support capturing SWO transmission but fortunately, STMCubeIDE and TrueStudio can.

To do debug-related activities, e.g. issuing instructions to the CPU, we communicate through a debug interface. The debug interface we’ll use here is SWD.

SWD is a two-wire protocol for accessing ARM debug interface. It works over an SWD connector, which has 2 debug pins and 1 optional trace pin (getting errortracing from processor). It is part of the ARM Debug Interface Specification and can be used as an alternative to JTAG.

SWD consists of SWDIO, a bidirectional data line (debug related data), and SWCLK, a clock driven by the host (ST-LINK debugger). E.g. a breakpoint in your code will be sent from the PC to the microcontroller CPU via SWDIO line. Both lines are managed by ST-LINK debugger.

Another debug interface: JTAG JTAG was the traditional debugging interface for ARM7/9, but with the invention of the Cortex-M family in 2003, ARM introduced SWD. The primary advantage of SWD over JTAG was that it needed a minimum of 2 pins instead of 4. SWD also provides an extra pin called Serial Wire Output (SWO), used for Serial Wire Viewer (SWV) which is low cost tracing.

Why do we need to implement our own write function? When we use prinf(), we make a call to the standard library, which defines prinf() that contains a lower level call to _write(). However the std library’s _write() is actually implemented in our very own syscalls.c. Data is received in a data pointer. Because it is weakly defined, we could even direct _write() to send characters via UART if we so desired.

To use this useful debugging feature, go to Window > Show View > SWV > SWM ITM Data Console. Click on Configure Trace, then enable port 0, as our _write() function will write into this port.