flash sharing of bootloader and app

I open up a flash shared space in app and bootloader, write values from app, bootloader read, bootloader read values such as 0xFFFFF, and not ideal values, may I ask why this is.

Based on the background of this problem, I want to customize the protocol OTA without any verification. I have correctly transferred the firmware data to bank1 through flash, and I want to modify s_dfu_setting myself to make the bootloader know that the firmware is valid and can be updated.

  • Hello, I have solved the above problem, and now there is a new problem:
    When the bootloader copies the new firmware from bank1 to bank0, there is a dead loop when the app is finally started. The run log file is as follows

    The background to these questions is: The nrf52840 external 4G module sends the firmware data to the app through http, and then the app saves the firmware data to bank_1 through flash, and then modifies these configurations in the bootloader, so that the bootloader copies the bank_1 data to bank_0. Here is the code added to the bootloader

    void nrf_dfu_settings_reinit(void)
    {
    // nrf_dfu_flash_read(0xFF000, m_dfu_settings_buffer, sizeof(new_dfu_setting_t));
    bool settings_valid = settings_crc_ok();
    bool settings_backup_valid = settings_backup_crc_ok();
    
    
    if (settings_valid)
    {
    NRF_LOG_DEBUG("Using settings page.");
    memcpy(&s_dfu_settings, m_dfu_settings_buffer, sizeof(nrf_dfu_settings_t));
    new_dfu_setting_t new_dfu_setting = {0};
    
    uint32_t setting_addr = 0;
    // setting_addr = 0x27000 + s_dfu_settings.bank_0.image_size;
    // setting_addr += 4096;
    nrf_dfu_flash_read(0x78000, &new_dfu_setting, sizeof(new_dfu_setting_t));
    NRF_LOG_INFO("new_dfu_setting.flag: %d", new_dfu_setting.flag);
    NRF_LOG_INFO("new_dfu_setting.fw_addr: 0x%08x, new_dfu_setting.fw_size: 0x%08x", new_dfu_setting.fw_addr, new_dfu_setting.fw_size);
    if(new_dfu_setting.flag == 0x01)    //Added the user-defined OTA mode, which is directly written to s_dfu_settings.
    {
    s_dfu_settings.progress.update_start_address = new_dfu_setting.fw_addr;
    s_dfu_settings.bank_1.image_size = new_dfu_setting.fw_size;
    s_dfu_settings.bank_1.image_crc = crc32_compute((uint8_t*)(s_dfu_settings.progress.update_start_address),s_dfu_settings.bank_1.image_size,NULL);
    s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP;
    s_dfu_settings.crc = settings_crc_get(&s_dfu_settings);
    memcpy(s_dfu_settings.boot_validation_app.bytes, &s_dfu_settings.bank_1.image_crc, 4);
    ret_code_t err_code = nrf_dfu_settings_write(NULL);
    if(err_code != NRF_SUCCESS) return;
    
    new_dfu_setting.flag = 0;
    err_code = nrf_dfu_flash_store(0x78000, &new_dfu_setting, sizeof(new_dfu_setting_t), NULL);
    if(err_code == NRF_SUCCESS)
    NRF_LOG_INFO("write new_dfu_setting success");
    //nrf_dfu_flash_erase(0x78000, 1, NULL);
    
    }
    else if (settings_backup_valid)
    {
    NRF_LOG_DEBUG("Copying forbidden parts from backup page.");
    settings_forbidden_parts_copy_from_backup((uint8_t *)&s_dfu_settings);
    }
    }
    else if (settings_backup_valid)
    {
    NRF_LOG_INFO("Restoring settings from backup since the settings page contents are "
    "invalid (CRC error).");
    memcpy(&s_dfu_settings,
    mp_dfu_settings_backup_buffer,
    sizeof(nrf_dfu_settings_t));
    }
    else
    {
    NRF_LOG_WARNING("Resetting bootloader settings since neither the settings page nor the "
    "backup are valid (CRC error).");
    memset(&s_dfu_settings, 0x00, sizeof(nrf_dfu_settings_t));
    s_dfu_settings.settings_version = NRF_DFU_SETTINGS_VERSION;
    }
    
    if (NRF_DFU_SETTINGS_COMPATIBILITY_MODE && !NRF_DFU_IN_APP && (s_dfu_settings.settings_version == 1))
    {
    NRF_LOG_INFO("Old settings page detected. Upgrading info.");
    
    // Old version. Translate.
    memcpy(&s_dfu_settings.peer_data, (uint8_t *)&s_dfu_settings + DFU_SETTINGS_BOND_DATA_OFFSET_V1, NRF_DFU_PEER_DATA_LEN);
    memcpy(&s_dfu_settings.adv_name, (uint8_t *)&s_dfu_settings + DFU_SETTINGS_ADV_NAME_OFFSET_V1, NRF_DFU_ADV_NAME_LEN);
    
    // 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_0.image_crc, sizeof(uint32_t));
    
    s_dfu_settings.settings_version = NRF_DFU_SETTINGS_VERSION;
    }
    
    return;
    }
    <info> app: s_set<info> app: Inside main
    
    <debug> app: In nrf_bootloader_init
    
    <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    
    <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    
    <debug> nrf_dfu_settings: Using settings page.
    
    <debug> nrf_dfu_flash: nrf_fstorage_read()(addr=0x00078000
    
    <info> nrf_dfu_settings: new_dfu_setting.flag: 0
    
    <info> nrf_dfu_settings: new_dfu_setting.fw_addr: 0x0004B5E8, new_dfu_setting.fw_size: 0x00023638
    
    <debug> nrf_dfu_settings: Copying forbidden parts from backup page.
    
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    
    <debug> app: Enter nrf_bootloader_fw_activate
    
    <debug> app: Valid App
    
    <debug> app: Enter nrf_dfu_app_continue
    
    <info> nrf_bootloader_wdt: WDT is not enabled
    
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0002F000, len=8 pages), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash erase success: addr=0x0002F000, pending 0
    
    <debug> app: Copying 0x535E8 to 0x2F000, size: 0x8000
    
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0002F000, src=0x000535E8, len=32768 bytes), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash write success: addr=0x0002F000, pending 0
    
    <debug> nrf_dfu_settings: Writing settings...
    
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0
    
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x20007F54, len=896 bytes), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0
    
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    
    <debug> nrf_dfu_settings: Writing settings...
    
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0
    
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x200082D4, len=896 bytes), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0
    
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x00037000, len=8 pages), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash erase success: addr=0x00037000, pending 0
    
    <debug> app: Copying 0x5B5E8 to 0x37000, size: 0x8000
    
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00037000, src=0x0005B5E8, len=32768 bytes), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash write success: addr=0x00037000, pending 0
    
    <debug> nrf_dfu_settings: Writing settings...
    
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0
    
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x20007F54, len=896 bytes), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0
    
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    
    <debug> nrf_dfu_settings: Writing settings...
    
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0
    
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x200082D4, len=896 bytes), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0
    
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0003F000, len=8 pages), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash erase success: addr=0x0003F000, pending 0
    
    <debug> app: Copying 0x635E8 to 0x3F000, size: 0x8000
    
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0003F000, src=0x000635E8, len=32768 bytes), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash write success: addr=0x0003F000, pending 0
    
    <debug> nrf_dfu_settings: Writing settings...
    
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0
    
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x20007F54, len=896 bytes), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0
    
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    
    <debug> nrf_dfu_settings: Writing settings...
    
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0
    
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x200082D4, len=896 bytes), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0
    
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x00047000, len=4 pages), queue usage: 1
    
    ding 0
    
    <debug> app: Copying 0x6B5E8 to 0x47000, size: 0x3638
    
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00047000, src=0x0006B5E8, len=13880 bytes), queue usage: 1
    
    <debug> nrf_dfu_flash: Flash write success: addr=0x00047000, pending 0
    
    <debug> nrf_dfu_settings: Writing settings...
    
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage<info> app: Inside main
    
    <debug> app: In nrf_bootloader_init
    
    <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    
    <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    
    <debug> nrf_dfu_settings: Using settings page.
    
    <debug> nrf_dfu_flash: nrf_fstorage_read()(addr=0x00078000
    
    <info> nrf_dfu_settings: new_dfu_setting.flag: 0
    
    <info> nrf_dfu_settings: new_dfu_setting.fw_addr: 0x0004B5E8, new_dfu_setting.fw_size: 0x00023638
    
    <debug> nrf_dfu_settings: Copying forbidden parts from backup page.
    
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    
    <debug> app: Enter nrf_bootloader_fw_activate
    
    <info> app: No firmware to activate.
    
    <debug> app: App is valid
    
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    
    <debug> app: Running nrf_bootloader_app_start with address: 0x00001000
    
    <debug> app: Disabling interrupts. NVIC->ICER[0]: 0x0

  • Hello,

    The bootloader enables read and write protection on itself with the ACL before booting the application. However, it will not protect the settings page if you have the bootloader built with NRF_BL_DFU_ALLOW_UPDATE_FROM_APP enabled in sdk_config.h. 

    Note that the app can only changes that are not within the red squares below, those are off limits to the app. Therefore you must load the stored values for the other elements into your RAM buffer. The app must not write to the backup either, the bootloader is responsible for that.

    The struct elements you must update to make the bootloader activate your update are: crc (is the checksum of settings struct - see settings_module for how it is calculated),  bank_current (set it to bank 1), progress, and init_command.

  • Hello, I have changed the method now.
    Create a flash space (shared by app and bootlaoder) to store bank_1's new address, firmware size, and whether or not to customize OTA tags. Enter bootloader back to read the original s_dfu_settings to modify these values s_dfu_settings after RAM. The progress. Update_start_address, s_dfu_settings bank_1. Image_size, s_dfu_settings.bank_1.image_crc, s_dfu_settings.bank_1.bank_code, s_dfu_settings.crc. As you said I should modify bank_current and init_command again, right? But init_command looks like something like a command, how do I change it?
    Also, as you said "NRF_BL_DFU_ALLOW_UPDATE_FROM_APP is enabled in sdk_config.h, it will not protect the Settings page". I also want to keep the original BLE OTA way. NRF_BL_DFU_ALLOW_UPDATE_FROM_APP Should I disable it?

  • Hello,

    The bank 1 start address should be found using the nrf_dfu_bank1_start_addr() function. It is based on the start address and size of the current application image. If you use another address than this, the bootloader will not be able to activate the update.

    name said:
    Update_start_address, s_dfu_settings bank_1. Image_size, s_dfu_settings.bank_1.image_crc, s_dfu_settings.bank_1.bank_code, s_dfu_settings.crc.

    The application is not permitted to change .bank_1.

    name said:
    But init_command looks like something like a command, how do I change it?

    The init command contains metadata about the update which is needed by the bootloader to activate the update and should be uploaded along with the binary image. The init command is created with nrfutil

    name said:
    NRF_BL_DFU_ALLOW_UPDATE_FROM_APP is enabled in sdk_config.h, it will not protect the Settings page". I also want to keep the original BLE OTA way. NRF_BL_DFU_ALLOW_UPDATE_FROM_APP Should I disable it?

    You will still be able to perform dfu within the bootloader with this setting enabled.

  • Hello, thank you very much for your time. Now I can successfully write firmware data to bank_1 area through the app, and I can also successfully pass the verification of setting after entering the bootloader. I have successfully made the bootloader recognize the firmware data written by me as valid. However, the problem is that the process of copying firmware data from bank_1 to bank_0 in the bootloader is restarting. The following is the run log. The log for the first image shows that the watchdog turned on when entering image_copy is not turned on. I wonder if that's what caused the reboot?

Related