While developing embedded software, you will introduce hard-to-find bugs sooner or later. We all think we won't, but most of us are wrong - we all do it. This is when you need a few tricks up your sleeves. You need professional debug capabilities, like SWV.
Serial Wire Viewer (SWV) real-time event- and data tracing are among the most valuable debugging techniques a Cortex-M developer can use. So useful, in fact, that I have written many blog posts on how to use SWV for debugging. To make it easier to find those blog posts, I took the time to list them all here, along with some annotations.
Cortex-M debugging: Introduction to Serial Wire Viewer (SWV) event- and data tracing
This blog post provides an introduction to the different technologies that are used with Serial Wire Viewer - in particular SWV, SWD, SWO, and ITM. Read this blog post to get an overview of what SWV and its associated technologies are, and how the different parts work together. Furthermore, this blog post explains what features and benefits there are with SWV, and what limitations this debug technology have.
For an overview and introduction to SWV, you can read this blog post:
Cortex-M debugging: printf() redirection to a debugger console using SWV/ITM
Despite its decades-old heritage, printf()-style debugging is still very common. Old favorites die slowly, apparently. But to use printf() debugging in your embedded project, you need to get the output to the host development PC somehow. Traditionally, this has often been done by hooking up PC terminal software to the embedded application, using an RS232 serial cable (nowadays, sometimes using a virtual serial port over USB).
While this debugging method has worked well for several decades, it is quite inconvenient to connect additional cables between the systems. With the Instrumentation Trace Macrocell (ITM), which is part of the SWV concept, you can re-direct printf() output and other data from the embedded application to the host PC debugger, using the JTAG cable.
This blog post explains how to set this up for simple printf() redirection using one ITM port/channel:
An additional blog post takes this concept one step further, and explains how different types of data can be sent from the target system to the host PC debugger using parallel ports/channels, to keep the output separated from each other (effectively, filtering the output data by functionality, purpose, or software module):
Cortex-M debugging: Performance optimization using SWV statistical profiling
Performance optimization has always been a top priority for embedded developers, and it has often been difficult to get any useful insights into the number of clock cycles used by various parts of the software. In reality, this has only been possible by instrumenting the code for profiling, or analyzing instruction trace logs (that requires expensive trace-enabled debug hardware).
With SWV, it becomes possible to measure the execution time of various C functions without software instrumentation or expensive instruction-tracing debug probes. The Cortex-M core can periodically emit program counter data that is sent to the debugger using more or less any low-cost debug probe. The debugger can then analyze these timestamps with program counter information and work out how much time is spent in each C function.
This works using statistical samples, and the measured values are thus approximations only. But if the software is run for a sufficient amount of time (a few seconds), the measured values are usually quite accurate. And the possibility to do this without the price penalty of instrumentation-trace enabled debug probes, and the size and speed penalty of software instrumentation, more than outweighs this disadvantage.
To learn more on statistical profiling, read this blog post:
Cortex-M debugging: Measure execution time using SWV/ITM
In addition to the possibility to measure the execution time of different C functions, SWV also enables the possibility to measure the execution time between two specific points in the code, with the help of ITM tracing.
Not only can you measure the execution time between any two code lines within a C function, but you can also measure the execution time between any arbitrary code lines in the complete application - for example the time it takes from a push-button is pressed to the temperature reach a certain threshold.
To learn more on measuring the execution time of code blocks, read this blog post:
Cortex-M debugging: Memory access history trace log and data plot graph using SWV/SWO
Thanks to SWV, you can also record the memory access history for certain variables or memory locations you want to monitor. Using this feature, you can get a memory access history trace log, that display every read from, and write to, the monitored memory location.
You can thus easily see when the variable get that strange invalid value, that this variable "can't" get (but still do, for some reason). A simple mouse-click on the "memory access" in the history log automatically bring you to the C source code line in the editor that made the memory access.
It has never been easier to figure out why a variable gets a strange value! If a variable get an unexpected value, you not only know exactly what memory write caused the problem, but also what code line did it. This functionality is a life-saver in many situations - I would have saved so many hours of debugging if this capability was available a decade or two ago!
Additionally, using SWV, a debugger can plot variable values as a real-time data plot "oscilloscope" graph, thus providing a highly visual overview of the variable values as the target system executes at full speed.
To read more on memory access tracing, read this blog post:
Cortex-M debugging: Real-time variable watch using SWV/SWO
Another highly useful debug feature you can use is real-time variable watch. With SWV, you can watch variable values changing in real-time as your application executes at full speed.
This is not only useful during debugging, but also during testing in the lab. You can, for example, monitor the XYZ axis positions or acceleration in real-time, as your control electronics make mechanical machinery move physically.
To read more on real-time variable watch, read this blog post:
Cortex-M debugging: Software tracing using SWV/ITM
You can also use SWV/ITM for generic software instrumented trace for many different purposes. You can, for example, log each time an RTOS semaphore is taken or released, log when a push-button is pressed, or log when a temperature sensor reach a certain threshold.
To read more on generic software tracing using SWV/ITM, read this blog post:
What you need to know about debugging interrupts and exceptions on Cortex-M devices
Interrupts and exceptions can be notoriously difficult to debug, but SWV can come to your rescue. With SWV, the debugger can provide statistics on interrupt and exception behavior. It can display any interrupt nesting too. You can thus understand how lower-prioritized interrupt handlers are interrupted by exceptions or interrupts of higher priority. This might reveal some very difficult-to-find bugs indeed!
To learn more on interrupt and exception analysis, read this blog post:
You can also get a good overview of Serial Wire Viewer real-time tracing on Cortex-M cores by reading this white paper on the subject:
Do you want to learn more on ARM Cortex-M development in general? Read this whitepaper: