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

Not able to update firmware using bootloader (SDK15.3.0)

Hi,

I am using bootloader and application based on SDK15.3.0 and SD s140_nrf52_6.1.1_softdevice.hex.

I am also using our own BLE transport layer in application to receive new firmware file.

My process is a below.

1. Receive whole firmware image over BLE and store in flash (Bank1) in application code

2. Update botloader settings to inform bootloader that new firmware is available in Bank1

3. Reset system

My issue when I reset system it indefinitely remain in bootloader code and do not jump to application.

However, same process works for SDK15.2.0 in my other device.

I am setting below bootloader setting from application before reset.

/**********************************************************************************/
void update_bl_setting(uint32_t startAddress, uint32_t fwSize)
{
    s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP;
    s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_INVALID;
    s_dfu_settings.app_version = 0;
    s_dfu_settings.bank_1.image_crc = crc32_compute((uint8_t *)startAddress, fwSize, NULL);
    s_dfu_settings.bank_1.image_size = fwSize;
    s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1;
    s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_DUAL;
    
    /* Set the progress to zero and remove the last command */
    memset(&s_dfu_settings.progress, 0, sizeof(dfu_progress_t));
    memset(s_dfu_settings.init_command, 0xFF, DFU_SIGNED_COMMAND_SIZE);
    s_dfu_settings.write_offset = 0;
    s_dfu_settings.progress.update_start_address = startAddress;
}

/******************************************************************

Is there any major change related to bootloader setting in SDK15.3.0? Why it is working in SDK 15.2.0 but not in SDK15.3.0?

How to correctly record the necessary data for the bootloader and pass control to it to update the application?

 

I tested bootloader by setting NRF_BL_DFU_ALLOW_UPDATE_FROM_APP value to 0 and 1 both in SDK15.3.0.

Thanks,

Nirav patel

Parents Reply Children
  • Hi Nirav,

    Do I need to enable NRF_BL_DFU_ALLOW_UPDATE_FROM_APP option in application also?

    No, but NRF_DFU_IN_APP must be enabled.

  • Hi Vidar,

    Getting error message when try to update setting ("nrf_dfu_settings_write_and_backup") when "NRF_DFU_IN_APP" is enabled in application.

    ERROR MESSAGE:

    "<warning> nrf_dfu_settings: Settings write aborted since it tries writing to forbidden settings."

    -Nirav Patel

  • Hi Nirav, 

    The bootloader will only let the app modify the bootloader settings required to permit a dual-banked update of itself. So you will get this error if you, for instance, try to change the bank 0 settings directly. It is the bootloader that is responsible for the final validation and activation of the new application image stored in bank 1.  

    You may take a look at the project I posted here if you have not already: https://devzone.nordicsemi.com/f/nordic-q-a/46994/background-dfu-application-source-code/187534#187534. It demonstrates background DFU, but with the UART transport.

  • Thanks Vidar,

    I process DFU as per below:

    1. Convert application HEX to BIN.

    2. Send whole firmware image over BLE and store in flash (Bank1) in application code.

    3. Update bootloader setting and reset the device and let bootloader to control the image update process.

    As you said NRF_DFU_IN_APP must be enabled. But by doing this I am getting 

    ERROR MESSAGE: "<warning> nrf_dfu_settings: Settings write aborted since it tries writing to forbidden settings."

    So,I disabled NRF_DFU_IN_APP in application and made changes in bootloader setting after new firmware image received as mentioned below:

    void update_bl_setting(uint32_t startAddress, uint32_t fwSize)
    {
        s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP;
        s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_INVALID;
        s_dfu_settings.app_version = 0;
        s_dfu_settings.bank_1.image_crc = crc32_compute((uint8_t *)startAddress, fwSize, NULL);
        s_dfu_settings.bank_1.image_size = fwSize;
        s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1;
        s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_DUAL;
        
        /* Set the progress to zero and remove the last command */
        memset(&s_dfu_settings.progress, 0, sizeof(dfu_progress_t));
        memset(s_dfu_settings.init_command, 0xFF, DFU_SIGNED_COMMAND_SIZE);
        s_dfu_settings.write_offset = 0;
        s_dfu_settings.progress.update_start_address = startAddress;
    
        /*******************New setting added**********************************************/
        // Initialize with defaults.
    	s_dfu_settings.boot_validation_softdevice.type = NO_VALIDATION;
    	s_dfu_settings.boot_validation_app.type        = VALIDATE_CRC;
    	s_dfu_settings.boot_validation_bootloader.type = NO_VALIDATION;
    	memcpy(s_dfu_settings.boot_validation_app.bytes, &s_dfu_settings.bank_1.image_crc, sizeof(uint32_t));
    
    	s_dfu_settings.settings_version = NRF_DFU_SETTINGS_VERSION;
        /*******************New setting End**********************************************/
    }

    Now I am able to update firmware after setting parameter of "s_dfu_settings.boot_validation_app" while updating bootloader setting.

    Is it correct way to do this?

    -Nirav Patel

  • khodidas said:
    Is it correct way to do this?

    It doesn't seem to be exactly what was intended by those who implemented the background DFU support, but that doesn't mean it's wrong. I don't foresee any problems with the approach you describe, just make sure to test it well. 

Related