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

How to fully erase app when using bootloader and DFU?

We are currently working on a production board where debugging is not easy. The board seems to have gotten into a state where FDS is reporting no available pages. I think it may simply be a matter of garbage collecting that was not being done but unfortunately it is not possible to initialize storage to even get to that point. I also believe FDS may be incorrectly identifying unerased pages as program data. 

Is there a way to fully reset (erase) everything beyond the bootloader so we can start from a known good state without cracking the case open?  We are using usb serial dfu. 

We have not been able to reproduce this issue on our dev boards so it is extremely hard to debug. 

Parents
  • Hi,

    Have you changed the number of allocated pages to FDS at some point? The only way for this to happen (that I know of) is if you update the app on the device with a new version with fewer pages allocated to FDS (=FDS_VIRTUAL_PAGES in sdk_config.h), and that the SWAP page happens to be outside of the new region at the time of update. SWAP is moved to a different page every time GC is run, which might explain why it's difficult to replicate. 

    You can dump the memory to confirm if this is why you get the "NO PAGES" error. I provided instructions on how to do that in this thread: https://devzone.nordicsemi.com/f/nordic-q-a/42676/fds_err_no_pages-returned-when-fds_init-is-called/166492#166492.  EDIT: Nevermind, sounds like you can't attach a debugger to the device. Also, I forgot to answer your question. It is possible to erase the app data region to avoid the "no page" error. You can modify the application code to erase the app data region in case FDS initialization fails, or make a new app with more pages allocated to FDS. 

  • I believe what triggered it was switching to release mode but I was confused as to why that would cause it to lose track of the swap. It’s possible I did something else but I don’t remember what it was. 

    Allocating more pages to FDS didn’t solve the problem (I should point out that we are pushing the limits of the nrf82540 and using a lot of that flash). 

    I actually ended up cracking open the case and resetting everything but one question I did have that might help me debug in the future was whether the DFU erases the existing app before writing the new one. Meaning, in the case of going from debug to release where the program size was cut in half, will FDS get to reclaim that space or will it detect those pages as unknown and assume they can’t be used?

  • Jeffrey Haynes said:
    I actually ended up cracking open the case and resetting everything but one question I did have that might help me debug in the future was whether the DFU erases the existing app before writing the new one.

    Only if the bootloader needs this area to fit the new FW image and DFU_APP_DATA_RESERVED/NRF_DFU_APP_DATA_AREA_SIZE symbol in bootloader is set to '0'. 

    FDS can reclaim pages that don't have a valid page tag. For this reason it is important to make sure that the app does not grow into the app data region. 

  • I’m not following. You say FDS can reclaim pages that don’t have a valid tag but that’s only true if they’re deleted, correct?  And it sounds like you’re saying that DFU won’t delete excess app space if the app shrinks. 

    It sounds like the answer is to only ever flash our board with a release build. However, because we can’t reclaim that space, if someone were to flash the device in debug mode, it will effectively unrecoverably corrupt the device (assuming we haven’t reserved enough FDS). 

    So - back to my original question. It would be nice if there was a mechanism via DFU/nrfprog to erase the app + FDS (non-bootloader) space. But it sounds like that is not currently possible, correct?

  • Yes, you are right, sorry. I was under the impression that FDS could reclaim flash pages if they didn't have a valid page tag, but it's only pages that have been fully erased that can be reclaimed. So I guess the problem was that the staged image (debug version) grew into the app data section, causing FDS initialization to fail on the following startup. The bootloader does not delete data in the swap area after DFU. 

    Jeffrey Haynes said:
    It sounds like the answer is to only ever flash our board with a release build. However, because we can’t reclaim that space, if someone were to flash the device in debug mode, it will effectively unrecoverably corrupt the device (assuming we haven’t reserved enough FDS). 

    I think you would have avoided this issue if NRF_DFU_APP_DATA_AREA_SIZE  was equal to FDS_VIRTUAL_PAGES, but then you would not have been able to perform a dual banked update for the debug build. 

    There is no existing mechanism in the bootloader to clean up the bank 1 area after an update. I think this mechanism would be more straightforward to add to the application code. E.g., manually erase FDS pages in case initialization fails, then do a reboot. With nrfjprog, you can use --erasepage command to manually erase the flash pages used for FDS. 

     

  • Yeah, that was my thinking too. Unfortunately after spending quite a bit of time on it I don’t think there’s a way for the application to erase those pages. The issue is that the pages aren’t tagged so the application has no more idea of which ones are valid than does the FDS subsystem. I tried various schemes to work around that but to no avail.

    I may look at adding something to the bootloader but maybe you guys could consider it as a possible future enhancement.

    Thanks

  • I will report this as a feature request internally. I was a bit surprised to see that FDS wouldn't reclaim pages used during DFU. It means that  NRF_DFU_APP_DATA_AREA_SIZE  must be equal to FDS_VIRTUAL_PAGES in the current implementation. 

    You may have seen it already, but the fds.c->flash_bounds_set() can be used to find the flash boundaries for FDS. The function is defined as static, so the module needs to be modified to expose this function to the app. It will become a bit more complicated if you have a requirement to retain valid data records instead of just deleting everything to recover the device though.  Parsing the FDS pages to find which can be freed (either erased or only containing deleted records) could be an option. 

Reply
  • I will report this as a feature request internally. I was a bit surprised to see that FDS wouldn't reclaim pages used during DFU. It means that  NRF_DFU_APP_DATA_AREA_SIZE  must be equal to FDS_VIRTUAL_PAGES in the current implementation. 

    You may have seen it already, but the fds.c->flash_bounds_set() can be used to find the flash boundaries for FDS. The function is defined as static, so the module needs to be modified to expose this function to the app. It will become a bit more complicated if you have a requirement to retain valid data records instead of just deleting everything to recover the device though.  Parsing the FDS pages to find which can be freed (either erased or only containing deleted records) could be an option. 

Children
Related