RIOT-OS / RIOT

RIOT - The friendly OS for IoT
https://riot-os.org
GNU Lesser General Public License v2.1
4.9k stars 1.98k forks source link

riotboot/nrf52840dk: flashing slot1 with JLINK fails #14576

Closed fjmolinas closed 5 months ago

fjmolinas commented 4 years ago

Description

Flashing slot1 results in an unspecified error when using JLINK on nrf52840dk. This works with Openocd.

Steps to reproduce the issue

BUILD_IN_DOCKER=1 BOARD=nrf52840dk make -C tests/riotboot/ riotboot/flash-slot1

Expected results

Flashing succeeds.

Actual results

Unspecified error.

compiling /home/francisco/workspace/RIOT2/dist/tools/riotboot_gen_hdr/bin/genhdr...
creating /home/francisco/workspace/RIOT2/tests/riotboot/bin/nrf52840dk/tests_riotboot-slot1.1595408589.riot.bin...
/home/francisco/workspace/RIOT2/dist/tools/jlink/jlink.sh flash /home/francisco/workspace/RIOT2/tests/riotboot/bin/nrf52840dk/tests_riotboot-slot1.1595408589.riot.bin
### Flashing Target ###
### Flashing at base address 0x0 with offset 528384 ###
SEGGER J-Link Commander V6.71a (Compiled Apr  3 2020 11:59:31)
DLL version V6.71a, compiled Apr  3 2020 11:59:21

J-Link Commander will now exit on Error

J-Link Command File read successfully.
Processing script file...

J-Link connection not established yet but required for command.
Connecting to J-Link via USB...O.K.
Firmware: J-Link OB-SAM3U128-V2-NordicSemi compiled Jan  7 2019 14:07:15
Hardware version: V1.00
S/N: 683890121
License(s): RDI, FlashBP, FlashDL, JFlash, GDB
VTref=3.300V
Target connection not established yet but required for command.
Device "NRF52" selected.

Connecting to target via SWD
InitTarget() start
InitTarget() end
Found SW-DP with ID 0x2BA01477
Unknown DP version. Assuming DPv0
Scanning AP map to find all available APs
AP[2]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x24770011)
AP[1]: JTAG-AP (IDR: 0x02880000)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FF000
CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)
Found Cortex-M4 r0p1, Little endian.
FPUnit: 6 code (BP) slots and 2 literal slots
CoreSight components:
ROMTbl[0] @ E00FF000
ROMTbl[0][0]: E000E000, CID: B105E00D, PID: 000BB00C SCS-M7
ROMTbl[0][1]: E0001000, CID: B105E00D, PID: 003BB002 DWT
ROMTbl[0][2]: E0002000, CID: B105E00D, PID: 002BB003 FPB
ROMTbl[0][3]: E0000000, CID: B105E00D, PID: 003BB001 ITM
ROMTbl[0][4]: E0040000, CID: B105900D, PID: 000BB9A1 TPIU
ROMTbl[0][5]: E0041000, CID: B105900D, PID: 000BB925 ETM
Cortex-M4 identified.
Halting CPU for downloading file.
Downloading file [/home/francisco/workspace/RIOT2/tests/riotboot/bin/nrf52840dk/tests_riotboot-slot1.1595408589.riot.bin]...
Unspecified error -1

Script processing completed.

Versions

Operating System Environment
----------------------------
         Operating System: "Ubuntu" "18.04.4 LTS (Bionic Beaver)"
                   Kernel: Linux 5.3.0-62-generic x86_64 x86_64
             System shell: /bin/dash (probably dash)
             make's shell: /bin/dash (probably dash)

Installed compiler toolchains
-----------------------------
               native gcc: gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
        arm-none-eabi-gcc: arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 8-2018-q4-major) 8.2.1 20181213 (release) [gcc-8-branch revision 267074]
                  avr-gcc: avr-gcc (GCC) 5.4.0
         mips-mti-elf-gcc: missing
               msp430-gcc: msp430-gcc (GCC) 4.6.3 20120301 (mspgcc LTS 20120406 unpatched)
     riscv-none-embed-gcc: riscv-none-embed-gcc (GNU MCU Eclipse RISC-V Embedded GCC, 64-bit) 8.2.0
     xtensa-esp32-elf-gcc: missing
   xtensa-esp8266-elf-gcc: xtensa-esp8266-elf-gcc (crosstool-NG crosstool-ng-1.22.0-80-g6c4433a5) 5.2.0
                    clang: missing

Installed compiler libs
-----------------------
     arm-none-eabi-newlib: "3.0.0"
      mips-mti-elf-newlib: missing
  riscv-none-embed-newlib: "3.0.0"
  xtensa-esp32-elf-newlib: missing
xtensa-esp8266-elf-newlib: "2.2.0"
                 avr-libc: "2.0.0" ("20150208")

Installed development tools
---------------------------
                   ccache: ccache version 3.4.1
                    cmake: cmake version 3.14.0-rc3
                 cppcheck: Cppcheck 1.82
                  doxygen: 1.8.16
                      git: git version 2.27.0
                     make: GNU Make 4.1
                  openocd: Open On-Chip Debugger 0.10.0+dev-01100-g51dd4ce6-dirty (2020-03-03-15:33)
                   python: Python 3.6.9
                  python2: Python 2.7.17
                  python3: Python 3.6.9
                   flake8: 3.7.7 (mccabe: 0.6.1, pycodestyle: 2.5.0, pyflakes: 2.1.1) CPython 3.6.9 on Linux
               coccinelle: spatch version 1.0.4 with Python support and with PCRE support
kaspar030 commented 4 years ago

I've seen this before. does the slot start at a flashpage boundary?

fjmolinas commented 4 years ago

I've seen this before. does the slot start at a flashpage boundary?

Seems so:

### Flashing at base address 0x0 with offset 528384 ###

528384 = 0x81000, pages are 0x1000 on nrf52

kaspar030 commented 4 years ago

did you update your jlink tools lately? maybe a newer version comes with a firmware upgrade.

kaspar030 commented 4 years ago

my arch installs JlinkExe 6.82a, which just upgraded my nrf52840dk's firmware.

fjmolinas commented 4 years ago

my arch installs JlinkExe 6.82a, which just upgraded my nrf52840dk's firmware.

Does it work for you?

kaspar030 commented 4 years ago

Does it work for you?

no:

Downloading file [/home/kaspar/src/riot.tmp/tests/riotboot/bin/nrf52840dk/tests_riotboot-slot1.1595414157.riot.bin]...
Writing target memory failed.

Script processing completed.

make: *** [/home/kaspar/src/riot.tmp/makefiles/boot/riotboot.mk:135: riotboot/flash-slot1] Error 1
kaspar030 commented 4 years ago

no:

sorry, updating JLink is my first step when it shows any issues, that's why I proposed it.

fjmolinas commented 4 years ago

sorry, updating JLink is my first step when it shows any issues, that's why I proposed it.

No prob, I avoid updating jlink because latest version have popups I haven't found out how to get rid off...

maribu commented 1 year ago

@SEGGERMicro I think that for this issue actually JLinkExe is to blame. The relevant part of the output is:

SEGGER J-Link Commander V7.88c (Compiled May 16 2023 15:43:50)
DLL version V7.88c, compiled May 16 2023 15:43:32

J-Link Commander will now exit on Error

J-Link Command File read successfully.
Processing script file...
J-Link>loadbin /home/maribu/Repos/software/RIOT/tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.1684495571.bin 0x00081000
J-Link connection not established yet but required for command.
Connecting to J-Link via USB...O.K.
Firmware: J-Link OB-SAM3U128-V2-NordicSemi compiled Nov  7 2022 16:21:57
Hardware version: V1.00
J-Link uptime (since boot): 0d 00h 28m 51s
S/N: 683252646
License(s): RDI, FlashBP, FlashDL, JFlash, GDB
USB speed mode: High speed (480 MBit/s)
VTref=3.300V
Target connection not established yet but required for command.
Device "NRF52" selected.

Connecting to target via SWD
InitTarget() start
InitTarget() end - Took 1.95ms
Found SW-DP with ID 0x2BA01477
DPIDR: 0x2BA01477
CoreSight SoC-400 or earlier
Scanning AP map to find all available APs
AP[2]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x24770011)
AP[1]: JTAG-AP (IDR: 0x02880000)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FF000
CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)
Found Cortex-M4 r0p1, Little endian.
FPUnit: 6 code (BP) slots and 2 literal slots
CoreSight components:
ROMTbl[0] @ E00FF000
[0][0]: E000E000 CID B105E00D PID 000BB00C SCS-M7
[0][1]: E0001000 CID B105E00D PID 003BB002 DWT
[0][2]: E0002000 CID B105E00D PID 002BB003 FPB
[0][3]: E0000000 CID B105E00D PID 003BB001 ITM
[0][4]: E0040000 CID B105900D PID 000BB9A1 TPIU
[0][5]: E0041000 CID B105900D PID 000BB925 ETM
Memory zones:
  Zone: "Default" Description: Default access mode
Cortex-M4 identified.
'loadbin': Performing implicit reset & halt of MCU.
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
Downloading file [/home/maribu/Repos/software/RIOT/tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.1684495571.bin]...
Writing target memory failed.

Script processing completed.

It seems that flashing a bin file to the nRF52840-DK fails with JLinkExe, if the image is not to be written at the start of the flash.

crasbe commented 5 months ago

It seems like the issue was not (solely) to blame on JLink. As you can see in the previous logs, JLinkExe selected "NRF52" as a target. While that is generally correct as in "that's the processor family", it does not work for programming the nRF52840.

The origin of this selection goes back to the common Makefile definition of "JLINK_DEVICE=nrf52" here: https://github.com/RIOT-OS/RIOT/blob/master/boards/common/nrf52/Makefile.include#L22 This Makefile is included for every nRF52 board and therefore all nRF52 boards have "nrf52" specified as the JLink target.

First I tried to reproduce the isuse with the latest version (and it seems like Segger pushes out updates on a daily basis...) The call I used was the following (no need to build it with docker I guess):

BOARD=nrf52840dk make -C tests/riotboot/ riotboot/flash-slot1

It gave the following result with the same message about a failed write. As you can see, it selected "NRF52" as a target as well.

/home/chris/flashdev-riot/RIOT/dist/tools/jlink/jlink.sh flash /home/chris/lashdev-riot/RIOT/tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.1713438899.bin
### Flashing Target ###
### Flashing bin file at base address 0x0 with offset 0x81000 ###
SEGGER J-Link Commander V7.96e (Compiled Apr 17 2024 16:28:22)
DLL version V7.96e, compiled Apr 17 2024 16:27:56

J-Link Commander will now exit on Error

J-Link Command File read successfully.
Processing script file...
J-Link>loadbin /home/chris/flashdev-riot/RIOT/tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.1713438899.bin 0x00081000
J-Link connection not established yet but required for command.
Connecting to J-Link via USB...O.K.
Firmware: J-Link OB-nRF5340-NordicSemi compiled Apr 11 2024 17:44:26
Hardware version: V1.00
J-Link uptime (since boot): 0d 00h 22m 00s
S/N: 1050208458
License(s): RDI, FlashBP, FlashDL, JFlash, GDB
USB speed mode: Full speed (12 MBit/s)
VTref=3.300V
Target connection not established yet but required for command.
Device "NRF52" selected.

Connecting to target via SWD
InitTarget() start
InitTarget() end - Took 1.89ms
Found SW-DP with ID 0x2BA01477
DPIDR: 0x2BA01477
CoreSight SoC-400 or earlier
Scanning AP map to find all available APs
AP[2]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x24770011)
AP[1]: JTAG-AP (IDR: 0x02880000)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FF000
CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)
Found Cortex-M4 r0p1, Little endian.
FPUnit: 6 code (BP) slots and 2 literal slots
CoreSight components:
ROMTbl[0] @ E00FF000
[0][0]: E000E000 CID B105E00D PID 000BB00C SCS-M7
[0][1]: E0001000 CID B105E00D PID 003BB002 DWT
[0][2]: E0002000 CID B105E00D PID 002BB003 FPB
[0][3]: E0000000 CID B105E00D PID 003BB001 ITM
[0][4]: E0040000 CID B105900D PID 000BB9A1 TPIU
[0][5]: E0041000 CID B105900D PID 000BB925 ETM
Memory zones:
  Zone: "Default" Description: Default access mode
Cortex-M4 identified.
'loadbin': Performing implicit reset & halt of MCU.
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
Downloading file [/home/chris/flashdev-riot/RIOT/tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.1713438899.bin]...
Writing target memory failed.

Script processing completed.

make: *** [/home/chris/flashdev-riot/RIOT/makefiles/boot/riotboot.mk:148: riotboot/flash-slot1] Fehler 1
make: Verzeichnis „/home/chris/flashdev-riot/RIOT/tests/riotboot“ wird verlassen

Then I started JLinkExe manually and selected the correct "NRF52840_XXAA" target and the loadbin command worked. The erase had to be done because even though JLink says the write operation failed, it actually complains about the memory already having the correct content. However this does not change the effect of the loadbin command.

SEGGER J-Link Commander V7.96e (Compiled Apr 17 2024 16:28:22)
DLL version V7.96e, compiled Apr 17 2024 16:27:56

Connecting to J-Link via USB...O.K.
Firmware: J-Link OB-nRF5340-NordicSemi compiled Apr 11 2024 17:44:26
Hardware version: V1.00
J-Link uptime (since boot): 0d 00h 24m 47s
S/N: 1050208458
License(s): RDI, FlashBP, FlashDL, JFlash, GDB
USB speed mode: Full speed (12 MBit/s)
VTref=3.300V

Type "connect" to establish a target connection, '?' for help
J-Link>connect
Please specify device / core. <Default>: NRF52
Type '?' for selection dialog
Device>?
Please specify target interface:
  J) JTAG (Default)
  S) SWD
  T) cJTAG
TIF>S
Specify target interface speed [kHz]. <Default>: 4000 kHz
Speed>
Device "NRF52840_XXAA" selected.

Connecting to target via SWD
InitTarget() start
InitTarget() end - Took 2.17ms
Found SW-DP with ID 0x2BA01477
DPIDR: 0x2BA01477
CoreSight SoC-400 or earlier
Scanning AP map to find all available APs
AP[2]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x24770011)
AP[1]: JTAG-AP (IDR: 0x02880000)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FF000
CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)
Found Cortex-M4 r0p1, Little endian.
FPUnit: 6 code (BP) slots and 2 literal slots
CoreSight components:
ROMTbl[0] @ E00FF000
[0][0]: E000E000 CID B105E00D PID 000BB00C SCS-M7
[0][1]: E0001000 CID B105E00D PID 003BB002 DWT
[0][2]: E0002000 CID B105E00D PID 002BB003 FPB
[0][3]: E0000000 CID B105E00D PID 003BB001 ITM
[0][4]: E0040000 CID B105900D PID 000BB9A1 TPIU
[0][5]: E0041000 CID B105900D PID 000BB925 ETM
Memory zones:
  Zone: "Default" Description: Default access mode
Cortex-M4 identified.
J-Link>Erase
No address range specified, 'Erase Chip' will be executed
'erase': Performing implicit reset & halt of MCU.
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
Erasing device...
J-Link: Flash download: Total time needed: 0.346s (Prepare: 0.098s, Compare: 0.000s, Erase: 0.177s, Program: 0.000s, Verify: 0.000s, Restore: 0.071s)
Erasing done.
J-Link>loadbin tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.
tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.1713438886.bin  tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.elf            
tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.1713438899.bin  tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.hdr            
tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.bin            
J-Link>loadbin tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.1713438886.bin 0x00081000
'loadbin': Performing implicit reset & halt of MCU.
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
Downloading file [tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.1713438886.bin]...
J-Link: Flash download: Bank 0 @ 0x00000000: 1 range affected (20480 bytes)
J-Link: Flash download: Total: 0.315s (Prepare: 0.051s, Compare: 0.009s, Erase: 0.000s, Program & Verify: 0.221s, Restore: 0.033s)
J-Link: Flash download: Program & Verify speed: 90 KB/s
O.K.

In order to verify my hypothesis I temporarily modified the boards/common/nrf52/Makefile.include to specify "JLINK_DEVICE=nrf52840_xxaa" and this is the resulting log:

/home/chris/flashdev-riot/RIOT/dist/tools/jlink/jlink.sh flash /home/chris/flashdev-riot/RIOT/tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.1713439428.bin
### Flashing Target ###
### Flashing bin file at base address 0x0 with offset 0x81000 ###
SEGGER J-Link Commander V7.96e (Compiled Apr 17 2024 16:28:22)
DLL version V7.96e, compiled Apr 17 2024 16:27:56

J-Link Commander will now exit on Error

J-Link Command File read successfully.
Processing script file...
J-Link>loadbin /home/chris/flashdev-riot/RIOT/tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.1713439428.bin 0x00081000
J-Link connection not established yet but required for command.
Connecting to J-Link via USB...O.K.
Firmware: J-Link OB-nRF5340-NordicSemi compiled Apr 11 2024 17:44:26
Hardware version: V1.00
J-Link uptime (since boot): 0d 00h 30m 48s
S/N: 1050208458
License(s): RDI, FlashBP, FlashDL, JFlash, GDB
USB speed mode: Full speed (12 MBit/s)
VTref=3.300V
Target connection not established yet but required for command.
Device "NRF52840_XXAA" selected.

Connecting to target via SWD
InitTarget() start
InitTarget() end - Took 2.01ms
Found SW-DP with ID 0x2BA01477
DPIDR: 0x2BA01477
CoreSight SoC-400 or earlier
Scanning AP map to find all available APs
AP[2]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x24770011)
AP[1]: JTAG-AP (IDR: 0x02880000)
Iterating through AP map to find AHB-AP to use
AP[0]: Core found
AP[0]: AHB-AP ROM base: 0xE00FF000
CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)
Found Cortex-M4 r0p1, Little endian.
FPUnit: 6 code (BP) slots and 2 literal slots
CoreSight components:
ROMTbl[0] @ E00FF000
[0][0]: E000E000 CID B105E00D PID 000BB00C SCS-M7
[0][1]: E0001000 CID B105E00D PID 003BB002 DWT
[0][2]: E0002000 CID B105E00D PID 002BB003 FPB
[0][3]: E0000000 CID B105E00D PID 003BB001 ITM
[0][4]: E0040000 CID B105900D PID 000BB9A1 TPIU
[0][5]: E0041000 CID B105900D PID 000BB925 ETM
Memory zones:
  Zone: "Default" Description: Default access mode
Cortex-M4 identified.
'loadbin': Performing implicit reset & halt of MCU.
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
Downloading file [/home/chris/flashdev-riot/RIOT/tests/riotboot/bin/nrf52840dk/riotboot_files/slot1.1713439428.bin]...
Comparing flash   [100%] Done.
Erasing flash     [100%] Done.
Programming flash [100%] Done.
J-Link: Flash download: Bank 0 @ 0x00000000: 1 range affected (4096 bytes)
J-Link: Flash download: Total: 0.231s (Prepare: 0.048s, Compare: 0.016s, Erase: 0.084s, Program & Verify: 0.052s, Restore: 0.029s)
J-Link: Flash download: Program & Verify speed: 76 KB/s
O.K.
J-Link>r
Reset delay: 0 ms
Reset type NORMAL: Resets core & peripherals via SYSRESETREQ & VECTRESET bit.
Reset: Halt core after reset via DEMCR.VC_CORERESET.
Reset: Reset device via AIRCR.SYSRESETREQ.
J-Link>g
Memory map 'after startup completion point' is active
J-Link>exit

Script processing completed.

make: Verzeichnis „/home/chris/flashdev-riot/RIOT/tests/riotboot“ wird verlassen

So... what's the takeaway from this? I guess the consequence is that we have to add "JLINK_DEVICE=nrf52840_xxaa" to the Makefile.include files of boards/nrf52840dk (and possibly others? I know the MDK stuff does not use JLinks and neither does the original nRF52840 Dongle). The question is whether we should delete the JLINK_DEVICE declaration from the common Makefile.include and add it explicitly to every nRF52 board or should we keep it as an implicit declaration and only add it to the boards that do not have the nRF52832 chip. I think the latter solution is worse, because Segger does not specify which chip they mean with "nrf52", so the nRF52832 was just my assumption, as it is the chip on the "nRF52-DK".

@maribu should I prepare a PR with the proposed changes? What do you think about which solution we should choose?

crasbe commented 5 months ago

Okay, I tried some things out and removing the JLINK_DEVICE variable from the boards/common/nrf52/Makefile.include and setting it in the boards/nrf52840dk/Makefile.include works fine. Leaving the variable in place and setting it in the boards/nrf52840dk/Makefile.include does not work, because the last line is always the include for the common Makefiles.

Unfortunately setting JLINK_DEVICE = CPU_MODEL does not work and will open the JLink Target Selection Dialog, because it complains about "NRF52840XXAA" being unknown. The underscore is important for the JLinkExe, so it has to be "JLINK_DEVICE = NRF52840_XXAA".

The changes only affect the nRF52DK, nRF52840DK and apparently the Ruuvitag boards, everything else does not use the JLink and the boards/common/nrf52/Makefile.include. The MDK, Feather and Dongle boards all use USB bootloaders.

I'll prepare a PR shortly to resolve this issue.

Edit: I was wrong, more nRF52 boards use the JLink: https://github.com/search?q=repo%3ARIOT-OS%2FRIOT+include+%24%28RIOTBOARD%29%2Fcommon%2Fnrf52%2FMakefile.include&type=code

Edit2: The full list of nRF52 boards using the JLink programmer: