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:
- 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). - 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. - 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?