IN APP DFU flash writes/erases timing out

Product info:

  • NRF52840
  • nRF5_SDK_17.1.0_ddde560
  • s140_nrf52_7.3.0_softdevice

I am working on a product with a NRF52840 and SDK 17.1.0 and a cell modem.  This product needs the ability to update firmware over-the-air (using cell) or over BLE.  I have a working in app DFU module that utilizes the SDK IN_APP_DFU option to allow me to download a new Nordic image and write it to application bank 1 while the app is running.

This has been working well but occasionally I see the in app DFU hash validation fail once the entire image has been downloaded to flash.  I found this odd as I CRC check each piece of data that is being handed to the NRF DFU module to ensure it's valid.

I dug into this a little deeper and found that occasionally I see FStorage (SD based) erases and writes encounter a timeout failure (example logs below):

00> [220809 21:53:42.606 2m e nrf_dfu_flash] Flash erase failed (0xD): addr=0x000B3000, len=0x1 bytes, pending 1
00> [220809 21:53:49.806 2m e nrf_dfu_flash] Flash write failed (0xD): addr=0x000B3000, len=0x5B4 bytes, pending 0

I have a few questions related to this:
1. I noticed that when the flash operation fails, that failure is not reported back to the top level DFU module.  The `nrf_dfu_flash` module does have call the `nrf_dfu_flash_callback_t` when the operation is complete, but it only provides a pointer to the data..not a status code.  Is there some other way to get the flash operation status from my app level DFU module...if not, how can I guarantee that the flash operation succeeded?

2. Related to item #1...I have also seen the following log messages:

00> [220809 21:52:25.499 44s e nrf_dfu_flash] Flash erase failed (0xD): addr=0x000FF000, len=0x1 bytes, pending 3
00> [220809 21:52:25.709 44s e nrf_dfu_flash] Flash write success: addr=0x000FF000, pending 2
00> [220809 21:52:26.371 45s e pwr_mgmt] CPU Usage: 0%
00> [220809 21:52:26.824 45s e nrf_dfu_flash] Flash erase success: addr=0x000AD000, pending 1
00> [220809 21:52:26.840 45s e nrf_dfu_flash] Flash write success: addr=0x000AD000, pending 0


The above logs imply that the flash erase failed but nrf_dfu_flash still attempted to write anyway....that seems problematic to me as writing to an unerased flash page would almost certainly corrupt the written data.

3. I saw this option in the SDK config:

// <o> NRF_FSTORAGE_SD_MAX_RETRIES - Maximum number of attempts at executing an operation when the SoftDevice is busy 
// <i> Increase this value if events frequently return the @ref NRF_ERROR_TIMEOUT error.
// <i> The SoftDevice might fail to schedule flash access due to high BLE activity.

#ifndef NRF_FSTORAGE_SD_MAX_RETRIES
#define NRF_FSTORAGE_SD_MAX_RETRIES 8
#endif

which I haven't tried to modify yet.  I'm wondering if this is my best bet as far as getting the occasional flash failures to succeed?  Can you provide any guidance on how much to increase the MAX_RETRIES config value?

It's worth calling out that I have only seen the flash write/erase failures when the soft device is doing a lot of BLE activity (scanning, connecting and transferring data) but I think the chip should be able to coordinate that and flash operations.

Thanks!

Related