Modifying Bootloader Settings Page from Main App

Hello,

SDK:17.10

MCU:nRF52833

Hello,

I want to receive new firmware via BLE at the application layer(not the bootloader ) and store it in bank1.

I have already done the validation and just want the bootloader to activate the FW by moving the image from Bank 1 to Bank 0.

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.

According to the app_activate(void) function, I only need to modify the following parameters in the setting structure to complete the upgrade:

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.bank_1.image_size = fwSize;

s_dfu_settings.progress.update_start_address = startAddress;

But modify these parameters and rewrite the setting page, reset, the firmware has not completed the upgrade and has been stuck in the bootloader.

What should I do to make the bootlaoder copy the firmware of bank1 to bank0 and skip the verification(becasue I have already done the validation and just want the bootloader to activate the FW by moving the image from Bank 1 to Bank 0. )

best gards

Parents
  • Hi Ryon,

    Many of my colleagues in Norway are on vacation and Our nRF5SDK bootloader expert is on vacation and will return to work next week. We will have to wait until then. Thanks for your patience so far.

  • Hi Ryon, 

    I'm sorry for late response. 
    Have you tried to test with the debug version of the bootloader and step into the code to see why it didn't continue the DFU process and swap the application. 

    I think it worth to check out an example my colleague Vidar has made a while ago on background DFU: 
    devzone.nordicsemi.com/.../187534

  • Hello,

    I have seen the background update done by your colleague Vidar, but I am not the same as him, he handles the image and init command by copying the DFU request handling from the bootloader to the application.I only receive the image through my own BLE communication protocol, then update the setting, reset and jump to the bootloader, and execute the copy program from bank1 to bank0.

    I have used the debug version to test, but I can’t debug, because I received the firmware->updated the settings page->reset -> the problem occurs after re-jumping to the bootloader(I checked the log through RTT and found that it stopped as below)

    so my question is :If I only receive the firmware (.bin) at the application layer and store it in bank1, how should I let the bootloader skip receiving the update package(.zip) and various verifications and go directly to copying the program of bank1 to bank0?

    As far as I know, the following parameters in the setting need to be updated:
    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.bank_1.image_size = fwSize;
    s_dfu_settings.progress.update_start_address = startAddress;
    But after I update these parameters, the firmware cannot be successfully updated.

    thanks and regards

Reply
  • Hello,

    I have seen the background update done by your colleague Vidar, but I am not the same as him, he handles the image and init command by copying the DFU request handling from the bootloader to the application.I only receive the image through my own BLE communication protocol, then update the setting, reset and jump to the bootloader, and execute the copy program from bank1 to bank0.

    I have used the debug version to test, but I can’t debug, because I received the firmware->updated the settings page->reset -> the problem occurs after re-jumping to the bootloader(I checked the log through RTT and found that it stopped as below)

    so my question is :If I only receive the firmware (.bin) at the application layer and store it in bank1, how should I let the bootloader skip receiving the update package(.zip) and various verifications and go directly to copying the program of bank1 to bank0?

    As far as I know, the following parameters in the setting need to be updated:
    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.bank_1.image_size = fwSize;
    s_dfu_settings.progress.update_start_address = startAddress;
    But after I update these parameters, the firmware cannot be successfully updated.

    thanks and regards

Children
  • Hi Ryon, 

    I don't think I fully understand what you meant by 

    Ryon_pan said:
    he handles the image and init command by copying the DFU request handling from the bootloader to the application

    As far as I know the way it work is that the application will handle the DFU packet directly from UART not via the bootloader. The bootloader and the application doesn't run at the same time. 

    I think there is some protection mechanism that not allow the application to write directly to bootloader setting. It's been a while I haven't looked in to the bootloader source code, but I would suggest to do a full search for where in the bootloader you find: 
    the check for NRF_BL_DFU_ALLOW_UPDATE_FROM_APP 
    These are where the bootloader can be changed so that it support what you want to achieve. 

    Also pay attention to NRF_DFU_IN_APP , it's the configuration you need in your app when you use nrf_dfu_utils.c to write to bootloader setting. 

  • Hi,

    What I mean is that the DFU background routine receives the init packet and firmware at the application layer, then resets and enters the bootloader, and executes firmware upgrade after judging that there is new firmware, and my upgrade method is to only receive firmware without init packet, and then change the bootloader setting , reset and re-enter the bootloader, judge that there is new firmware, and then perform firmware upgrade.

    I think this kind of upgrade is also possible, but I just don’t know how to modify the bootloader setting. It must be that the bootloader setting is not set correctly, which leads to the inability to enter the firmware upgrade correctly.

    So my question is, what parameters do I need to update the bootloader setting for this kind of operation?

  • Hi Ryon, 
    As I mentioned, it's been a while I haven't looked into the code of the bootloader. 

    My understanding is that the bootloader will reset after it has postvalidated the image. https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.1.0/lib_bootloader_dfu_process.html?cp=9_1_3_5_1

    If the image is valid, the device resets and the bootloader activates the image to replace the existing firmware. Depending on the type of the image, it might replace the application, the SoftDevice, or even the current bootloader that is receiving the update.

    The bootloader would reset when NRF_DFU_EVT_DFU_COMPLETED event is triggered. This occurs after the write to bootloader setting has finished. On the next boot nrf_bootloader_fw_activate() will be called and if p_bank->bank_code == NRF_DFU_BANK_VALID_APP app_activate() will be called and the image will be swapped. 

    My suggestion is to try doing a normal DFU update with the stock bootloader. You then can intercept the process when the bootloader reset, and before it swap the application. You can put a breakpoint inside nrf_bootloader_fw_activate() and check what's the bootloader setting at that stage. 

    You then can compare with what you have in your application when you trigger a reset to jump to bootloader for the swap. I suspect that there could be something wrong when you write to bootloader setting, maybe you didn't wait until bootloader setting write is finished ? Or if you don't have the CRC written correctly ? To avoid having to calculate CRC manually I would just copy exactly what inside the stock bootloader setting at the intercept step I described above. 

  • Hi,

    Actually, I have tried your method. I use the normal DFU to update the firmware, enter the debugging, and let the code stop at the position shown in the figure below to view the changes of the bootloader setting before and after the update.

    The figure below shows the changes of the bootloader setting. The left side is the bootloader setting before the firmware is not updated, and the right side is the bootloader setting after receiving all the new firmware. According to the nrf_dfu_settings_t structure, we can know what needs to be changed before updating the new firmware:

    1.CRC
    2. app version;
    2. The bank code of bank0
    3. bank1, including image size, image crc and bank code
    4. update_start_address in progress
    5. boot_validation_crc
    6. boot_validation_app
    7. adv_name

        

    But after I changed these parameters, I still couldn’t successfully enter the image_copy() function to copy the firmware of bank1 to bank0.

    thanks & regards

  • Hi Ryon, 

    I think  you are very close to solve it. 
    When you write bootloader setting in the application and then trigger a reset, would you hit the breakpoint at  

    activation_result = nrf_bootloader_fw_activate();  in nrf_bootloader_init() ? 

    If it does, and you continue what stopped it from calling app_activate() ? 

Related