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

Dualbank to Singlebank via BLE DFU

I currently have a dualbank bootloader setup and I'm trying to change it to singlebank. If I burn the singlebank bootloader with the jlink it works fine, but if I use the old dualbank bootloader to update itself to the new singlebank hex, then it doesn't boot. It goes both ways, I can't go from singlebank and dfu the old dualbank hex.

On the other hand, If I burn the singelbank hex and try to dfu another modified singlebank hex, then it works perfect.

I'm using SDK 7.1.0 with softdevice 2.0.1 with Keil 5.

All I'm doing to change from between single and dualbank is selecting the correct option form the "dfu_bootloader" dropdown in the "Manage Run-Time Environment" window of Keil.

Is this a known issue?

EDIT:

It works now. I modified dfu_bl_image_validate() in dfu_single_bank.c from this:

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)
    {
        uint32_t bl_image_start = (bootloader_settings.sd_image_size == 0) ?
                                  DFU_BANK_0_REGION_START :
                                  bootloader_settings.sd_image_start +
                                  bootloader_settings.sd_image_size;

        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);
        sd_mbr_cmd.params.compare.len  = bootloader_settings.bl_image_size / sizeof(uint32_t);

        return sd_mbr_command(&sd_mbr_cmd);
    }
    return NRF_SUCCESS;
}

to this:

uint32_t dfu_bl_image_validate(void) {
    bootloader_settings_t bootloader_settings;
    sd_mbr_command_t      sd_mbr_cmd_1;
    sd_mbr_command_t      sd_mbr_cmd_2;

    bootloader_settings_get(&bootloader_settings);

    if (bootloader_settings.bl_image_size != 0)
    {
        uint32_t bl_image_start_1 = (bootloader_settings.sd_image_size == 0) ?
                                  DFU_BANK_0_REGION_START :
                                  bootloader_settings.sd_image_start +
                                  bootloader_settings.sd_image_size;

        sd_mbr_cmd_1.command             = SD_MBR_COMMAND_COMPARE;
        sd_mbr_cmd_1.params.compare.ptr1 = (uint32_t *)BOOTLOADER_REGION_START;
        sd_mbr_cmd_1.params.compare.ptr2 = (uint32_t *)(bl_image_start_1);
        sd_mbr_cmd_1.params.compare.len  = bootloader_settings.bl_image_size / sizeof(uint32_t);

			
		
    uint32_t bl_image_start_2 = (bootloader_settings.sd_image_size == 0) ?
                                  DFU_BANK_1_REGION_START :
                                  bootloader_settings.sd_image_start +
                                  bootloader_settings.sd_image_size;

        sd_mbr_cmd_2.command             = SD_MBR_COMMAND_COMPARE;
        sd_mbr_cmd_2.params.compare.ptr1 = (uint32_t *)BOOTLOADER_REGION_START;
        sd_mbr_cmd_2.params.compare.ptr2 = (uint32_t *)(bl_image_start_2);
        sd_mbr_cmd_2.params.compare.len  = bootloader_settings.bl_image_size / sizeof(uint32_t);

        return sd_mbr_command(&sd_mbr_cmd_1) && sd_mbr_command(&sd_mbr_cmd_2);
    }
    return NRF_SUCCESS;
}

And it works perfectly. I'm sure other people will need this in the future. Particularly if they have a dualbank bootloader (on devices in the field) and they run out of space for runtime code. I hope it helps. Thanks Vidar.

Related