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

Background DFU application source code

Hi there,

We are designing our DFU mechanism for our system that has 4 Nordic 52840.
It's going to be a consumer product, so we don't want the user to have to do 4 manual updates. For this reason, we are thinking to write the new application to the flash ourselves (through Wifi & ESB using our proprietary packets) and utilize the bootloader to check if there's valid application in "Bank 1" and process it if valid. So if the user requests, we will distribute the packets to the flash transparently. Then the user would only need to power cycle the boards and, voila, it's updated.

From reading through the forum, it seems like "Background DFU update" is the way to go. However, in the post such as this one, the links to the documentation seem to be invalid:
devzone.nordicsemi.com/.../163720
devzone.nordicsemi.com/.../background-dfu-update-problem-on-nrf52832
devzone.nordicsemi.com/.../180557

It seems like there are 2 parts we need to modify:
1) The bootloader part, that can be found in:
<InstallFolder>/examples/iot/bootloader
based on info here: infocenter.nordicsemi.com/.../background_dfu_bootloader.html

2) The application part, that does:
Transferring the new firmware to flash memory.
Validating checksum for each block of the firmware.
Triggering a swap procedure by entering the bootloader context.

I don't find where I can find the code for this part. Can you please direct me to the where in the <InstallFolder> it is located?

And, perhaps, if you have documentation that shows how to do background DFU? So that I can try it in the DK first...

Thanks!

Parents
  • Hi

    The install folder is the same as "SDK root", so \nRF5_SDK_15.3.0_59ac345\examples\iot\bootloader. What you need to do is to copy the DFU request handling from the bootloader to the application, then make your own custom ESB/WIFI transport layer for DFU. The transport layer requirements are outlined in the Bootloader documentation here: https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v15.3.0/lib_dfu_transport.html?cp=5_0_3_5_2. The same bootloader is also used in our thread/zigbee SDK for background DFU, so may use those as a reference. 

    Another relevant thread https://devzone.nordicsemi.com/f/nordic-q-a/46336/bootloader-no-transport-dual-bank-dfu-and-dependencies

  • Hi Vidar,

    Thanks for your prompt response!

    For the app side, porting the bootloader code to "copy the DFU request handling" from the app seems very involved. So, I'm thinking to just manually copy the new FW to the flash chunk by chunk (and do simple CRC check). Will this be enough?

    Or, will I also need to update the Bootloader Settings to notify the Bootloader that there's image in Bank 1?

    The bootloader that I have in mind is very similar to what you wrote on the other ticket:

    1. Checks to see if should enter DFU mode or not (I already have this working via USB)
    2. Check if there are any new FW images to activate (could be an image that the app has stored).
    3. If dfu_enter == true, initialize transport and wait for DFU master to initiate a DFU
    4. if dfu_enter == false, verify CRC of app image and boot the app.

    I notice in the other ticket that you will release a sample bootloader that can validate FW in flash. I'll probably wait for that also because I'm not sure how to tell the bootloader that there's a new FW image to activate.

  • Hi,

    I've uploaded the project to the other thread. It's configured for the 52832, so some porting will be required to make it run on the 52840 (mainly linker settings). Do you have a nRF52 DK to test with so you can verify that everything works first?

    Cecylia said:
    For the app side, porting the bootloader code to "copy the DFU request handling" from the app seems very involved. So, I'm thinking to just manually copy the new FW to the flash chunk by chunk (and do simple CRC check). Will this be enough?

    I think would be easier to re-use the "dfu" files from the bootloader. This gives you support for FW signing, and you will not have to modify the existing bootloader. The remaining task will then be to create a custom DFU transport to be used by the app. 

  • Hi Vidar, I don't have a DK, and Segger SES is kind of new for me actually (we're mostly using IAR).  I'm ordering one nRF52-DK that will arrive in 2 days.  But in the meantime do you have some pointers on how to try to change the linker settings so I can try it on 52840?

  • Hi,

    I  think you can use the ble_app_hrs example for PCA10056 as a starting point and add the following files to your  *.ewp file:

    <folder Name="nRF_Serial_DFU">
    <file file_name="../../../../../../components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c" />
    </folder>

    <folder Name="nRF_DFU">
    <file file_name="../../../../../../components/libraries/bootloader/dfu/nrf_dfu_settings.c" />
    <file file_name="../../../../../../components/libraries/bootloader/dfu/dfu-cc.pb.c" />
    <file file_name="../../../../../../components/libraries/bootloader/dfu/nrf_dfu.c" />
    <file file_name="../../../../../../components/libraries/bootloader/dfu/nrf_dfu_handling_error.c" />
    <file file_name="../../../../../../components/libraries/bootloader/dfu/nrf_dfu_mbr.c" />
    <file file_name="../../../../../../components/libraries/bootloader/dfu/nrf_dfu_req_handler.c" />
    <file file_name="../../../../../../components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c" />
    <file file_name="../../../../../../components/libraries/bootloader/dfu/nrf_dfu_transport.c" />
    <file file_name="../../../../../../components/libraries/bootloader/dfu/nrf_dfu_utils.c" />
    <file file_name="../../../../../../components/libraries/bootloader/dfu/nrf_dfu_validation.c" />
    <file file_name="../../../../../../components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c" />
    <file file_name="../../../nrf_dfu_flash.c" />
    </folder>
    <folder Name="nano-pb">
    <file file_name="../../../../../../external/nano-pb/pb_common.c" />
    <file file_name="../../../../../../external/nano-pb/pb_decode.c" />
    </folder>

    Then replace main.c file with the one from the other project. You also need to copy the DFU configuration from the sdk_config.h file. Just let me know if you run into any problems, I can probably help with porting next week if neccessary.  

  • Hi Vidar,

    So the NRF52DK has arrived.  But when I try it, the debugger never stops at main() function.
    Steps were:
    1) Program using program_bl_sd_bl_settings.bat
    2) Build the ble_app_hrs_pca10040_s132 project
    3) Ran debugger.

    If I pause the debugger, it stops at address 0x15xxx..but showing no source file..
    And, the Teraterm at 115200 shows no log at all.  I upload here the screenshot of trying to run the debugger.
    Should I use "Debug" or "Release" btw? Although both didn't work as expected for me.

    I also made progres with the NRF52840 DK (thanks!) I ran this on the Eval board.  Btw, I'm not actually sure if my board is PreviewDK or just DK, I don't know how to tell them apart.  Here's the project files.
    pca10056.zip

    It shows some printfs on Teraterm, but it has issue with the Bootloader address so it fails to continue.


    After I program with program_bl_sd_bl_settings, 0xFF8 shows the right address.
    >nrfjprog --memrd 0xff8 --n 100
    0x00000FF8: 00078000 0007E000 20001380 00024B19 |........... .K..|
    0x00001008: 0000C005 00024A7F 0000C005 0000C005 |.....J..........|
    0x00001018: 0000C005 00000000 00000000 00000000 |................|
    0x00001028: 00000000 00024B75 0000C005 00000000 |....uK..........|
    0x00001038: 0000C005 0000C005 00024BDD 00024BE3 |.........K...K..|
    0x00001048: 0000C005 0000C005 0000C005 0000C005 |................|
    0x00001058: 0000C005 |....|

    But as I'm running the debugger, when I check again, 0xFF8 and 0xFFC become all F's.
    >nrfjprog --memrd 0xff8 --n 100
    0x00000FF8: FFFFFFFF FFFFFFFF 20001380 000257B1 |........... .W..|
    0x00001008: 0000C069 00025717 0000C069 0000C069 |i....W..i...i...|
    0x00001018: 0000C069 00000000 00000000 00000000 |i...............|
    0x00001028: 00000000 0002580D 0000C069 00000000 |.....X..i.......|
    0x00001038: 0000C069 0000C069 00025875 0002587B |i...i...uX..{X..|
    0x00001048: 0000C069 0000C069 0000C069 0000C069 |i...i...i...i...|
    0x00001058: 0000C069 |i...|

    Please let me know how to proceed.  Thanks Slight smile

  • Hi,

    Cecylia said:
    So the NRF52DK has arrived.  But when I try it, the debugger never stops at main() function.
    Steps were:
    1) Program using program_bl_sd_bl_settings.bat
    2) Build the ble_app_hrs_pca10040_s132 project
    3) Ran debugger.

    Please try to do a complete "re-build" and see if it helps. Maybe it's missing the debug symbols. Otherwise, it may be the CRC validation of the app image inside the bootloader that fails, in that case, the bootloader will enter DFU mode instead of booting the app. 

    Cecylia said:

    If I pause the debugger, it stops at address 0x15xxx..but showing no source file..
    And, the Teraterm at 115200 shows no log at all.  I upload here the screenshot of trying to run the debugger.
    Should I use "Debug" or "Release" btw? Although both didn't work as expected for me.

    0x15xxx is the wait for events loop inside the Softdevice. This is where the program ends up when you call sd_app_evt_wait(). But it's hard to say if it was called from the bootloader or the app. 

    I used the RTT backend for logging since the UART is used for DFU (there's only 1 UART on 52832). RTT logs should be shown in the console output in SES. 

    The scripts I made assumes that you use the "Debug" target. This target will also enable more verbose error logging, so suggest that you use this target for now. 

    Cecylia said:
    I also made progres with the NRF52840 DK (thanks!) I ran this on the Eval board.  Btw, I'm not actually sure if my board is PreviewDK or just DK, I don't know how to tell them apart.  Here's the project files.

    The white sticker on the interface MCU tells you the version number of the board. Version 1.0.0 and later means that you have a non-preview kit. However, it's more important to know what IC revision you have. You can check the laser markings and look up the build code here: https://infocenter.nordicsemi.com/topic/comp_matrix_nrf52840/COMP/nrf52840/nRF52840_ic_revision_overview.html?cp=3_0_3_0. Engineering C and later should be fine.  

    I'm almost finished with porting the sample project to nRF52840. The only problem is that the final hash validation fails because the cc310 backend needs the hash message (i.e., application image) to reside in RAM, not FLASH. We have solved this in the bootloader by using an immediate RAM buffer. 

    PCA10056 project:

    nRF_SDK_15.3.0_background_dfu_2.zip

    Cecylia said:
    But as I'm running the debugger, when I check again, 0xFF8 and 0xFFC become all F's.

     SES programs the Softdevice along with the application hex, that's why the addresses are being overwritten. A workaround is to disable automatic programming of the Softdevice. Have done that in the attached project.

    Edit: Forgot to ask if it's possible to use the cc310 bootloader backend in your existing app? That would fix the problem with hashing. It supports the secp256r1 and secp224r1 curve for ECC, and sha256.

Reply
  • Hi,

    Cecylia said:
    So the NRF52DK has arrived.  But when I try it, the debugger never stops at main() function.
    Steps were:
    1) Program using program_bl_sd_bl_settings.bat
    2) Build the ble_app_hrs_pca10040_s132 project
    3) Ran debugger.

    Please try to do a complete "re-build" and see if it helps. Maybe it's missing the debug symbols. Otherwise, it may be the CRC validation of the app image inside the bootloader that fails, in that case, the bootloader will enter DFU mode instead of booting the app. 

    Cecylia said:

    If I pause the debugger, it stops at address 0x15xxx..but showing no source file..
    And, the Teraterm at 115200 shows no log at all.  I upload here the screenshot of trying to run the debugger.
    Should I use "Debug" or "Release" btw? Although both didn't work as expected for me.

    0x15xxx is the wait for events loop inside the Softdevice. This is where the program ends up when you call sd_app_evt_wait(). But it's hard to say if it was called from the bootloader or the app. 

    I used the RTT backend for logging since the UART is used for DFU (there's only 1 UART on 52832). RTT logs should be shown in the console output in SES. 

    The scripts I made assumes that you use the "Debug" target. This target will also enable more verbose error logging, so suggest that you use this target for now. 

    Cecylia said:
    I also made progres with the NRF52840 DK (thanks!) I ran this on the Eval board.  Btw, I'm not actually sure if my board is PreviewDK or just DK, I don't know how to tell them apart.  Here's the project files.

    The white sticker on the interface MCU tells you the version number of the board. Version 1.0.0 and later means that you have a non-preview kit. However, it's more important to know what IC revision you have. You can check the laser markings and look up the build code here: https://infocenter.nordicsemi.com/topic/comp_matrix_nrf52840/COMP/nrf52840/nRF52840_ic_revision_overview.html?cp=3_0_3_0. Engineering C and later should be fine.  

    I'm almost finished with porting the sample project to nRF52840. The only problem is that the final hash validation fails because the cc310 backend needs the hash message (i.e., application image) to reside in RAM, not FLASH. We have solved this in the bootloader by using an immediate RAM buffer. 

    PCA10056 project:

    nRF_SDK_15.3.0_background_dfu_2.zip

    Cecylia said:
    But as I'm running the debugger, when I check again, 0xFF8 and 0xFFC become all F's.

     SES programs the Softdevice along with the application hex, that's why the addresses are being overwritten. A workaround is to disable automatic programming of the Softdevice. Have done that in the attached project.

    Edit: Forgot to ask if it's possible to use the cc310 bootloader backend in your existing app? That would fix the problem with hashing. It supports the secp256r1 and secp224r1 curve for ECC, and sha256.

Children
Related