This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

DFU image offset recovery

I want to recover DFU over BLE upon a dropped connection while in the middle of an update.

I have my own software that I've cooked up to program from another NRF52 chip and I've tested with nrfutil the following scenarios:

  • Start secure DFU, force-stop host program so that target times out due to inactivity and re-advertises as 'DfuTarg'
  • Start secure DFU, unplug power to DFU target

In both scenarios, I am able to read offset and crc of the init packet that was sent before above events, skip re-sending the init packet, and jump right into sending image packets.

However, I am unable to read my last image offset from before these events and recover from that point, which is what I want to do so that I spend less time re-sending packets when dropped connections can occur.

I would post some of my code, but I am unable to recover even when using nrfutil application that has code showing a recovery method that doesn't seem to work either...

        def try_to_recover():
            if response['offset'] == 0:
                # Nothing to recover
                return

            expected_crc = binascii.crc32(firmware[:response['offset']]) & 0xFFFFFFFF
            remainder    = response['offset'] % response['max_size']

            if expected_crc != response['crc']:
                # Invalid CRC. Remove corrupted data.
                response['offset'] -= remainder if remainder != 0 else response['max_size']
                response['crc']     = binascii.crc32(firmware[:response['offset']]) & 0xFFFFFFFF
                return

            if (remainder != 0) and (response['offset'] != len(firmware)):
                # Send rest of the page.
                try:
                    to_send             = firmware[response['offset'] : response['offset'] + response['max_size'] - remainder]
                    response['crc']     = self.__stream_data(data   = to_send,
                                                             crc    = response['crc'],
                                                             offset = response['offset'])
                    response['offset'] += len(to_send)
                except ValidationException:
                    # Remove corrupted data.
                    response['offset'] -= remainder
                    response['crc']     = binascii.crc32(firmware[:response['offset']]) & 0xFFFFFFFF
                    return

            self.__execute()
            self._send_event(event_type=DfuEvent.PROGRESS_EVENT, progress=response['offset'])

  • Hi,

    However, I am unable to read my last image offset from before these events and recover from that point, which is what I want to do so that I spend less time re-sending packets when dropped connections can occur.

    I would post some of my code, but I am unable to recover even when using nrfutil application that has code showing a recovery method that doesn't seem to work either...

    As you also see this with nrfutil I assume we can hold your DFU master implementation out of the equation for now. Did you check with nRF Connect for iOS or Android also? Those also supports continuing in the middle of an update instead of starting from the scratch. If this fails also there it would be interesting to know about your bootloader. Which SDK version do you use, and which modifications have you done to the bootloader?

  • I've went back to the DFU test image software (secure/bondless/nrf52832 from v17.0.2 nrf5 sdk), and was unable to recover from last offset before a disconnection event. Again, it seems the init packet stayed in memory and was able to recover what was already transmitted but the image offset still responded back as 0...

    Where I forced disconnect...

    2022-04-04 08:42:24,087 | nordicsemi.dfu.dfu_transport_ble:626 |  DEBUG: BLE: Object selected: max_size:4096 offset:0 crc:0
    2022-04-04 08:42:24,201 | nordicsemi.dfu.dfu_transport_ble:636 |  DEBUG: BLE: Streaming Data: len:4096 offset:0 crc:0x00000000
      [------------------------------------]    2%  00:11:462022-04-04 08:42:27,081 | nordicsemi.dfu.dfu_transport_ble:636 |  DEBUG: BLE: Streaming Data: len:4096 offset:4096 crc:0xC512DFBB
      [#-----------------------------------]    5%  00:08:592022-04-04 08:42:29,991 | nordicsemi.dfu.dfu_transport_ble:636 |  DEBUG: BLE: Streaming Data: len:4096 offset:8192 crc:0x3F11680D
      [##----------------------------------]    8%  00:07:252022-04-04 08:42:32,871 | nordicsemi.dfu.dfu_transport_ble:636 |  DEBUG: BLE: Streaming Data: len:4096 offset:12288 crc:0xFBDB4B41
      [###---------------------------------]   10%  00:06:222022-04-04 08:42:35,751 | nordicsemi.dfu.dfu_transport_ble:636 |  DEBUG: BLE: Streaming Data: len:4096 offset:16384 crc:0x6A13CD4B
      [####--------------------------------]   13%  00:05:352022-04-04 08:42:38,661 | nordicsemi.dfu.dfu_transport_ble:636 |  DEBUG: BLE: Streaming Data: len:4096 offset:20480 crc:0xDF895DEC
      [#####-------------------------------]   16%  00:05:002022-04-04 08:42:41,541 | nordicsemi.dfu.dfu_transport_ble:636 |  DEBUG: BLE: Streaming Data: len:4096 offset:24576 crc:0xC1CFC488

    Where i tried to reconnect and re-transmit...

    2022-04-04 08:45:59,479 | nordicsemi.dfu.dfu_transport_ble:626 |  DEBUG: BLE: Object selected: max_size:512 offset:148 crc:3907975341
    2022-04-04 08:45:59,565 | nordicsemi.dfu.dfu_transport_ble:621 |  DEBUG: BLE: Selecting Object: type:2
    2022-04-04 08:45:59,732 | nordicsemi.dfu.dfu_transport_ble:626 |  DEBUG: BLE: Object selected: max_size:4096 offset:0 crc:0
    2022-04-04 08:45:59,833 | nordicsemi.dfu.dfu_transport_ble:636 |  DEBUG: BLE: Streaming Data: len:4096 offset:0 crc:0x00000000
      [------------------------------------]    2%  00:08:112022-04-04 08:46:02,713 | nordicsemi.dfu.dfu_transport_ble:636 |  DEBUG: BLE: Streaming Data: len:4096 offset:4096 crc:0xC512DFBB
      [#-----------------------------------]    5%  00:06:232022-04-04 08:46:05,653 | nordicsemi.dfu.dfu_transport_ble:636 |  DEBUG: BLE: Streaming Data: len:4096 offset:8192 crc:0x3F11680D

    Thanks for the help with this...

  • Hello,

    Einar is Out of Office, so I will look at your questions.

    What SDK version is the nRF Bootloader that is programmed onto the nRF from? In the sdk_config.h file from that bootloader, do you see something like NRF_DFU_SAVE_PROGRESS_IN_FLASH? (that is what it is called in SDK 17.1.0). You need to enable this by setting that parameter to 1 for it to store the progress over resets.

    Best regards,

    Edvin

Related