Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpu/nRF52: Always recover Device before Flashing #20970

Merged
merged 2 commits into from
Nov 11, 2024

Conversation

crasbe
Copy link
Contributor

@crasbe crasbe commented Nov 8, 2024

Contribution description

With nRF52 silicon revision Fxx and newer, the behavior of the APPROTECT flash protection was changed. Previously it had to be activated manually and as long as it was not activated, the flash could be read from and written to without issues.
After the revision, the device is in a protected state after the first power cycle, making it impossible to read/write/modify the flash memory with an external debugger.

Furthermore, the device has to be unlocked (or in Nordic terms "recovered") explicitly. Unlike the term "recover" might suggest, the flash is erased during that "recovery".
The Segger J-Link does that recovery process implicitly, while OpenOCD has a dedicated nrf52_recover command for it which has to be called after the init command and before any other command.

This necessitated the introduction of another OpenOCD variable, which is between the init and the following target command in the flash procedure, called OPENOCD_POST_INIT_CMDS.

This variable is defined in the shared boards/common/nrf52/Makefile.include and is therefore set for all nRF52 devices. When not using OpenOCD, it does not have any effect and there should not be any adverse effects on other programmers.

A side effect is that earlier silicon revisions might get their flash memory erased by the nrf52_recover command even though it is not necessary for them, but adding a distinction for the old chips is beyond the scope of the RIOT flashing scripts I think.

Testing procedure

Programming any nRF52 board using an external programmer (J-Link or ST-LINK) in conjunction with OpenOCD with the newer silicon revisions should throw an OpenOCD error about the missing recovery command with the current master.

chris@ThinkPias:~/flashdev-riot/RIOT$ PROGRAMMER=openocd BOARD=nrf52840dk make -C examples/hello-world flash -j12
make: Verzeichnis „/home/chris/flashdev-riot/RIOT/examples/hello-world“ wird betreten
Building application "hello-world" for "nrf52840dk" with CPU "nrf52".

"make" -C /home/chris/flashdev-riot/RIOT/pkg/cmsis/ 
...
"make" -C /home/chris/flashdev-riot/RIOT/cpu/cortexm_common/periph
   text    data     bss     dec     hex filename
  11456     108    2328   13892    3644 /home/chris/flashdev-riot/RIOT/examples/hello-world/bin/nrf52840dk/hello-world.elf
/home/chris/flashdev-riot/RIOT/dist/tools/openocd/openocd.sh flash /home/chris/flashdev-riot/RIOT/examples/hello-world/bin/nrf52840dk/hello-world.elf
### Flashing Target ###
Open On-Chip Debugger 0.11.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
swd
Info : J-Link EDU Mini V1 compiled Apr 15 2024 17:39:18
Info : Hardware version: 1.00
Info : VTarget = 2.992 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Error: Could not find MEM-AP to control the core
****** WARNING ******
nRF52 device has AP lock engaged (see UICR APPROTECT register).
Debug access is denied.
Use 'nrf52_recover' to erase and unlock the device.

Warn : target nrf52.cpu examination failed
Info : starting gdb server for nrf52.cpu on 0
Info : Listening on port 39965 for gdb connections
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* nrf52.cpu          cortex_m   little nrf52.cpu          unknown

Error: Could not find MEM-AP to control the core
****** WARNING ******
nRF52 device has AP lock engaged (see UICR APPROTECT register).
Debug access is denied.
Use 'nrf52_recover' to erase and unlock the device.

Error: Target not examined, reset NOT asserted!

With this PR, it should just work. I tested it with a J-Link EDU (an unrelated issue prevents using the builtin J-Link with the latest firmware) and a Nordic Semiconductor nRF52840 DK (PCA10056 Revision 3.0.1 from 2023.6).

chris@ThinkPias:~/flashdev-riot/RIOT$ PROGRAMMER=openocd BOARD=nrf52840dk make -C examples/hello-world flash -j12
make: Verzeichnis „/home/chris/flashdev-riot/RIOT/examples/hello-world“ wird betreten
Building application "hello-world" for "nrf52840dk" with CPU "nrf52".
...
   text    data     bss     dec     hex filename
  11472     108    2328   13908    3654 /home/chris/flashdev-riot/RIOT/examples/hello-world/bin/nrf52840dk/hello-world.elf
/home/chris/flashdev-riot/RIOT/dist/tools/openocd/openocd.sh flash /home/chris/flashdev-riot/RIOT/examples/hello-world/bin/nrf52840dk/hello-world.elf
### Flashing Target ###
Open On-Chip Debugger 0.11.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
swd
Info : J-Link EDU Mini V1 compiled Apr 15 2024 17:39:18
Info : Hardware version: 1.00
Info : VTarget = 2.990 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Error: Could not find MEM-AP to control the core
****** WARNING ******
nRF52 device has AP lock engaged (see UICR APPROTECT register).
Debug access is denied.
Use 'nrf52_recover' to erase and unlock the device.

Warn : target nrf52.cpu examination failed
Info : starting gdb server for nrf52.cpu on 0
Info : Listening on port 35695 for gdb connections
Waiting for chip erase...
nrf52.cpu device has been successfully erased and unlocked.
Info : nrf52.cpu: hardware has 6 breakpoints, 4 watchpoints
Error: nrf52.cpu -- clearing lockup after double fault
Polling target nrf52.cpu failed, trying to reexamine
Info : nrf52.cpu: hardware has 6 breakpoints, 4 watchpoints
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* nrf52.cpu          cortex_m   little nrf52.cpu          halted

target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
Info : nRF52840-xxAA(build code: F0) 1024kB Flash, 256kB RAM
Warn : Adding extra erase range, 0x00002d3c .. 0x00002fff
auto erase enabled
wrote 11580 bytes from file /home/chris/flashdev-riot/RIOT/examples/hello-world/bin/nrf52840dk/hello-world.elf in 0.511253s (22.119 KiB/s)

verified 11580 bytes in 0.079247s (142.701 KiB/s)

shutdown command invoked
Done flashing
make: Verzeichnis „/home/chris/flashdev-riot/RIOT/examples/hello-world“ wird verlassen

Issues/PRs references

This solves #20968 (at least the issues we can fix from RIOTs side).

@crasbe crasbe requested a review from aabadie as a code owner November 8, 2024 15:23
@github-actions github-actions bot added Area: build system Area: Build system Area: tools Area: Supplementary tools Area: boards Area: Board ports labels Nov 8, 2024
Copy link
Contributor

@mguetschow mguetschow left a comment

Choose a reason for hiding this comment

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

Thanks, looks good! Just a minor comment below.

boards/common/nrf52/Makefile.include Show resolved Hide resolved
@mguetschow mguetschow added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Nov 8, 2024
@riot-ci
Copy link

riot-ci commented Nov 8, 2024

Murdock results

✔️ PASSED

168829f boards/nrf52: always recover device before flashing with OpenOCD

Success Failures Total Runtime
10215 0 10215 17m:27s

Artifacts

Copy link
Contributor

@mguetschow mguetschow left a comment

Choose a reason for hiding this comment

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

Confirmed to work locally with a nRF52840dk, revision PCA10056. Thanks a bunch!

@mguetschow mguetschow enabled auto-merge November 8, 2024 17:53
@mguetschow mguetschow added this pull request to the merge queue Nov 8, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Nov 8, 2024
@crasbe
Copy link
Contributor Author

crasbe commented Nov 9, 2024

I'm not sure how this PR broke the 'tests/sys/xtimer_usleep_short' test on native64? 🤔😅

@mguetschow
Copy link
Contributor

Probably an unrelated spurious failure, let's retry :)

@mguetschow mguetschow added this pull request to the merge queue Nov 11, 2024
Merged via the queue into RIOT-OS:master with commit d86738f Nov 11, 2024
29 checks passed
@crasbe
Copy link
Contributor Author

crasbe commented Nov 12, 2024

Probably an unrelated spurious failure, let's retry :)

Awesome, thank you :)
Now it merged fine.

@crasbe crasbe deleted the pr/nRF_OpenOCD branch November 12, 2024 07:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: boards Area: Board ports Area: build system Area: Build system Area: tools Area: Supplementary tools CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants