Tutorial

How to plot STM32 variables in real time

MCUViewer reads variables straight from the target's RAM through the debug probe while the core keeps running. You don't add any code to your firmware - the addresses and types come from your *.elf file. The same steps work on any Cortex-M target, with an ST-Link, a J-Link or a probe behind OpenOCD.

What you need

  • A debug probe: ST-Link, J-Link, or any probe that works with OpenOCD, such as a CMSIS-DAP probe or the Raspberry Pi Debug Probe.
  • The SWDIO, SWCLK and GND lines connected between the probe and your target.
  • The *.elf file of the firmware running on the target, built with debug information (the default for Debug builds).
  • MCUViewer for Windows, Linux or macOS - free download.
  1. 1Connect the probe and run your firmware

    Wire SWDIO, SWCLK and GND between the probe and the target and let the firmware run as usual. There is nothing to add to your code - MCUViewer finds the variables in the *.elf file and reads them from RAM through the probe.

  2. 2Select the *.elf file and the debug probe

    Open Options → Acquisition, select your project's *.elf file and choose the debug probe: STLINK, JLINK, or GDBSERVER for OpenOCD and other GDB servers (see the STM32 and OpenOCD guide). Then pick the probe's serial number from the list. Sampling [Hz] sets how often the variables are read.

    Fields that are still missing are outlined in red - hover over them to see what's wrong.

  3. 3Import the variables you want to watch

    Close the settings window and click Import variables. MCUViewer lists the variables found in the *.elf file - select the ones you need (Ctrl/Shift for several, or double-click a single one) and click Import.

    Only variables with a fixed address can be read this way: globals and static variables, including struct members and array elements. Local variables on the stack are not available.

  4. 4Drag the variables onto a plot

    Drag variables from the variable table and drop them on a plot. A curve plot shows the values over time, a table plot shows the current values. More plots - curve, bar, table or XY - can be added by right-clicking in the plot group tree.

  5. 5Press start and watch the values live

    Click the large STOPPED button or press Space. The plots update while the MCU keeps running - nothing gets halted. The actual sampling frequency is shown in the top menu bar; if it's lower than you need, raise the SWD speed, or use the Recorder for fast signals.

    When you stop, every sample of the run is still there: pan and zoom through it, measure with cursors or open the statistics window.

  6. 6Change values while the firmware runs

    Table plots can also write: type a new value in the write column and it goes straight to the target's RAM. That's how you tune a PID gain or a setpoint and see the response on the curve plot right away - without rebuilding and re-flashing.

Troubleshooting

My variable isn't in the import list

Make sure it's global or static (it needs a constant address) and isn't a pointer. You can also add it by hand: right-click the variable table, choose New → Variable and type its path, for example myStruct.member. uint64_t and double variables aren't supported.

The sampling frequency I set isn't reached

Try a higher SWD speed, or lower the sampling frequency. For fast signals switch to the Recorder module - it isn't limited by the SWD speed.

The ST-Link can't find my target

First check that STM32CubeProgrammer can connect to it. If it can, switch the probe to STLINK (CUBE PROGRAMMER), or use OpenOCD with GDBSERVER as shown in the STM32 and OpenOCD guide.

My target resets or halts on start (J-Link)

Lower the SWD speed, keep Keep connection checked and try a generic target name such as Cortex-M4 instead of the exact part number.

Next steps

Download MCUViewer for free