Explore Freedom of Choice with Debug Extensions for NXP and Cortex-Debug

I’m using different MCUS from NXP with VS Code, and for this I’m mostly using the NXP MCUXpresso extension for VS Code.

At the same time, I’m using the cortex-debug extension for other ARM Cortex-M based MCUs, for example the Raspberry Pi Pico series.

Does it makes sense to use cortex-debug for NXP devices, and what would be the benefit? More precise: can I use the NXP MCU-Link (LinkServer based) debug probes with cortex-debug, to debug another NXP MCU?

MCU-Link (right) debugging a MCU-Link Pro (LPC55S69, right) with cortex-debug
NXP MCU-Link (right) debugging a NXP MCU-Link Pro (LPC55S69, right)

Outline

cortex-debug from marus25 is a popular debug extension for Cortex-M. It is a very versatile extension, and one can find many tutorials and examples for it. It works with the mcu-debug RTOS views (XRTOS) or mcu-debug Memory view extension.

NXP offers the MCUXpresso extension for VS Code extension. That extension supports debugging NXP micro-controllers with NXP LinkServer/MCU-Link/LPC-Link, SEGGER and PEMICRO debug probes. It supports debugging NXP MCUs out of the box. Additionally it includes automatic probe detection and probe switching. With the MCUXpresso extension v26.6.57, it supports the mcu-debug RTOS Views plus the mcu-debug Memory view.

In the next sections, I show how to use cortex-debug in addition to the NXP extension, plus how to use the mcu-debug RTOS and Memory views. I’m using the NXP FRDM-MCXN946 board with LinkServer debugger. This can be easily changed to any other board you have.

Extension Debugging Features

The table below gives an overview about debugging features in each extension:

cortex-debugMCUXpresso for VS Code
virtually any Cortex-M devices, plus Cortex-A, Extensa, RISC-VNXP Cortex-M devices
Separate launch config for each probeSingle launch configuration for different probes
textual launch.jsontextual launch.json, graphical editor (experimental)
disassembly: CTRL+SHIFT+P Open Disassembly View/Toggle Source Code in Disassembly viewdisassembly: debug toolbar icon
mcu-debug MEMORY viewmcu-debug MEMORY, MEMORY INSPECTOR (Eclipse CDT cloud) enabled
mcu-debug XRTOS view (FreeRTOS)mcu-debug XRTOS plus RTOS view (Zephyr, FreeRTOS)
XPERIPHERALS viewPERIPHERALS plus OFFLINE PERIPHERALS view
SWO/ITMSWO/ITM, Power/Energy Measurement Data display
SEGGER RTT, SemihostingSemihosting
CMSIS-PACKNXP SDK Manifest

So from the feature comparison, most of the things are covered in the MCUXpresso extension too. Using cortex-debug gives a VS Code RTT support. But I always prefer having multiple way (or debug probes) of doing things.

Plus with installed mcu-debug views (XRTOS, MEMORY) I get extra views for the MCUXpresso extension.

Grahical launch.json view/editor

VS Code uses the .vscode/launch.json file for the debug configuration. What the MCUXpresso extension has added (experimental, you need to enable it in the settings) is a graphical view/editor of the settings:

Graphical launch.json editor
Graphical launch.json editor

This makes exploring and editing the launch.json file easier, as I can see all the different possible settings.

mcuxpresso-debug Debug Configuration

As reference, below is the MCUXpresso debug configuration I’m using:

{
"type": "mcuxpresso-debug",
"name": "MCUXpresso-debug",
"request": "launch",
"cwd": "${workspaceFolder}",
"stopAtSymbol": "main",
"probeSerialNumber": "",
"isAttach": false,
"skipBuildBeforeDebug": false,
"gdbInitCommands": [
"set remotetimeout 600",
"set debug-file-directory",
"set non-stop off"
],
"postLaunchCommands": [
"mon semihosting ena"
],
"gdbServerConfigs": {
"linkserver": {
"gdbServerCwd": "${workspaceFolder}",
"gdbServerExtraArgs": [
"--semihost-port=4444"
],
"device": "MCXN947:FRDM-MCXN947",
"core": "cm33_core0"
},
"segger": {
"rtos": "GDBServer/RTOSPlugin_FreeRTOS",
"gdbServerCwd": "${workspaceFolder}"
},
"pemicro": {},
},
"showDevDebugOutput": "none",
"svdPath": "${workspaceFolder}/sdk/mcuxsdk/svd/MCXN947/MCXN947_cm33_core0.xml"
}

J-Link cortex-debug Debug Configuration

Below is what I’m using with J-Link and cortex-debug:

{ // see https://github.com/Marus/cortex-debug/blob/master/debug_attributes.md
"name": "J-Link cortex-debug",
"type": "cortex-debug",
"request": "launch",
"servertype": "jlink",
"serverpath": "${env:PICO_JLINK_PATH}/JLinkGDBServerCL", // running on Windows Host
"cwd": "${workspaceFolder}",
"executable": "${command:cmake.launchTargetPath}",
"armToolchainPath": "${env:TOOLCHAIN_PATH}", // needed for the gdb
"device": "MCXN947_M33_0",
"interface": "swd",
"runToEntryPoint": "main", // "_reset_handler" or for example "main"
"postLaunchCommands": [
"monitor semihosting enable",
"monitor semihosting ioclient 3", // 1: telnet (localhost, port 50002); 2: gdb; 3: both telnet and gdbclient output
],
"rtos": "FreeRTOS",
"svdFile": "./sdk/mcuxsdk/svd/MCXN947/MCXN947_cm33_core.xml",
"rttConfig": { // use view in 'Terminal'
"enabled": true,
"address": "0x20008638",
"decoders": [
{
"label": "Console0",
"port": 0,
"type": "console"
}
]
},
}

LinkServer cortex-debug Launch Configuration

Below is my launch.json for using LinkServer with cortex-debug:

{
"type": "cortex-debug",
"name": "LinkServer cortex-debug",
"request": "launch",
"servertype": "external",
"gdbTarget": "localhost:3333",
"preLaunchTask": "LinkServer: gdbserver", // or: LinkServer gdbserver --keep-alive MCXN947:FRDM-MCXN947 --semihost-port=4444
"cwd": "${workspaceFolder}",
//"executable": "${command:cmake.launchTargetPath}",
"executable": "./debug/frdm-mcxn947_ezh_cm33_core0.elf",
"armToolchainPath": "${env:TOOLCHAIN_PATH}", // needed for the gdb
"runToEntryPoint": "main",
"postLaunchCommands": [
"mon semihosting ena",
"file ./debug/frdm-mcxn947_ezh_cm33_core0.elf" // need this extra symbol file load for proper RTOS awareness
],
"symbolFiles": [
//"${command:cmake.launchTargetPath}",
"./debug/frdm-mcxn947_ezh_cm33_core0.elf"
],
"svdFile": "./sdk/mcuxsdk/svd/MCXN947/MCXN947_cm33_core0.xml",
"rttConfig": { // adds automatically a view in 'Terminal' view
"enabled": true,
"address": "0x20008638",
"decoders": [
{
"label": "Console0",
"port": 0,
"type": "console"
}
]
},
}

Unlike J-Link, cortex-debug does not directly support LinkServer. Instead, I’m using the “external” “servertype”.

Using a “PreLaunchTask”, I have created a VS Code task (.vscode/tasks.json) to start LinkServer. The task looks like this:

    {
"type": "shell",
"label": "LinkServer: gdbserver",
"command": "LinkServer gdbserver MCXN947:FRDM-MCXN947 --semihost-port=1234",
"options": {
"cwd": "${workspaceFolder}"
},
"isBackground": true,
"group": {
"kind": "build",
"isDefault": false
},

With this task, cortex-debug will automatically start the GDB server in LinkServer for debugging. Note that the same approach can be used for remote debugging too.

RTOS Views

With the XRTOS view (extension mcu-debug.rtos-views) I get a view of tasks, queues and mutex/semaphore:

Tasks in XRTOS
Tasks in XRTOS
Queue in XRTOS
Queue in XRTOS
Semaphore and Mutex in XRTOS
Semaphore and Mutex in XRTOS

With the MCUXpresso extension v26.6.57 or later I can get the above views too. The NXP extension comes with its own RTOS view for FreeRTOS and Zephyr:

RTOS Details (NXP MCUXpresso Extension) showing FreeRTOS tasks
RTOS Details (NXP MCUXpresso Extension) showing FreeRTOS tasks

Memory Views

The NXP Extension comes with the CDT Memory Inspector. To open it, use CTRL-SHIFT-P with Memory: Show Memory Inspector:

Show Memory Inspector

This opens the inspector (read only, cannot change memory):

Memory Inspector
Memory Inspector

That CDT Cloud Memory Inspector can be enabled for cortex-debug in the settings:

Memory Inspector enabled for cortex-debug

mcu-debug comes with a MEMORY view which most embedded developers expect. Just keep in mind that currently this view does not support writing back (feature still planned). But it is a very good viewer.

mcu-debug MEMORY View
mcu-debug MEMORY View

Summary

I have used the cortex-debug extension for many years.It does one thing well (debug). It is vendor neutral. But the last release is from January 2023, and not clear if there will be an update anytime soon.

The NXP MCUXpresso extension v26.6.57 supports now the XRTOS and MEMORY views too, which is really nice addition. Making me less switch between cortex-debug and MCUXpresso extension.

Other than that: I always prefer to have multiple ways of doing things. Not every extension is perfect. Then it is always good to have a second tool at hand. With this, to me it is not the one or the other, but both together which make me most efficient during debugging.

Happy extensioning:-)

Links

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.