Skip to main content

Embedded Expertise

[Lab] There Is No Single Best JTAG Probe

printf and printk trace. They do not debug.

So which JTAG probe should you choose? My answer: one affordable probe per low-level developer, plus access to a high-end system for the hard cases.

I am often asked what the best JTAG probe or debugging solution is.

That question can turn into a small religion war surprisingly quickly. J-Link, ST-Link, vendor-specific probes, Lauterbach, open tools, proprietary environments: everybody has a favorite, usually for good reasons.

I do not think there is one best answer.

After using many debugging environments over the years, I have ended up with a simpler view: the right probe depends first on what you expect it to do.

For everyday low-level development, I want an affordable probe that can sit permanently on the developer’s desk.

For the hard cases, I want the company or department to have access to a much more capable system, even if it is too expensive to equip everyone.

My own choices are J-Link with GDB for the first role, and Lauterbach hardware with TRACE32 for the second. They are not really competing for the same place in my toolbox.

Before going further, one caveat: probe-less debugging solutions do exist in some environments, typically by running a debug server directly on the target. They can be perfectly appropriate, especially on Linux-class systems, but they come with their own trade-offs and are outside the scope of this discussion.

Here, I am talking specifically about hardware-assisted debugging through JTAG or SWD.

For everyday work, choose something you can give to everyone

If you work on boot code, BSPs, device drivers, bare metal, RTOSes or low-level Linux, a debug probe is not exceptional laboratory equipment. It is an everyday development tool.

My preferred setup is simple: one J-Link per low-level developer, GDB, and optionally a graphical frontend.

The exact brand matters less than availability. A developer should not have to locate a shared unit, unplug somebody else’s target or postpone an investigation because the probe is being used elsewhere.

Saving a few hundred euros by sharing basic debugging equipment can very quickly cost more than it saves. Engineering time remains rather more expensive than a probe.

Why I still use GDB

One can call me old school for using GDB. I am old enough to know it, not old for using it.

GDB remains free, open source, extremely widespread and highly scriptable. It also has one quality I particularly appreciate: it does not try to hide the machine.

Graphical frontends are useful. Source browsing, watches, call stacks and breakpoint management are generally more comfortable in a GUI.

But every GDB frontend I have used eventually becomes restrictive. Sooner or later I need an unusual register, a monitor command, some advanced scripting or an odd reset sequence.

At that point, I usually return to the command line.

For me, the GUI is a convenience layer. It should not define the limits of the debugging environment.

Why J-Link?

J-Link is my personal choice, but not because every embedded developer necessarily needs one.

There are many inexpensive vendor-specific probes. ST-Link is the obvious example, and in an STM32-centric environment it may be the natural and perfectly adequate solution. The same applies to other proprietary cost-effective probes with which I am less familiar.

My preference for J-Link is mainly about portability across platforms. I like being able to keep essentially the same probe and workflow when moving between silicon vendors and processor families.

An STM32 can perfectly well be debugged with a J-Link. Tomorrow’s target may come from NXP or another vendor, and the basic setup can remain largely unchanged.

So my recommendation is not “buy a J-Link.”

It is: choose an affordable, capable probe that every low-level developer can have on the desk. J-Link simply happens to be the one I keep choosing for that role.

Affordable does not mean cheapest

There is one shortcut I would avoid: the ultra-cheap anonymous probes that are easy to find online.

I have tried some of them. The experience can be remarkably frustrating. Slow communication is annoying enough, but intermittent connections and unexplained failures are much worse when the tool itself is supposed to help you find failures.

Electrical robustness also matters. Debug probes get connected to prototypes, development boards and bench setups that are not always perfectly behaved. ESD, grounding differences and voltage differences between the target and the probe are part of real laboratory life. A fragile probe can turn a difficult debugging session into an investigation of the debugger itself.

That is false economy.

An everyday probe does not need to be expensive, but it does need to be trustworthy. When something strange happens on the target, I want the probe to be the last thing I suspect.

The software model also matters

There is another reason I like the J-Link plus GDB combination.

The J-Link hardware, firmware and SEGGER software are proprietary. GDB itself is free and open source.

The probe and the associated GDB server provide the link to the target, while the debugger remains an independent and extremely popular tool. A graphical frontend can be added above that without fundamentally changing the model.

I like this modularity for everyday work. The probe vendor does not completely dictate the way I interact with the target.

However, that becomes less important when debugging gets really difficult.

When a cost-effective probe is no longer enough

Most embedded bugs can be solved using fairly conventional techniques. Set a breakpoint, inspect memory, examine registers, add a watchpoint and narrow the problem down.

Then there are the other bugs.

The problem disappears as soon as the processor stops. Memory was corrupted long before the visible crash. Several cores are involved. Races occur. An interrupt, DMA transfer, RTOS task and peripheral have interacted in precisely the wrong order.

At that point, the question is no longer simply which inexpensive probe offers the best value.

You need a different class of debugging system.

For me, that means Lauterbach.

Lauterbach is not just a more expensive probe vendor

It is useful to separate the hardware from the software.

Lauterbach provides several PowerDebug hardware configurations, with additional trace hardware depending on the target and requirements. TRACE32 PowerView is the software environment used to control and exploit that hardware.

In practice, the two are tightly integrated.

This is quite different from my J-Link and GDB setup. With Lauterbach, TRACE32 is not merely an optional GUI sitting above an otherwise independent probe. If I select Lauterbach hardware, I am realistically also selecting TRACE32.

I am comfortable with that because the integration is precisely what I am paying for.

Target and O/S awareness, scripting, multicore support, sophisticated triggering and trace analysis all belong to the same environment.

For everyday work, I value modularity. For difficult investigations, I value capability.

Multicore and trace change the equation

Modern SoCs can contain several heterogeneous processors, and one physical JTAG connection does not necessarily mean one core at a time. Where the SoC debug architecture supports it, a high-end system can access several debug components behind the same interface and coordinate debugging across them.

The silicon still defines what is possible, of course. No debugger can create access that the SoC does not expose.

The other major step up is hardware execution trace.

Traditional debugging starts from the current state of the machine. The processor has stopped, something is wrong, and you try to infer what happened before.

With trace, enough execution information can be captured in real time to reconstruct the path that led there. TRACE32 can then navigate through that recorded execution history, including backward.

The processor is not literally executing instructions in reverse. The debugger is reconstructing execution that has already happened.

But the practical effect is important: instead of asking how the system might have reached a bad state, you can start looking for the point where things first became wrong.

That is especially valuable for race conditions, interrupt interactions, memory corruption, multicore problems and failures that disappear when conventional debugging interferes with execution.

SEGGER also offers J-Trace for hardware execution trace. I see it as a useful extension of the J-Link ecosystem, but not as a separate category for the purpose of this discussion.

So, which probe should you choose?

For everyday low-level development, choose something affordable enough that every developer can have one permanently available. Vendor-specific probes may be entirely adequate if you stay within one ecosystem. I prefer J-Link because I value portability across targets and vendors.

But affordable should not be confused with disposable. The probe is part of the measurement chain, and like any measurement instrument, it has to be something you can trust.

For the hard cases, do not expect the same inexpensive probe to cover every problem. A company or department working seriously on embedded systems should also have access to a high-end debugging system with deep target awareness, scripting, multicore capabilities and trace.

My choice there is Lauterbach with TRACE32.

Different use cases. Different ownership. Different budgets. That, more than the logo on the probe, is what should drive the choice.

Enjoyed this article?
Embedded Notes is an occasional, curated selection of similar content, delivered to you by email. No strings attached, no marketing noise.

Related resources
  • Platform Architecture service · en | fr
  • Embedded Cybersecurity · en | fr
  • Training · en | fr