This post explains some low-level details related to nRF52 Debug Access Port (DAP) protection.
Nordic produces a multitude of ARM System-on-Chip (SoC) products. Among those, nRF52 is a popular ARMv7 chip with Bluetooth 5 support, running at 64 MHz.
For this chip, OpenOCD offers support for basic debugging features (nrf52.cpu
commands), flash manipulation (nrf5
/flash
commands), and advanced debugging via the Debug Access Port (nrf52.dap
).
Upon starting a debugging session via OpenOCD, it will be identified as such:
$ openocd -f interface/cmsis-dap.cfg -f target/nrf52.cfg
[...]
nrf52.cpu: hardware has 6 breakpoints, 4 watchpoints
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
However, on some chips OpenOCD may instead complain when trying to access the debug port:
Error: Could not find MEM-AP to control the core
The above error means that the vendor have disabled debugging capabilities (and firmware access) when flashing this chip.
nRF52 chips come with (optional) flash read-back protection to prevent firmware dumping (among many other things). Such a feature works by disabling access to the default debug port in the CPU (AHB-AP).
Section 14.1.62 of the nRF52 manual describes the APPROTECT
field, which can be written in order to lock access to the debug access port. It is a flash-backed value memory-mapped to address 0x10001208
, with the following semantics:
However the chip includes an additional custom Control Access Port (CTRL-AP), which is always available for core debug access.
This can be used in order to unlock R/W access to the flash, as well as full debug features. Unlocking automatically erases all flash and RAM content, and is performed via the ERASEALL
field.
Its semantics is described in section 16.2.1 of the nRF52 manual, and shown below:
Similarly, AP-protection status can be checked at any time via the the APPROTECTSTATUS
field, which is described in the same section.
OpenOCD can be extended with custom scripts to directly support those operations. The Tcl code below (and submitted as a patch upstream) adds three helper methods:
nrf52_is_ap_protected
returns whether nRF52 debug access is lockednrf52_erase_unlock
erases all nRF52 content and unlock debug accessnrf52_protect_ap
enables nRF52 debug access protection# Return whether debug access is locked (see manual §16.2)
proc nrf52_is_ap_protected {} {
if { [using_hla] } {
return -code error "command not working with hla interfaces"
}
set val [[[target current] cget -dap] apreg 1 0x0c]
return [expr {$val == 0 ? true : false}]
}
add_help_text nrf52_is_ap_protected "return whether nRF52 debug access is locked"
# Erase all content and unlock debug access (see manual §16.2)
proc nrf52_erase_unlock {} {
if { [using_hla] } {
return -code error "command not working with hla interfaces"
}
poll off
set target [target current]
set dap [$target cget -dap]
# Erase all content
$dap apreg 1 0x04 1
# Wait for completion
while {[$dap apreg 1 0x08] == 1} {
echo "erase in progress..."
sleep 150
}
echo "erased and unlocked"
reset halt
poll on
}
add_help_text nrf52_erase_unlock "erase all nRF52 content and unlock debug access"
# Enable debug access protection (see manual §14.1.62)
proc nrf52_protect_ap {} {
poll off
flash fillw 0x10001208 0x00 1
reset run
poll on
}
add_help_text nrf52_protect_ap "enable nRF52 debug access protection"