openthread / ot-nrf528xx

OpenThread on Nordic nRF528xx examples.
https://openthread.io/
BSD 3-Clause "New" or "Revised" License
65 stars 59 forks source link

nRF52840 DK: -DOT_BOOTLOADER=USB produces non-bootable image #867

Closed sjlongland closed 2 months ago

sjlongland commented 2 months ago

Hi, I'm busy dusting off the Fanstel port I did quite some time back, and noticed that my code would not boot if I built it with -DOT_BOOTLOADER=USB as is normal practice. If I omitted this flag, I could run the OpenThread firmware as normal, but not flash the device by any means other than JTAG.

We're using these devices as RCPs, but I suspect the same issue applies to NCP and CLI builds as well.

I've grabbed a standard Nordic dev board, nRF52840 DK (PCA10056), and tried building the current ot-nrf528xx both with and without -DOT_BOOTLOADER=USB.

commit 5a4790347edddb4da95c0894fa6b4c0bafa2d66d (HEAD -> upstream/master, origin/upstream/master, origin/develop, develop)
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Mon Aug 12 09:51:02 2024 -0700

    submodule: bump openthread from `6771761` to `df757ba` (#864)

    Bumps [openthread](https://github.com/openthread/openthread) from `6771761` to `df757ba`.
    - [Commits](https://github.com/openthread/openthread/compare/67717618b79d609561b5485bd73a273fde2db547...df757ba0cf3405e5d36538f3c774500a08ff366e)

    ---
    updated-dependencies:
    - dependency-name: openthread
      dependency-type: direct:production
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

Compiler information

$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (Arm GNU Toolchain 12.2.Rel1 (Build arm-12.24)) 12.2.1 20221205
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Hardware set-up:

P1050856

Building with USB boot-loader enabled:

Command: ./script/build nrf52840 USB_trans -DOT_BOOTLOADER=USB

⇒ firmware image loads (via nRF Connect) but then on reset, the MCU fails to enumerate as a USB device

Building without a boot-loader

Command: ./script/build nrf52840 USB_trans ⇒ firmware image loads, and a new CDC-ACM device appears

Kernel logs observed on reset:

Aug 15 16:01:20 LPA075 kernel: [23975.752812] usb 3-6.4: new full-speed USB device number 65 using xhci_hcd
Aug 15 16:01:20 LPA075 kernel: [23975.975426] usb 3-6.4: New USB device found, idVendor=1915, idProduct=cafe, bcdDevice= 1.00
Aug 15 16:01:20 LPA075 kernel: [23975.975445] usb 3-6.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Aug 15 16:01:20 LPA075 kernel: [23975.975448] usb 3-6.4: Product: nRF528xx OpenThread Device
Aug 15 16:01:20 LPA075 kernel: [23975.975452] usb 3-6.4: Manufacturer: Nordic Semiconductor
Aug 15 16:01:20 LPA075 kernel: [23975.975454] usb 3-6.4: SerialNumber: F40D69648880
Aug 15 16:01:20 LPA075 kernel: [23975.978857] cdc_acm 3-6.4:1.0: ttyACM1: USB ACM device

Not quite sure what I'm doing wrong, but it seems there's a step missing that wasn't needed before.

LuDuda commented 2 months ago

Hello,

If I understand correctly, what you described is expected behavior.

The OT_BOOTLOADER flag simply instructs the linker where to place the application. The NRF52840 DK does not have a bootloader flashed, so the application does not boot. This option was primarily created for the nRF52840 Dongle, which has a USB bootloader flashed in the factory. If you want to run it on the DK, it is certainly possible, but you need to build and flash the USB bootloader first from our legacy nRF5 SDK using JTAG.

sjlongland commented 2 months ago

Right, so the OpenThread instructions do not link to any instructions for flashing a boot-loader, and reading the Nordic Semiconductor SDK docs, it isn't clear how one does so.

I expect a nRF52840 IC bought off-the-shelf is unlikely to have such a bootloader flashed into it: that is something that needs to be done after it is soldered onto a PCB. I'm in the situation of trying to get OpenThread RCP firmware onto a (third-party) nRF52840 dongle that seems to be missing its bootloader.

I'm also observing that the current OpenThread code when flashed onto some Fanstel USB840X dongles, refuses to boot. My suspicion is that the bootloader on these is an older release that is not compatible with the current OpenThread builds -- replacing this with a later release may fix the problem.

I did find a hexdump for a bootloader in amongst the SDK files, however it uses regions that overlaps with those of the OpenThread build, so they're unable to be flashed together, it's not clear what needs to change.

Is there a particular guide I should be following for an OpenThread-compatible bootloader on the nRF52840?

LuDuda commented 2 months ago

@sjlongland if you are developing a new product, please note that this repo and nRF5 SDK is in a maintenance mode. Please consider using nRF Connect SDK which has the most recent OpenThread RCP support as well. The USB Bootloader configuration for this repo was mainly to support nRF52840 Dongle which you can find in the documentation. However, i don't see any reason why the Bootloader for the nRF52840 DK might occupy different flash regions (not counting potential different configuration e.g. debug/release).

I would also recommend to create a devzone ticket to get support from our tech support team.

sjlongland commented 2 months ago

No problems, I think I found the SDK here: https://github.com/nrfconnect/sdk-nrf with docs at https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/installation/updating.html

It's the same chip in the little dongle as in the full dev board, and I think the USB pins are dedicated (can't be re-mapped) so the same code should work on both (LED and pushbutton connections being the sticking point).

I'll check those out and have a close look. It helps that I'm not digging around in the now obsolete nRF5 SDK. :-) Many thanks.

sjlongland commented 2 months ago

Right… so after a few days of tinkering, I finally got something working.

I did have a look at the nRF Connect SDK. I was able to use this to build an RCP image, and I think with some further tinkering, should be able to get a bootloader running with that, but this requires getting familiar with Zephyr OS's build system. Definitely worth doing long-term, but more than I wanted to tackle at this stage.

I will revisit this soon.

For this application, basically I needed something that was more-or-less compatible with the existing project, so stuck with the nRF5 SDK despite its maintenance status. These are the steps I followed to get a working system:

  1. Downloaded nRF5 SDK from https://www.nordicsemi.com/Products/Development-software/nRF5-SDK/Download#infotabs -- I used version 17.1.0
  2. Downloaded and installed the CLI tools from https://www.nordicsemi.com/Products/Development-tools/nRF-Command-Line-Tools/Download
  3. Installed the ARM GNU toolchain (v12 works, with some warnings generated)
  4. Modified components/toolchain/gcc/Makefile.posix with my toolchain's location
  5. Entered the examples/dfu/open_bootloader/pca10059_usb/armgcc directory (or any of the others, in my case the PCA10059 is the closest to the Fanstel USB840X, but one could also use pca10056_usb instead)
  6. Added -Wno-error=array-bounds (look for -Werror) to CFLAGS in the Makefile
  7. Updated examples/dfu/dfu_public_key.c with the public key being used (Fanstel publish this in their documentation, you can just use the existing one and remove the #ifdef/#endif instead… or replace it with yours).
  8. Ran make; the file _build/nrf52840_xxaa.hex was generated
  9. Ran /opt/nrf-command-line-tools/bin/mergehex -o bootloader.hex -m _build/nrf52840_xxaa.hex ../../../../../components/softdevice/s140/hex/s140_nrf52_7.2.0_softdevice.hex to produce the final bootloader.hex

Then I could flash bootloader.hex via the nRF52840 DK to my target. I was also (by accident) able to flash the nRF52840 with this firmware and have it work.

On reset, the MCU will blink a LED, much like the PCA10059 boards do, and the nRF Connect programmer will let you upload .hex files as required. The ot-rcp image generated with -DOT_BOOTLOADER=USB works once loaded via nRF Connect.

So in short, the above is where one can get a compatible boot-loader and load it to get something working quickly. nRF Connect SDK offers a much better option using MCUBoot at the cost of a steeper learning curve, but if all you need is a USB-updateable RCP dongle, this will get people there with minimal fuss.