An extension for nvim-dap providing integration with VS Code's cortex-debug debug adapter.
- Launch nvim-dap sessions using cortex-debug's
launch.json
- Support J-Link and OpenOCD
- Support other GDB servers (#mightwork)
- Globals and Static variable scopes
- Cortex Core Register Viewer (shown under "Registers" scope)
- Peripheral Register Viewer from SVD file
- SWO decoding
- SEGGER RTT using OpenOCD/J-Link (currently only "console")
- Raw Memory Viewer
- Dissassembly viewer
- RTOS support
- Integration with nvim-dap-ui: RTT output
- Download cortex-debug with mason.nvim
Requirements:
- cortex-debug
- node (to start cortex-debug)
- appropriate toolchain and debugger
To use this plugin you must first install cortex-debug VS Code extension. There are a several options:
- If you're using mason.nvim then just
:MasonInstall cortex-debug
- Install it in VS Code and point
extension_path
to appropriate location. - Download the extension from releases and unzip the
.vsix
file (it is just a zip archive) - Clone the repo and build from sources.
Make sure that the extension_path
(see Configuration) is correct.
With the default value of nil
nvim-dap-cortex-debug will try to detect the path from mason.nvim
from the default VS Code extensions path.
Otherwise configure it yourself - it should be the path to the directory in which dist/debugadapter.js
is located.
In most cases the directory will be named marus25.cortex-debug-x.x.x
(so there should be a
marus25.cortex-debug-x.x.x/dist/debugadapter.js
file).
Example using packer.nvim:
use { 'jedrzejboczar/nvim-dap-cortex-debug', requires = 'mfussenegger/nvim-dap' }
Call require('dap-cortex-debug').setup { ... }
in your config.
Available options (with default values):
require('dap-cortex-debug').setup {
debug = false, -- log debug messages
-- path to cortex-debug extension, supports vim.fn.glob
-- by default tries to guess: mason.nvim or VSCode extensions
extension_path = nil,
lib_extension = nil, -- shared libraries extension, tries auto-detecting, e.g. 'so' on unix
node_path = 'node', -- path to node.js executable
dapui_rtt = true, -- register nvim-dap-ui RTT element
-- make :DapLoadLaunchJSON register cortex-debug for C/C++, set false to disable
dap_vscode_filetypes = { 'c', 'cpp' },
rtt = {
buftype = 'Terminal', -- 'Terminal' or 'BufTerminal' for terminal buffer vs normal buffer
},
}
This will configure nvim-dap adapter (i.e. assign to dap.adapters['cortex-debug']
) and set up required nvim-dap listeners.
Now define nvim-dap configuration for debugging, the format is the same as for
cortex-debug.
You can use a launch.json
file (see
nvim-dap launch.json
for details) or define the configuration in Lua.
When writing the configuration in Lua you may write the whole table manually or use one of the helper functions defined in
dap-cortex-debug.lua which sets
up some default values that get overwritten by the passed table, e.g.
local dap_cortex_debug = require('dap-cortex-debug')
require('dap').configurations.c = {
dap_cortex_debug.openocd_config {
name = 'Example debugging with OpenOCD',
cwd = '${workspaceFolder}',
executable = '${workspaceFolder}/build/app',
configFiles = { '${workspaceFolder}/build/openocd/connect.cfg' },
gdbTarget = 'localhost:3333',
rttConfig = dap_cortex_debug.rtt_config(0),
showDevDebugOutput = false,
},
}
which should be equivalent to the following:
local dap_cortex_debug = require('dap-cortex-debug')
require('dap').configurations.c = {
{
name = 'Example debugging with OpenOCD',
type = 'cortex-debug',
request = 'launch',
servertype = 'openocd',
serverpath = 'openocd',
gdbPath = 'arm-none-eabi-gdb',
toolchainPath = '/usr/bin',
toolchainPrefix = 'arm-none-eabi',
runToEntryPoint = 'main',
swoConfig = { enabled = false },
showDevDebugOutput = false,
gdbTarget = 'localhost:3333',
cwd = '${workspaceFolder}',
executable = '${workspaceFolder}/build/app',
configFiles = { '${workspaceFolder}/build/openocd/connect.cfg' },
rttConfig = {
address = 'auto',
decoders = {
{
label = 'RTT:0',
port = 0,
type = 'console'
}
},
enabled = true
},
}
}
GDB server output can be seen in cotex-debug://gdb-server-console
buffer. It is hidden by default,
use :buffer
or some buffer picker to open it. If RTT logging is enabled, a terminal buffer with
the output will be opened (with the name cortex-debug://rtt:PORT
where PORT
is rttConfig.decoders[i].port
).
This extension registers custom DAP UI element rtt
for viewing RTT channel output, e.g.
require('dapui').setup {
layouts = {
{
position = 'left',
size = 96,
elements = {
{ id = 'scopes', size = 0.4 },
{ id = 'rtt', size = 0.6 },
},
},
-- (...)
},
}
To verify common problems run checkhealth:
:checkhealth dap-cortex-debug
cortex-debug implements Debug Adapter Protocol server, so it should be possible to use it with nvim-dap which is a DAP client. However, there are some extensions to DAP that cortex-debug uses, which have to be implemented separately to make it work with nvim-dap.
Cortex-debug is split into two parts: frontend and backend. Backend is what acts as DAP server and does most of the job, fronted is mostly used for preparing configuration data and implementing additional functionality like RTT logging or SVD viewer. For more details see Cortex Debug: Under the hood.
This plugin tries to reimplement cortex-debug frontend. It:
- takes the launch configuration, fills in missing keys, sets default values and checks config correctness;
see
adapter.lua
(backend expects a complete configuration - no missing values) - starts a server to which the output from gdb-server will be sent; this output is displayed in a terminal buffer
(
cortex-debug://gdb-server-console
) - if RTT is enabled, the plugin connects via TCP and shows RTT output in a terminal buffer
- hooks into nvim-dap event/command listeners to handle cortex-debug's custom events and fix some existing incompatibilities
Implementing a missing cortex-debug feature most likely requires implementing some of the custom events and displaying the output in Neovim buffers.