DFU failure when updating bootloader

Hello,

I am using the nRF51822 with SDK v9.0.0, SoftDevice S110, and the DFU bootloader v8.1.0.

For certain reasons, I want to reserve one page of the 'app data' for shared information between the application and the bootloader. To achieve this, I have reserved this page in the bootloader by setting DFU_APP_DATA_RESERVED = 0x0400 (previously it was set to 0x0). Now, I want to create an image of the new bootloader and distribute it using DFU.

I have already created the bootloader zip file using nrfutil and followed all the requirements. However, after the DFU process finishes, the bootloader is no longer starting. I tried debugging the bootloader and discovered that the dfu_bl_image_swap function is causing a HardFault_Handler.

Does anyone have any idea what might be causing this issue?

Note that if I perform the same process without reserving the 'app data' page (DFU_APP_DATA_RESERVED = 0x0), the DFU is successful, and the bootloader starts correctly.

  • Hello,

    Thank you for your reply.

    I have fixed the problem based on your answer.

    I updated the function dfu_bl_image_validate() as follows:

    uint32_t dfu_bl_image_validate(void)
    {
        bootloader_settings_t bootloader_settings;
        sd_mbr_command_t      sd_mbr_cmd;
    
        bootloader_settings_get(&bootloader_settings);
    
        if (bootloader_settings.bl_image_size != 0)
        {
            // Determine the new and old (when DFU_APP_DATA_RESERVED was OLD_DFU_APP_DATA_RESERVED = 0x0) bank_1 addresses
            uint32_t bl_image_start_new = (bootloader_settings.sd_image_size == 0) ?
                                          DFU_BANK_1_REGION_START :
                                          bootloader_settings.sd_image_start +
                                          bootloader_settings.sd_image_size;
    
            uint32_t bl_image_start_old = (bootloader_settings.sd_image_size == 0) ?
                                          OLD_DFU_BANK_1_REGION_START :
                                          bootloader_settings.sd_image_start +
                                          bootloader_settings.sd_image_size;
    
            // Check at the new bank address first
            sd_mbr_cmd.command             = SD_MBR_COMMAND_COMPARE;
            sd_mbr_cmd.params.compare.ptr1 = (uint32_t *)BOOTLOADER_REGION_START;
            sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)(bl_image_start_new);
            sd_mbr_cmd.params.compare.len  = bootloader_settings.bl_image_size / sizeof(uint32_t);
    
            uint32_t result = sd_mbr_command(&sd_mbr_cmd);
    
            // If the new bank address doesn't match, check the old one
            if (result != NRF_SUCCESS)
            {
                sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)(bl_image_start_old);
                result = sd_mbr_command(&sd_mbr_cmd);
            }
    
            return result;
        }
        return NRF_SUCCESS;
    }

    In which:

    #define OLD_DFU_APP_DATA_RESERVED       0x0                                               /**< Old size of app data. */
    #define DFU_APP_DATA_RESERVED           0x0400                                            /**< Size of Application Data that must be preserved between application updates. This value must be a multiple of page size. Page size is 0x400 (1024d) bytes, thus this value must be 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, etc. */
    #define OLD_DFU_BANK_1_REGION_START     (DFU_BANK_1_REGION_START + DFU_APP_DATA_RESERVED) /**< Old Bank 1 region start when DFU_APP_DATA_RESERVED was OLD_DFU_APP_DATA_RESERVED = 0x0. */

Related