From time to time, I face some problems that are really hard to find. Mostly, these kind of bugs are very time-sensitive and depend on interrupt execution order. Maybe a dangling pointer is overwriting memory, code is running wild, or some functions are not reentrant like they should be. For these kinds of bugs, good tools are worth their weight in gold. The Percepio FreeRTOS+Trace and the Segger SystemView have helped me many times to narrow down such kind problems in my applications. Another ultimate tool is hardware trace: Now I have a Segger J-Trace Pro for ARM Cortex-M in my arsenal of bug extinguishing weapons on my desk.
Dear bugs, look what I have on my desk. You have nowhere to hide now!
The unit came with all the cables: two USBs, Ethernet, 20-pin and 19-pin Cortex ribbon cables, plus a 5V/700mA USB power supply (for the small debug board, more about this later):
The box includes the 'Cortex-M Trace Reference Board,' powered by an ARM Cortex-M4F (STM32F407VE). For this one, there is the provided 5V USB power supply. The J-Trace itself gets power through the USB plug. The unit has both a USB and Ethernet/LAN host connection:
The reference board is actually a really cool thing: It's a board I can use with my tutorials, and I don’t have to mess with my hardware first (more about this later).
The reference board is sold separately too, but did not find it in the Segger web shop. The trace test points are available on the board, and if more pins would be available (e.g. for a header row), that could be a cool general purpose board, too.
Main features of the trace unit:
- ETM Tracing and Cortex-M debugging.
- USB 2.0 (480 MBit/s) and Gigabit Ethernet interface.
- ‘Unlimited’ streaming to the host.
- 64 MByte on-board trace memory.
- Supports all Cortex-M (M0, M0+, M1, M3, M4, M7).
- 50 MHz JTAG speed.
- Can be used like a normal J-Link debugging probe.
As with other Segger probes, there is Windows, Linux, and Mac OS host support. I have used the J-Trace under Windows.
The probe can be used like a normal Segger J-Link debugging probe, e.g. with the NXP Kinetis Design Studio or any IDE which supports the Segger J-Link probes. What I noticed compared to the Segger EDU or the OpenSDA implementation that it is much faster downloading.
Unlike the ‘normal’ Segger J-Link units, I do not need an SWD cable adapter with the 20-pin Cortex Debug+ETM connector (labeled “Target+Trace”):
I could still use the J-Link adapter board if needed on the ‘Target’ port (but that will be for debugging only). This makes sense if need access to the signals or want to use the 10pin debug cable instead (note that the J-Link Adapter Board is not part of the J-Trace package):
There are several status LEDs on the unit that are very helpful to solve possible oversights like target not powered. The ‘Trace’ LED is on when the units collect trace:
The Eclipse-based Kinetis Design Studio does not include trace capabilities. CodeWarrior does, but all my current NXP projects are running either with LPCXpresso or with the NXP Kinetis Design Studio, and CodeWarrior is kept only for legacy and maintenance projects. I saw that the Segger documentation and tutorials mention Ozone. Ozone is Segger’s own debugger, which, of course, supports the J-Link debug probes.
In case of an ’emulated’ J-Link, like the OpenSDA J-Link firmware, a dialog pops up:
When I first saw the news about Segger providing their own debugger, I was kind of thinking: “Why yet another debugger?” Well, after using it a for a few days, I think it is actually a good thing: It is small (14 MByte download), it is very snappy and fast, and it does its job very well:
And with the J-Trace tutorial, I was indeed able to get the trace demo working in less than 15 minutes, using the reference board:
Ozone features all the usual views I expect (source, memory, console/terminal, registers, disassembly, call stack) and many others:
Views can be moved around and put over each other to have a ‘tabbed’ view. Views can be moved out of the main window, such as to be placed on a separate monitor display.
The source view offers line numbers, setting breakpoints. What I really like is that I can unfold a source line, and it directly shows the disassembly code:
The debugger has an easy way to attach to an already running application (this is usually a big pain in other debuggers):
The ‘Download & Reset Program’ does exactly that. There is no way in the UI to specify, for example, a temporary breakpoint on main().
Ozone has a nice scripting engine: It seems that pretty much everything is scriptable:
Actually the Ozone project files are (sor of) C files written in that scripting language. That way, I can easily change the debugger:
The instruction trace shows the executed instructions and shows it synced with the source and disassembly view:
It automatically groups the trace instructions by the functions:
Trace getting streamed to the host application (Ozone) is almost ‘unlimited’ that way, and I was able to collect trace for a long time.
Code Profile View
The Code Profile view shows source and instruction coverage based on the instruction counters:
The execution counters can be turned on in the source view:
While I wish that would work the same way in Eclipse, unfortunately, there is no Ozone Eclipse plugin (yet?). Just imagine getting the instruction trace and profiling information into Eclipse. That would be fabulous.
I’m working with Ozone in the following way: I build the project in Eclipse and have the .elf file/project configured in Ozone for debugging. When I rebuild the .elf file, Ozone automatically detects the change and reloads it:
The J-Trace works really nicely in combination with the Ozone debugger. At first, I thought the Ozone debugger wasn't necessary. But it makes sense, and it can be used with Eclipse or any other IDE.
I was able to get trace with Ozone, J-Trace, and the Cortex-M Trace Reference board in a very short time early this past Sunday morning. But I spent the rest of the day trying get trace out of my TWR-K64F120M board, so I have to come up with a follow-up article.
This is why I think Segger includes that trace reference board as a starting point: Getting trace out of the Tower board was not easy because of incorrect board documentation and example code, and trace pins used for other board components. This is not Segger's fault, but it made it clear to me why Segger provides that reference board: “It just works.”
The follow-up article about tracing Kinetis with the J-Trace has to wait for a few days until I find time to publish it, so stay tuned. And to all the bugs out there: You have a few days more to hide, but no more!