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

DFU Bootloader fails to correctly allocate memory for SoftDevice update

Hello,

My team and I are experiencing a problem with our custom DFU Bootloader, which is based on the Experimental Bootloader Secure Serial example (SDK 13), running in a custom NRF52832 board. Our main app uses a single bank, and we're also using the S132 v4 SoftDevice, our custom Bootloader and Bootloader settings.

The whole flash process seems to work fine, whether we update the Application, the SoftDevice or the Bootloader itself. However, when our boards are flashed with an application using almost all the flash space allocated to the application, problems occur when attempting to update the Bootloader or the SoftDevice using our custom Bootloader.

When our app uses more than 307200 bytes, leaving only about 3 pages of unused space, the function nrf_dfu_find_cache() fails to safely allocate space for the temporary swap space required by the update process, leading to the write operations overwriting the Bootloader region that is executing the DFU requests. This causes the Bootloader itself to become corrupt and the system hangs (only recovers after a re-flash with the programmer).

We are wondering if this is a known problem with SDK 13 and if there is a solution to the problem. (As a workaround, we're currently limiting our application size in the linker so that it fails to compile if grows beyond the aforementioned size.)

Thank you for your attention to this matter, please let me know if we are required to provide more details regarding this issue, TC

  • Hi Tiago,

    Could you step into nrf_dfu_find_cache() and let me know what exactly failed inside the function ? Note that if you setup some data page as reserved application data space (for example bond information ) it will affect the maximum swap area can be used. Please check the value of DFU_REGION_TOTAL_SIZE, DFU_APP_DATA_RESERVED etc

  • Hi Hung,

    Sorry for the late reply, I have been assigned to other tasks and could not follow up with this issue until now. Meanwhile, I have also identified another problem, in which the bootloader rejects an upgrade with nrf_dfu_res_code_t = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES. This occurs when I attempt to flash an application of size 307756 bytes, even when I have a reserved flash size of 319488 bytes for the application. Here are my flash regions' definitions:

    FLASH (rx) : ORIGIN = 0x6D000, LENGTH = 0x11000 (in the Bootloader's linker settings)

    FLASH (rx) : ORIGIN = 0x1F000, LENGTH = 0x4E000 (in main application's linker settings)

    MBR_PARAMS_PAGE (rw) : ORIGIN = 0x0007E000, LENGTH = 0x1000

    BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x0007F000, LENGTH = 0x1000

  • Ok, I have determined that the failure due to insufficient resources is caused by the DFU_APP_DATA_RESERVED assignment, which reserves 3 pages on top of the application memory region for keeping device bonding information, correct?

    I also believe that the failure described by the original question is caused by trying to flash an hex file with different linker settings that the ones configured in the already running bootloader code. That somehow causes the nrf_dfu_find_cache() to return wrong values.

  • However, I have came across another problem: when I limit the size of my app to 0x4A000 bytes in the linker settings, the hexs generated by nrfutil are slightly larger than that (say, 0x04B164). I believe the larger size is due to metadata being inserted in the hex, but this causes the bootloader to reject that hex due to insufficient resources. Is this behavior normal? Why is the hex rejected if the linker settings limited the size of the app to precisely the space available for the app? I have looked into it and found out that DFU_REGION_TOTAL_SIZE - DFU_APP_DATA_RESERVED = 0x4A000 as expected.

  • The application's linker size you set would have nothing to do with the bootloader. The bootloader only looks at the size of the application provided by the init packet which base on the binary image. So it's a normal behaviour.

    The bootloader is not a black box, you can always set a break point and step the code (change optimization level to 0) to see why you get an error.

Related