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'])

Parents
  • 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

Reply
  • 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

Children
No Data
Related