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

Detecting DFU upgrade

This is really a question about best practice - I have some ideas of ways to do what I want, but wonder if there is some clean API-supported method that I haven't found...

I'm implementing DFU over BLE, and I want my application to "know" that it's been upgraded.

This is necessary because:

  • the firmware logs to internal flash (I'm using a nRF52840) - directly, not using FDS
  • therefore there is not enough "unused" flash to support dual-bank upgrades
  • I don't want to give my users the potentially bad, and risky, experience of a failed single-bank upgrade
    (yes, "in theory" an upgrade in place is safe enough, but still...)

That means that I'll need to blow away the logged data to give DFU enough space to have two banks to play with.  Or, more accurately, I'll only make NRF_DFU_APP_DATA_AREA_SIZE big enough to retain my application's persistent configuration (and bonds), but not the log area.

Ok, so when the application starts, it needs to know whether the DFU process has overwritten it's log storage area.

Some ideas:

  1. Compare running firmware version with the last stored version, if different then an upgrade occurred.
    However, what if an upgrade failed?  Logs could still have been overwritten, before the DFU process fell back to the original copy (since we're using dual bank for safety).
  2. Validate log storage integrity on every boot, and reinitialise log if it is corrupt.
    That has the big advantage of always being safe, and will pickup corruption that occurs due to other reasons (power off in the middle of a write or erase?).
    But it's time and therefore battery consuming.  On the other hand, rebooting shouldn't happen often, so maybe ok.
  3. Modify the bootloader to write a value to GPREGRET whenever DFU starts downloading into bank 1, then check it in the main application.
    That's similar to the signally used for buttonless DFU, but in the opposite direction.

Thoughts?  Anyone doing anything like this?

  • Hi David, 

    Option 1 and 2 would requires you run a relatively time consuming check every time you boot your application. 
    Option 3 may have an issue if you have a power reset before you enter the main application. 

    I would think of writing to the start address of bank 1 a magic word, 0xFEEDC0DE for example. When your application booting up, it will check for this magic word at the first address of the first page of bank 1. If it's 0xFFFFFFFF or something else not 0xFEEDC0DE , the application knows that it should reinitialize the log. It should then erase the first page in bank 1 and re-write the magic word back and continue to reinitialize the log database. 


    This should work in both case successful and unsuccessful DFU update. And it works even in case that there was a power failure when switching from bootloader to application. And you don't need to modify the bootloader. 

Related