This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

USB-Serial DFU to nRF52840 on nRF91 DK Board

Hello, thank you for taking time to review this.

I am trying to setup a serial DFU setup for the nRF52 on the nRF91 DK board. I am running into problems getting it to work and understanding it in general.
I looked at several pages trying to help myself understand it
1) https://docs.zephyrproject.org/1.12.0/samples/subsys/usb/dfu/README.html
2) https://docs.zephyrproject.org/1.13.0/devices/dts/flash_partitions.html
3) https://mcuboot.com/mcuboot/readme-zephyr.html
4) https://docs.zephyrproject.org/1.12.0/samples/subsys/mgmt/mcumgr/smp_svr/README.html
5) https://github.com/apache/mynewt-mcumgr-cli
    As well as the links on these pages

I have tried several processes, but for the sake of conversation I will explain my most recent approach.

I compiled the MCUbootloader:
-in mcuboot/boot/zephyr/build

1) cmake -GNinja -DBOARD=nrf52840_pca10090 ..
2) ninja
3) ninja flash

Once I have flashed the bootloader
-in /zephyr/samples/bluetooth/beacon/build
1) cmake -GNinja -DBOARD=nrf52840_pca10090 ..
2) ninja
3) ~/<path/to/source>/ncs/mcuboot/scripts/imgtool.py sign \
--key ~/<path/to/source>/ncs/mcuboot/root-rsa-2048.pem \
--header-size 0x200 \
--align 8 \
--version 1.0 \
--slot-size 0x69000 --pad-header \
./zephyr/zephyr.hex b_signed.hex

After both are completed:
-in above build dir
1) nrfjprog --program b_signed.hex

Error:
Parsing hex file.
Reading flash area to program to guarantee it is erased.
ERROR: The area to write is not erased.

Notes:
I have tried signing the bootloader and loading at 0xC000
I have tried adding CONFIG_BOOTLOADER_MCUBOOT=y to the beacon prj.conf

I am just having trouble putting this all together and understanding how it all works and how to do it. My goal is to load some project like bluetooth/beacon, then use a serial DFU to change the project image to like the hello_world example and have it load into slot1, then switch it to slot0 after verification and then load hellow_world on reset/boot.

Thanks for your help

  • Also tried downloading a signed at 0x69000 .bin of a file with dfu-util
    --from example (dfu-util --alt 1 --download signed-hello.bin)

    dfu-util: Invalid DFU suffix signature
    dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
    Deducing device DFU version from functional descriptor length
    Opening DFU capable USB device...
    ID 05ac:821d
    Run-time device DFU version 0100
    Claiming USB DFU Runtime Interface...
    Determining device status: state = appIDLE, status = 0
    Device really in Runtime Mode, send DFU detach request...
    Resetting USB...
    Deducing device DFU version from functional descriptor length
    dfu-util: Lost device after RESET?

    And when attempting to move a signed image via mcumgr I get:

    Error: NMP timeout

  • UPDATE

    So I moved to just using cmake and noticed in the Makefile a menuconfig option existed. So I explored that and saw I could specify the offset I wanted the image to be loaded at here. I could do the same for the bootloader. I set the bootloader to not verify the image on boot (just to simplify for now) and then flashed it, an of course it prints
            ***** Booting Zephyr OS v1.13.99-ncs2 *****
    on boot. I then configured the offset on the hello_world image for slot0_partition. When I have CONFIG_BOOTLOADER_MCUBOOT enabled it acts like only the bootloader image exists, and prints the same thing. If I disable CONFIG_BOOTLOADER_MCUBOOT then it prints out my custom bootloader message and my example image. This makes me think that maybe I am uploading the image and the bootloader to the offset which would explain why it doesn't change its boot behavior when CONFIG_BOOTLOADER_MCUBOOT is enabled, because slot0 would have the new bootloader image and the application image in it. I could obviously be wrong. I also tried uploading signed both ways and got the same results as the unsigned method. I am still just trying to pass in an original image, have it execute that, then once that works pass in an image to slot1 and have it swap to that.

  • Hi,

    Did you build and flash the smp_svr, with pr.conf CONFIG_MCUMGR_SMP_UART=y ?

    And when attempting to move a signed image via mcumgr I get:

    What command did you use ? Something like this?

    sudo mcumgr -t 60 --conntype serial --connstring='dev=/dev/ttyACM0,
    baud=115200' image upload signed.bin

    3) ~/<path/to/source>/ncs/mcuboot/scripts/imgtool.py sign \
    --key ~/<path/to/source>/ncs/mcuboot/root-rsa-2048.pem \
    --header-size 0x200 \
    --align 8 \
    --version 1.0 \
    --slot-size 0x69000 --pad-header \
    ./zephyr/zephyr.hex b_signed.hex

    The mcumgr cli might only work with bin-files, so try zephyr/zephyr.bin signed.bin instead.

    Are you able to do a image list?

    sudo mcumgr -t 60 --conntype serial --connstring='dev=/dev/ttyACM0,
    baud=115200' image list

    It should give an output similar to this before the DFU is performed:

    Images:
    slot=0
    version: 1.0.0
    bootable: true
    flags: active confirmed
    hash:
    b7c2f11913e061639f8c78e2b92de2867670841ed1b8386264cfb118dd5e611c
    Split status: N/A (0)

    And after the DFU, you should be able to see images in both slot 0 and slot 1.

    In order to instruct MCUboot to swap the images we need to test the image first, making sure it boots:

    sudo mcumgr -t 60 --conntype serial --connstring='dev=/dev/ttyACM0,
    baud=115200' image test
    6869bd755d54c82c14bc1c2d19e566ceb227307c0703bc87e0a91ace87ec5e42

    Replace the hash at the end of the command with the correct one given in the output from the image list command. You can now run the newly uploaded image by performing a soft reset of the board:

    sudo mcumgr -t 60 --conntype serial --connstring='dev=/dev/ttyACM0,
    baud=115200' reset

  • Thank you for this, I appreciate it.

    I can get the image of whatever sample (currently hello world) to load into slot-1, but then it always stays in "pending" as a flag after a test is issued, even though I issue a reset afterwards. I loaded the signed image, issued a list, saw a flag of nothing, used the hash form the list with the test command, saw a flag of pending, then issued a reset command. The original program loaded and when I did a list again it stayed as status pending.

    Also it lists nothing at all for slot0 even though smp_svr is running on it

Related