MCUViewer: Real-Time Variable and SWO Trace Inspection for Cortex-M Devices
Real-time embedded variable & trace viewer
At a glance
- What is it?
- MCUViewer provides a desktop interface for reading global variables through a debug probe and plotting SWO trace output from supported Cortex-M targets. It suits firmware developers who need direct memory inspection or high-frequency signal capture, but the current distribution is closed-source and the variable import workflow has documented limitations.
- Who is it for?
- Firmware engineers debugging global state or tracing Cortex-M activity may find MCUViewer more convenient than repeatedly pausing hardware in a conventional debugger. Projects that require auditable open-source code, local variable inspection, reliable 64-bit variable imports, or vendor-neutral probe support should resolve those boundaries first.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
MCUViewer's Two Debugging Paths
MCUViewer addresses two related firmware observability problems. Its Variable Viewer reads application variables from target RAM while the program is running, then presents their values in plots and supports logging or manual manipulation. Its Trace Viewer decodes SWO data produced through the Cortex-M ITM trace peripheral and turns that stream into digital or analog plots.
The target audience is firmware developers working with an STLink or JLink probe and a debug or release executable whose addresses and symbols can be inspected through an ELF file. Variable Viewer is intended for values that change often enough to follow visually, while Trace Viewer addresses faster signals and execution markers. The README gives function profiling, interrupt-frequency confirmation, and high-frequency signal display as trace use cases.
This is not a general-purpose logic analyzer or source-level debugger. It depends on MCU-specific debug infrastructure, suitable pins, a compatible probe, and instrumented firmware for SWO output. The Variable Viewer also has a structural requirement: its debug-memory approach works with objects whose addresses remain constant, which the README identifies as global variables. That boundary matters more than the word “real-time” because a local or moving object is not a reliable target for this workflow.
Variable Viewer Reads ELF Symbols and Target RAM
According to the README, Variable Viewer obtains variable addresses from the `.elf` file produced by the embedded build. It then reads their current values directly from RAM through the probe's SWDIO and SWCLK connections, with GND also required. This design lets a developer inspect a running application without embedding a logging transport such as UART.
The ELF file is therefore more than a file-selection convenience. It is the mapping between names or symbols in the interface and addresses in target memory. After an ELF file is selected, the user imports variables, updates their addresses, drags them into a plot, selects STLink or JLink, and starts acquisition. The README states that the compiler output should be in debug mode for this process, although the trace documentation separately says that Trace Viewer is unaffected by optimizations.
The address requirement introduces a meaningful limitation. Global objects with stable addresses are suitable, but the documentation does not promise support for local variables whose stack locations change. Automatic variable import is also identified as beta. If a variable remains marked `NOT FOUND!`, the documented fallback is `Add variable`, where the name can be entered manually. Values represented by `uint64_t` and `double` are explicitly unsupported. Consequently, MCUViewer offers useful low-overhead observation, but it is not a complete substitute for a debugger's expression evaluation and type inspection.
SWO Trace Uses ITM Register Writes for Faster Observation
Trace Viewer follows a different data path. Instrumented firmware writes values to an ITM port, the target sends those writes over SWO, the probe transports the trace, and MCUViewer converts the arriving frames into configured channels. The required probe connections for this module are SWDIO, SWCLK, SWO, and GND. The README limits the feature to Cortex-M3, M4, M7, and M33 targets with the required trace hardware.
A software marker can delimit an interval. The documented pattern writes one value before an operation and another afterward, allowing the trace display to show the associated state. Binary data can be represented through `u8`, a float can be written by copying its bit pattern to a `u32` port, and a 16-bit ADC sample can be sent through `u16`. The channel type in MCUViewer must match the instrumented write.
The documentation says each data point is a single register write and that Trace Viewer is not influenced by compiler optimizations. It also describes trace capture as suitable for release builds, although Quick Start still directs first-time users through a CubeMX configuration and firmware compilation sequence. Trace timing depends directly on the system clock and SWO transport rate. An incorrect `System Core Clock` setting changes the timebase, while an insufficient probe rate produces lost or delayed frames. This makes prescaler selection part of correctness, not merely display tuning.
Installing MCUViewer on Linux and Windows
The distribution situation needs attention before installation. The repository is licensed as GPL-3.0, but its README states that MCUViewer is now closed-source and that this repository holds sources for the 1.1.0 release. The README also points current users to the project downloads page. An engineer who requires source for the installed version cannot infer that the repository contains the current executable's implementation.
For Linux, the README requires GDB 12.1 or later and directs users to download a `.deb` package. Install that package with:
sudo apt install ./MCUViewer-x.y.z-Linux.debReplace the placeholder filename with the downloaded package before running the command. The documentation says the dependencies should be installed and the application should then be ready to launch. If Linux permissions prevent STLink detection, the documented remedy is to copy the contents of `launch/install/Unix/udevrules/` into `/etc/udev/rules.d/`.
On Windows, the README directs users to download and run the installer from the project's releases page. STLink devices must be placed in `STM32 Debug + Mass Storage + VCP` mode according to the installation guidance. The README attributes the alternative `STM32 Debug + VCP` behavior to `libusb` errors, but does not claim that the underlying cause has been resolved. The Windows installer is also the only documented path to the currently distributed application, so this is not a source-only build tutorial.
First Variable Viewer Session with MCUViewer
Open `Options -> Acqusition Settings`, select the project's ELF file, and use a debug build. Then choose `Import variables form *.elf`, select the required names, and click `Import`. If a name is not detected, add it manually. After the variable list is complete, click `Update variable addresses`; the documentation says its type and address should change from `NOT FOUND!` to a valid ELF-derived address. Drag each variable into the plot area, connect the probe, select `STLink` or `JLink`, download the executable, and press `STOPPED` to begin.
The spelling `Acqusition` and `Import variables form *.elf` is reproduced because those are the interface labels given by the README. Users troubleshooting an unsuccessful import are directed to the `example/MCUViewer_test` CubeIDE project and its corresponding `MCUViewer_test.cfg` file. They must build that project and update its ELF path in the acquisition settings.
This first-use path is practical enough for a repeatable smoke test, but it does not validate every supported data type. In particular, `uint64_t` and `double` remain outside the documented feature set. If those values matter, the README provides no supported workaround. Adoption should therefore be decided against the actual variables that need inspection rather than the broad label of “variables.”
Configuring SWO Channels and Clock Timing
Begin Trace Viewer setup in CubeMX under `System Core -> SYS Mode and Configuration`, then select `Trace Asynchronous Sw`. Instrument the firmware around the behavior that needs measurement. For a simple state interval, the README shows:
ITM->PORT[x].u8 = 0xaa;
foo();
ITM->PORT[x].u8 = 0xbb;For a float, it documents writing the value's `uint32_t` bit representation:
float a = sin(10.0f * i);
ITM->PORT[x].u32 = *(uint32_t*)&a;After compiling and downloading, enter the correct `System Core Clock` in kHz, configure each MCUViewer channel as `analog` or another suitable type, select a prescaler that keeps the trace below the probe's maximum SWO speed, and press `STOPPED` to record. The README's example divides a 160 MHz system clock by the stated 2 MHz maximum of STLINK V2, producing a prescaler of at least 80.
Trace problems have specific documented responses. Error frames call for a lower trace rate and a shorter SWO connection. `delayed timestamp 3` can indicate SWO bandwidth saturation, while `delayed timestamp 1` means some frames may be delayed. Reducing the number of simultaneous channels is the stated response to both warning classes. Because SWO is standardized but device implementations can differ, the README refers users to SEGGER's SWO documentation for MCU-specific setup.
MCUViewer Open-Source Status and Release History
The repository's licensing metadata identifies GPL-3.0, but the README explicitly says that MCUViewer is now closed-source and that the checked-in sources correspond to release 1.1.0. That distinction affects source review, redistribution, and upgrade planning. The documentation does not provide legal interpretation of what a particular binary or downstream use requires, so engineers must examine the license files and current distribution terms themselves.
The repository is not archived. Its last push was on 2026-08-28. Release information lists `v1.2.9` on the same date, following `v1.2.8` on 2026-06-24 and `v1.2.7` on 2026-06-08. This shows recent repository and release activity, but it does not establish compatibility between the 1.1.0 source tree and the 1.2.9 binary described by the download page. The repository does not provide enough information here to claim that either release supports every current target or probe configuration.
Upgrade cost is therefore tied to external changes. Firmware symbols and ELF formats must remain compatible with variable acquisition, ITM instrumentation may need adjustment, and each Windows upgrade may reinstall the current closed-source application. Linux users also face the GDB 12.1 minimum and possible udev configuration for STLink detection. Teams that pin MCUViewer in a regression workflow should verify probe firmware, target support, configuration-file compatibility, and retained variables before replacing an existing installation.
Editorial conclusion
Firmware engineers debugging global state or tracing Cortex-M activity may find MCUViewer more convenient than repeatedly pausing hardware in a conventional debugger. Projects that require auditable open-source code, local variable inspection, reliable 64-bit variable imports, or vendor-neutral probe support should resolve those boundaries first. The immediate adoption check is whether an up-to-date executable can read the exact ELF file and communicate with the selected STLink or JLink on the target board.
Frequently asked questions
Does MCUViewer support Linux?
Yes. The README documents a `.deb` installation and requires GDB 12.1 or later. It also provides a udev-rule path for STLink detection problems.
Does MCUViewer inspect local variables?
The documented method requires an object's address to remain constant throughout the program, and the README identifies this as requiring a global object. Local variables with changing stack addresses are therefore not a documented use case.
Why is an MCUViewer trace delayed or full of error frames?
The README recommends reducing the trace rate, checking that the high-frequency SWO wire is not too long, or logging fewer channels when the SWO bandwidth is saturated. It also says the configured `System Core Clock` value is important because it affects the timebase.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/klonyyy-mcuviewer)Was this useful?