Skip to content

Conversation

nmaggioni
Copy link
Contributor

Summary

Both cores of this uC can have a custom SWD DAP instance ID set. Changing these from the default values is uncommon but can help with multi-drop debugging where more than one board is daisy-chained to the same debug probe.

Currently, this can be achieved with a custom OpenOCD config like in the following example, but such a technique needs more testing before it can be considered stable for a broader use.

rp2040-custom_instid.cfg
# SPDX-License-Identifier: GPL-2.0-or-later

# RP2040 is a microcontroller with dual Cortex-M0+ core.
# https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html

# The device requires multidrop SWD for debug.
transport select swd

source [find target/swj-dp.tcl]

if { [info exists CHIPNAME] } {
	set _CHIPNAME $CHIPNAME
} else {
	set _CHIPNAME rp2040
}

if { [info exists WORKAREASIZE] } {
	set _WORKAREASIZE $WORKAREASIZE
} else {
	set _WORKAREASIZE 0x10000
}

if { [info exists CPUTAPID] } {
	set _CPUTAPID $CPUTAPID
} else {
	set _CPUTAPID 0x01002927
}

if { [info exists DAP_INSTID_0] } {
	set _DAP_INSTID_0 $DAP_INSTID_0
} else {
	set _DAP_INSTID_0 0
}

if { [info exists DAP_INSTID_1] } {
	set _DAP_INSTID_1 $DAP_INSTID_1
} else {
	set _DAP_INSTID_1 1
}

# Set to '1' to start rescue mode
if { [info exists RESCUE] } {
	set _RESCUE $RESCUE
} else {
	set _RESCUE 0
}

# Set to '0' or '1' for single core configuration, 'SMP' for -rtos hwthread
# handling of both cores, anything else for isolated debugging of both cores
if { [info exists USE_CORE] } {
	set _USE_CORE $USE_CORE
} else {
	set _USE_CORE SMP
}
set _BOTH_CORES [expr { $_USE_CORE != 0 && $_USE_CORE != 1 }]

swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID

# The rescue debug port uses the DP CTRL/STAT bit DBGPWRUPREQ to reset the
# PSM (power on state machine) of the RP2040 with a flag set in the
# VREG_AND_POR_CHIP_RESET register. Once the reset is released
# (by clearing the DBGPWRUPREQ flag), the bootrom will run, see this flag,
# and halt. Allowing the user to load some fresh code, rather than loading
# the potentially broken code stored in flash
if { $_RESCUE } {
	dap create $_CHIPNAME.rescue_dap -chain-position $_CHIPNAME.cpu -dp-id $_CPUTAPID -instance-id 0xf -ignore-syspwrupack
	init

	# Clear DBGPWRUPREQ
	$_CHIPNAME.rescue_dap dpreg 0x4 0x00000000

	# Verifying CTRL/STAT is 0
	set _CTRLSTAT [$_CHIPNAME.rescue_dap dpreg 0x4]
	if {[expr {$_CTRLSTAT & 0xf0000000}]} {
		echo "Rescue failed, DP CTRL/STAT readback $_CTRLSTAT"
	} else {
		echo "Now restart OpenOCD without RESCUE flag and load code to RP2040"
	}
	shutdown
}

# core 0
if { $_USE_CORE != 1 } {
	dap create $_CHIPNAME.dap0 -chain-position $_CHIPNAME.cpu -dp-id $_CPUTAPID -instance-id $_DAP_INSTID_0
	set _TARGETNAME_0 $_CHIPNAME.core0
	target create $_TARGETNAME_0 cortex_m -dap $_CHIPNAME.dap0 -coreid 0
	# srst does not exist; use SYSRESETREQ to perform a soft reset
	$_TARGETNAME_0 cortex_m reset_config sysresetreq
}

# core 1
if { $_USE_CORE != 0 } {
	dap create $_CHIPNAME.dap1 -chain-position $_CHIPNAME.cpu -dp-id $_CPUTAPID -instance-id $_DAP_INSTID_1
	set _TARGETNAME_1 $_CHIPNAME.core1
	target create $_TARGETNAME_1 cortex_m -dap $_CHIPNAME.dap1 -coreid 1
	$_TARGETNAME_1 cortex_m reset_config sysresetreq
}

if {[string compare $_USE_CORE SMP] == 0} {
	$_TARGETNAME_0 configure  -rtos nuttx
	$_TARGETNAME_1 configure  -rtos nuttx
	target smp $_TARGETNAME_0 $_TARGETNAME_1
}

if { $_USE_CORE == 1 } {
	set _FLASH_TARGET $_TARGETNAME_1
} else {
	set _FLASH_TARGET $_TARGETNAME_0
}
# Backup the work area. The flash probe runs an algorithm on the target CPU.
# The flash is probed during gdb connect if gdb_memory_map is enabled (by default).
$_FLASH_TARGET configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE -work-area-backup 1
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME rp2040_flash 0x10000000 0 0 0 $_FLASH_TARGET

if { $_BOTH_CORES } {
	# Alias to ensure gdb connecting to core 1 gets the correct memory map
	flash bank $_CHIPNAME.alias virtual 0x10000000 0 0 0 $_TARGETNAME_1 $_FLASHNAME

	# Select core 0
	targets $_TARGETNAME_0
}
openocd.cfg
source [find interface/cmsis-dap.cfg]
adapter driver picoprobe
transport select swd
adapter speed 5000

set DAP_INSTID_0 4
set DAP_INSTID_1 5
source [find rp2040-custom_instid.cfg]

Impact

Users will be able to debug boards with non-standard SWD DAP IDs.

Testing

These changes were tested on a Linux host, targeting a custom Cortex-M0+ (RP2040) board using NuttX v12.8.0 as the baseline. They were then manually ported to the current master branch.

The OpenOCD version used in the tests was 0.12.0+dev-gcf9c0b4.

…e IDs

Both cores can have a custom SWD DAP instance ID set. Changing these
from the default values is uncommon but can help with multi-drop
debugging where more than one board are daisy-chained to the same debug
probe.

Currently this can be achieved with a custom OpenOCD config but needs
more testing before it can be considered stable.

Signed-off-by: Niccolò Maggioni <nicco.maggioni+nuttx@gmail.com>
@github-actions github-actions bot added Arch: arm Issues related to ARM (32-bit) architecture Size: M The size of the change in this PR is medium labels Aug 12, 2025
Copy link
Contributor

@acassis acassis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nmaggioni Please include a Documentation/ about this features and explain how the users can use it in a multi channel (daisy chain) scenario.

@nmaggioni
Copy link
Contributor Author

@acassis I will look into that, I am currently waiting for more hardware to test this properly. Anyway, this code also works fine for a single board.

@acassis
Copy link
Contributor

acassis commented Aug 13, 2025

@acassis I will look into that, I am currently waiting for more hardware to test this properly. Anyway, this code also works fine for a single board.

Great! Please include all the necessary details to use this feature, this way people could be use it easily. And will avoid becoming the 1001 hidden features of NuttX

@nmaggioni nmaggioni marked this pull request as draft August 19, 2025 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Arch: arm Issues related to ARM (32-bit) architecture Size: M The size of the change in this PR is medium
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants