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

DFU package for targets with and without softdevice

Is it possible to generate a DFU package for both bootloader-only and fully-programmed (bootloader, softdevice, and app) chips?
I'm unable to do so for an nrf52833 using nrfutil version 6.1.0.

Here's how I generate the package:

nrfutil pkg generate \
    --hw-version 52 \
    --sd-req 0x00,0xCA \
    --sd-id 0xCA \
    --application _build/app.hex \
    --application-version-string 0.0.0 \
    --softdevice /Users/dev/Downloads/nRF5_SDK_17.0.0_9d13099/components/softdevice/s140/hex/s140_nrf52_7.0.1_softdevice.hex \
    --key-file app.pem \
    _build/app_dfu.zip

(nrfutil pkg display app_dfu.zip follows at end of post.)

This flashes fine to a bootloader-only chip.

But when I try to flash again, I get

    pc_ble_driver_py.exceptions.NordicSemiException: Extended Error 0x07: The array of supported SoftDevices for the update does not contain the FWID of the current SoftDevice.

However, the memory at 0x0000300C shows 0xffff00CA, indicating that the expected softdevice has been programmed fine.
Am I misunderstanding something?
Here is the output of nrfutil pkg display.

DFU Package: <_build/app_dfu.zip>:
|
|- Image count: 2
|
|- Image #0:
   |- Type: softdevice
   |- Image file: s140_nrf52_7.0.1_softdevice.bin
   |- Init packet file: s140_nrf52_7.0.1_softdevice.dat
      |
      |- op_code: INIT
      |- signature_type: ECDSA_P256_SHA256
      |- signature (little-endian): b'f420bf315bc80e8f4d8c1ef77239588d758949fd8e87c0f785e5b1f5805ad58567a0122ecf2cef74d7d5455d520553d89bf24f246990b0cf4a52d07f35f5d7f9'
      |
      |- fw_version: 0xFFFFFFFF (4294967295)
      |- hw_version 0x00000034 (52)
      |- sd_req: 0x00, 0xCA
      |- type: SOFTDEVICE
      |- sd_size: 152984
      |- bl_size: 0
      |- app_size: 0
      |
      |- hash_type: SHA256
      |- hash (little-endian): b'b48b4dc06490f8e1d5fad5804b1718c47487ba463a5325cfb8dcb8b460ee9f93'
      |
      |- boot_validation_type: ['VALIDATE_GENERATED_CRC']
      |- boot_validation_signature (little-endian): [b'']
      |
      |- is_debug: False

|
|- Image #1:
   |- Type: application
   |- Image file: app.bin
   |- Init packet file: app.dat
      |
      |- op_code: INIT
      |- signature_type: ECDSA_P256_SHA256
      |- signature (little-endian): b'39b73aba0b5414408a55b74114a9f4a7f1f4a49e2bfc92439a0bcef5c10f0515522a57ee3a026a5af00f90cb443d3cdaf65bdc66b658897f02643bb4d4dc3226'
      |
      |- fw_version: 0x00000000 (0)
      |- hw_version 0x00000034 (52)
      |- sd_req: 0xCA
      |- type: APPLICATION
      |- sd_size: 0
      |- bl_size: 0
      |- app_size: 86924
      |
      |- hash_type: SHA256
      |- hash (little-endian): b'58c0dff1f5c10bd17478b9f776d59daaac9177ad3f174f98f2dd894dd7ade1da'
      |
      |- boot_validation_type: ['VALIDATE_GENERATED_CRC']
      |- boot_validation_signature (little-endian): [b'']
      |
      |- is_debug: False

Parents
  • Hi,

    I do not make sense of the error, since the SoftDevice ID should be correct. However, you must make sure that either the application and bootloader version is increasing (a higher number than already present on the device). For the application, you could also configure the bootloader to accept the same version by setting NRF_DFU_APP_ACCEPT_SAME_VERSION to 1 in the bootloader's sdk_config.h, but the bootloader version must be higher every time. But again, I do not see a link between this and the error you get, and I have not been able to reproduce it.

    Can you reproduce this and upload all the relevant files here to that I can test on my side as well? Please describe each step of the process so that I do not miss anything.

  • Thanks for your help Einar!

    the bootloader version must be higher every time

    I'm not sure what you mean here --- isn't the bootloader staying the same? The DFU update should only update the app and softdevice.

    Glad to know that this is expected to work. Is there a way to upload files privately? I can send you the bootloader and app hex files for testing, but they should not be public.

    Here are steps to reproduce.

    ## Erase Chip

    openocd -f openocd.cfg -c "init; reset halt; nrf5 mass_erase"

    openocd.cfg contains

        source [find interface/stlink.cfg]
        transport select hla_swd
        source [find target/nrf52.cfg]

    Version: Open On-Chip Debugger 0.10.0+dev-01293-g7c88e76a (2020-06-28-19:39)


    ## Build + Flash bootloader

    Build secure_bootloader_usb_mbr_pca10100e example using GCC.
    (Note: this example already has `#define NRF_DFU_APP_ACCEPT_SAME_VERSION 1`.)
    Then combine with MBR

        mergehex --merge \
        bootloader/_build/bootloader.hex \
        $(SDK_ROOT)/components/softdevice/mbr/hex/mbr_nrf52_2.4.1_mbr.hex \
        --output bootloader/_build/bootloader_mbr.hex

    Then flash:

        openocd -f openocd.cfg -c "program bootloader/_build/bootloader_mbr.hex verify reset exit"


    ## Flash softdevice and app via DFU

    nrfutil pkg generate \
        --hw-version 52 \
        --sd-req 0x00,0xCA \
        --sd-id 0xCA \
        --application _build/app.hex \
        --application-version-string 0.0.0 \
        --softdevice /Users/dev/Downloads/nRF5_SDK_17.0.0_9d13099/components/softdevice/s140/hex/s140_nrf52_7.0.1_softdevice.hex \
        --key-file app.pem \
        _build/app_dfu.zip

    nrfutil dfu usb-serial -p /dev/tty.usb* --package _build/app_dfu.zip

    This works fine the first time.
    App starts up fine as expected, and I initiate a reset into DFU mode through the app.

    Then when I run

    nrfutil dfu usb-serial -p /dev/tty.usb* --package _build/app_dfu.zip

    again, I get the error:

    pc_ble_driver_py.exceptions.NordicSemiException: Extended Error 0x07: The array of supported SoftDevices for the update does not contain the FWID of the current SoftDevice.

  • Hi,

    lynaghk said:
    Here are steps to reproduce.

    Thank you. I followed this using unmodified SDK examples and reproduced it on my side  using the nRF52840 DK and unmodified SDK examples. For reference:

    SDK 17.0.0 secure USB bootlaoder (non-standard public key): secure_bootloader_usb_mbr_pca10056_debug.hex

    MBR: mbr_nrf52_2.4.1_mbr.hex

    Application (unmodified SDK 17 HRS example): ble_app_hrs_pca10056_s140.hex

    SoftDevice: s140_nrf52_7.0.1_softdevice.hex 

    DFU zip generated like this (same as you did, using my key file): app_dfu.zip

    nrfutil dfu usb-serial -p /dev/tty.usb* --package _build/app_dfu.zip

    Then erase, program bootloader + MBR, DFU update, reset to DFU mode via button press, and run DFU again in this sequence:

    >nrfjprog.exe -e
    Erasing user available code and UICR flash areas.
    Applying system reset.
    
    >nrfjprog.exe --program mbr_nrf52_2.4.1_mbr.hex
    Parsing hex file.
    Reading flash area to program to guarantee it is erased.
    Checking that the area to write is not protected.
    Programming device.
    
    >nrfjprog.exe --program secure_bootloader_usb_mbr_pca10056_debug.hex
    Parsing hex file.
    Reading flash area to program to guarantee it is erased.
    Checking that the area to write is not protected.
    Programming device.
    
    >nrfjprog.exe --reset
    Applying system reset.
    Run.
    
    >nrfutil dfu usb-serial -p COM60 --package app_dfu.zip
      [####################################]  100%
    Device programmed.
    
    >nrfutil dfu usb-serial -p COM60 --package app_dfu.zip
    
    Traceback (most recent call last):
      File "c:\python37\lib\runpy.py", line 193, in _run_module_as_main
        "__main__", mod_spec)
      File "c:\python37\lib\runpy.py", line 85, in _run_code
        exec(code, run_globals)
      File "C:\Python37\Scripts\nrfutil.exe\__main__.py", line 7, in <module>
      File "c:\python37\lib\site-packages\click\core.py", line 764, in __call__
        return self.main(*args, **kwargs)
      File "c:\python37\lib\site-packages\click\core.py", line 717, in main
        rv = self.invoke(ctx)
      File "c:\python37\lib\site-packages\click\core.py", line 1137, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "c:\python37\lib\site-packages\click\core.py", line 1137, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "c:\python37\lib\site-packages\click\core.py", line 956, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "c:\python37\lib\site-packages\click\core.py", line 555, in invoke
        return callback(*args, **kwargs)
      File "c:\python37\lib\site-packages\nordicsemi\__main__.py", line 1015, in usb_serial
        timeout)
      File "c:\python37\lib\site-packages\nordicsemi\__main__.py", line 970, in do_serial
        dfu.dfu_send_images()
      File "c:\python37\lib\site-packages\nordicsemi\dfu\dfu.py", line 119, in dfu_send_images
        self._dfu_send_image(self.manifest.softdevice)
      File "c:\python37\lib\site-packages\nordicsemi\dfu\dfu.py", line 95, in _dfu_send_image
        self.dfu_transport.send_init_packet(data)
      File "c:\python37\lib\site-packages\nordicsemi\dfu\dfu_transport_serial.py", line 256, in send_init_packet
        self.__execute()
      File "c:\python37\lib\site-packages\nordicsemi\dfu\dfu_transport_serial.py", line 421, in __execute
        self.__get_response(DfuTransportSerial.OP_CODE['Execute'])
      File "c:\python37\lib\site-packages\nordicsemi\dfu\dfu_transport_serial.py", line 502, in __get_response
        raise NordicSemiException('Extended Error 0x{:02X}: {}'.format(resp[3], data))
    pc_ble_driver_py.exceptions.NordicSemiException: Extended Error 0x07: The array of supported SoftDevices for the update does not contain the FWID of the current SoftDevice.

     I don't understand why this is, but I will continue to look into it and get back to you.

    lynaghk said:
    I'm not sure what you mean here --- isn't the bootloader staying the same?

     Yes, you do not include the bootloader in this case. If you did, it must have had an increasing version, but it is not relevant in this case.

Reply
  • Hi,

    lynaghk said:
    Here are steps to reproduce.

    Thank you. I followed this using unmodified SDK examples and reproduced it on my side  using the nRF52840 DK and unmodified SDK examples. For reference:

    SDK 17.0.0 secure USB bootlaoder (non-standard public key): secure_bootloader_usb_mbr_pca10056_debug.hex

    MBR: mbr_nrf52_2.4.1_mbr.hex

    Application (unmodified SDK 17 HRS example): ble_app_hrs_pca10056_s140.hex

    SoftDevice: s140_nrf52_7.0.1_softdevice.hex 

    DFU zip generated like this (same as you did, using my key file): app_dfu.zip

    nrfutil dfu usb-serial -p /dev/tty.usb* --package _build/app_dfu.zip

    Then erase, program bootloader + MBR, DFU update, reset to DFU mode via button press, and run DFU again in this sequence:

    >nrfjprog.exe -e
    Erasing user available code and UICR flash areas.
    Applying system reset.
    
    >nrfjprog.exe --program mbr_nrf52_2.4.1_mbr.hex
    Parsing hex file.
    Reading flash area to program to guarantee it is erased.
    Checking that the area to write is not protected.
    Programming device.
    
    >nrfjprog.exe --program secure_bootloader_usb_mbr_pca10056_debug.hex
    Parsing hex file.
    Reading flash area to program to guarantee it is erased.
    Checking that the area to write is not protected.
    Programming device.
    
    >nrfjprog.exe --reset
    Applying system reset.
    Run.
    
    >nrfutil dfu usb-serial -p COM60 --package app_dfu.zip
      [####################################]  100%
    Device programmed.
    
    >nrfutil dfu usb-serial -p COM60 --package app_dfu.zip
    
    Traceback (most recent call last):
      File "c:\python37\lib\runpy.py", line 193, in _run_module_as_main
        "__main__", mod_spec)
      File "c:\python37\lib\runpy.py", line 85, in _run_code
        exec(code, run_globals)
      File "C:\Python37\Scripts\nrfutil.exe\__main__.py", line 7, in <module>
      File "c:\python37\lib\site-packages\click\core.py", line 764, in __call__
        return self.main(*args, **kwargs)
      File "c:\python37\lib\site-packages\click\core.py", line 717, in main
        rv = self.invoke(ctx)
      File "c:\python37\lib\site-packages\click\core.py", line 1137, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "c:\python37\lib\site-packages\click\core.py", line 1137, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "c:\python37\lib\site-packages\click\core.py", line 956, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "c:\python37\lib\site-packages\click\core.py", line 555, in invoke
        return callback(*args, **kwargs)
      File "c:\python37\lib\site-packages\nordicsemi\__main__.py", line 1015, in usb_serial
        timeout)
      File "c:\python37\lib\site-packages\nordicsemi\__main__.py", line 970, in do_serial
        dfu.dfu_send_images()
      File "c:\python37\lib\site-packages\nordicsemi\dfu\dfu.py", line 119, in dfu_send_images
        self._dfu_send_image(self.manifest.softdevice)
      File "c:\python37\lib\site-packages\nordicsemi\dfu\dfu.py", line 95, in _dfu_send_image
        self.dfu_transport.send_init_packet(data)
      File "c:\python37\lib\site-packages\nordicsemi\dfu\dfu_transport_serial.py", line 256, in send_init_packet
        self.__execute()
      File "c:\python37\lib\site-packages\nordicsemi\dfu\dfu_transport_serial.py", line 421, in __execute
        self.__get_response(DfuTransportSerial.OP_CODE['Execute'])
      File "c:\python37\lib\site-packages\nordicsemi\dfu\dfu_transport_serial.py", line 502, in __get_response
        raise NordicSemiException('Extended Error 0x{:02X}: {}'.format(resp[3], data))
    pc_ble_driver_py.exceptions.NordicSemiException: Extended Error 0x07: The array of supported SoftDevices for the update does not contain the FWID of the current SoftDevice.

     I don't understand why this is, but I will continue to look into it and get back to you.

    lynaghk said:
    I'm not sure what you mean here --- isn't the bootloader staying the same?

     Yes, you do not include the bootloader in this case. If you did, it must have had an increasing version, but it is not relevant in this case.

Children
  • Hi,

    I suspect there is a bug in the bootloader. Doing the same test with the BLE bootloader everything works as expected. However, with the USB bootloader, you get this error, which is interesting for a couple of reasons: First of all, the ID is correct. And second of all, it does not matter for the bootloader itself, as unlike the BLE bootloader, it has no dependency on the SoftDevice (it still should check compatibility between SoftDevice and application, though).

    Looking at the log from the bootloader when it fails you can see that prevalidation fails, and digging a bit further this is because of the result set on line 134 nrf_dfu_ver_validation.c. You can work around this by setting NRF_DFU_APP_DOWNGRADE_PREVENTION to 0 in the sdk_config.h of the bootloader. I will report the bug internally.

  • Great, thanks for getting to the bottom of this so quickly Einar.

Related