OFF CHIP OTA UPDATE using external flash

I am working on this project off chip ota update on nRF5_SDK  using ecample/thread/dfu

by now, i have done changes in these functions on_data_obj_create_request() and on_data_obj_write_request(). initially these functions were erasing and writing data in internal flash which I changed to qspi functions like nrf_drv_qspi_erase() and nrf_drv_qspi_write(). and it works perfectly.

Later i changed functions for hash verification which is also working but i am not sure about what should be the next step so that bootloader changes the earlier application with the new firmware image.

  • Sorry, I was using different build files for comparison.

    After using the same build files, there is no difference in the application area. The only distinction lies in the settings area of the flash. This time, I'm comparing direct flash and flash after DFU.

    Perhaps the reason for this difference is that I generate different setting files to flash this app on my device.

    dnk124 ~ nrfjprog --memrd 0x0 --n 1048576 > qspi_flash.hex
    dnk124 ~ nrfjprog --memrd 0x0 --n 1048576 > flash.hex
    dnk124 ~ cmp qspi_flash.hex flash.hex
    qspi_flash.hex flash.hex differ: byte 4204678, line 60938
    dnk124 ~ 1 diff qspi_flash.hex flash.hex
    60938,61027c60938,61027
    < 0x000EE090: FFFF0026 C4100402 00000000 000003EA |&...............|
    < 0x000EE0A0: 000003EC 1D049C28 65E2F7EE 146DA9C1 |....(......e..m.|
    < 0x000EE0B0: 656F9674 B15B635F 0AB10002 FFF40007 |t.oe_c[.........|
    < 0x000EE0C0: FFFF0020 BFFD8B82 80573BF0 52DF1B7E | ........;W.~..R|
    < 0x000EE0D0: 9B630F2F EEDEFAAB EC74EBE6 9C0D6EED |/.c.......t..n..|
    < 0x000EE0E0: C2E2718D FFF40003 FFFF0026 C4100402 |.q......&.......|
    < 0x000EE0F0: 00000000 000003EB 000007D4 1D049C28 |............(...|
    < 0x000EE100: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE110: 146D0002 FFF40003 FFFF0026 C4100402 |..m.....&.......|
    < 0x000EE120: 00000000 000003EB 00000BBC 1D049C28 |............(...|
    < 0x000EE130: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE140: 146D0002 FFF40003 FFFF0026 C4100402 |..m.....&.......|
    < 0x000EE150: 00000000 000003EB 00000FA4 1D049C28 |............(...|
    < 0x000EE160: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE170: 146D0002 FFF40003 FFFF0026 C4100402 |..m.....&.......|
    < 0x000EE180: 00000000 000003EB 0000138C 1D049C28 |............(...|
    < 0x000EE190: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE1A0: 20030002 FFF40003 FFFF0026 C4100402 |... ....&.......|
    < 0x000EE1B0: 00000000 000003EB 00001774 1D049C28 |........t...(...|
    < 0x000EE1C0: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE1D0: 20030002 FFF40003 FFFF0026 C4100402 |... ....&.......|
    < 0x000EE1E0: 00000000 000003EB 00001B5C 1D049C28 |........\...(...|
    < 0x000EE1F0: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE200: 20030002 FFF40003 FFFF0026 C4100402 |... ....&.......|
    < 0x000EE210: 00000000 000003EB 00001F44 1D049C28 |........D...(...|
    < 0x000EE220: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE230: 20030002 FFF40003 FFFF0026 C4100402 |... ....&.......|
    < 0x000EE240: 00000000 000003EB 0000232C 1D049C28 |........,#..(...|
    < 0x000EE250: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE260: 20030002 FFF40003 FFFF0026 C4100402 |... ....&.......|
    < 0x000EE270: 00000000 000003EB 00002714 1D049C28 |.........'..(...|
    < 0x000EE280: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE290: 00000002 FFF40003 FFFF0026 C4100402 |........&.......|
    < 0x000EE2A0: 00000000 000003EB 00002AFC 1D049C28 |.........*..(...|
    < 0x000EE2B0: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE2C0: 20030002 FFF40003 FFFF0026 C4100402 |... ....&.......|
    < 0x000EE2D0: 00000000 000003EB 00002EE4 1D049C28 |............(...|
    < 0x000EE2E0: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE2F0: 00000002 FFF40003 FFFF0026 C4100402 |........&.......|
    < 0x000EE300: 00000000 000003EB 000032CC 1D049C28 |.........2..(...|
    < 0x000EE310: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE320: 20030002 FFF40003 FFFF0026 C4100402 |... ....&.......|
    < 0x000EE330: 00000000 000003EB 000036B4 1D049C28 |.........6..(...|
    < 0x000EE340: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE350: 19130002 FFF40003 FFFF0026 C4100402 |........&.......|
    < 0x000EE360: 00000000 000003EB 00003A9C 1D049C28 |.........:..(...|
    < 0x000EE370: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE380: 20030002 FFF40003 FFFF0026 C4100402 |... ....&.......|
    < 0x000EE390: 00000000 000003EB 00003E84 1D049C28 |.........>..(...|
    < 0x000EE3A0: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE3B0: 20030002 FFF40003 FFFF0026 C4100402 |... ....&.......|
    < 0x000EE3C0: 00000000 000003EB 0000426C 1D049C28 |........lB..(...|
    < 0x000EE3D0: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE3E0: 00000002 FFF40003 FFFF0026 C4100402 |........&.......|
    < 0x000EE3F0: 00000000 000003EB 00004654 1D049C28 |........TF..(...|
    < 0x000EE400: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE410: 20030002 FFF40003 FFFF0026 C4100402 |... ....&.......|
    < 0x000EE420: 00000000 000003EB 00004A3C 1D049C28 |........<J..(...|
    < 0x000EE430: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE440: 00000002 FFF40003 FFFF0026 C4100402 |........&.......|
    < 0x000EE450: 00000000 000003EB 00004E24 1D049C28 |........$N..(...|
    < 0x000EE460: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE470: 146D0002 FFF40003 FFFF0026 C4100402 |..m.....&.......|
    < 0x000EE480: 00000000 000003EB 0000520C 1D049C28 |.........R..(...|
    < 0x000EE490: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE4A0: 146D0002 FFF40003 FFFF0026 C4100402 |..m.....&.......|
    < 0x000EE4B0: 00000000 000003EB 000055F4 1D049C28 |.........U..(...|
    < 0x000EE4C0: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE4D0: 20030002 FFF40003 FFFF0026 C4100402 |... ....&.......|
    < 0x000EE4E0: 00000000 000007D4 000059DC 1D049C28 |.........Y..(...|
    < 0x000EE4F0: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE500: 00000002 FFF40003 FFFF0026 C4100402 |........&.......|
    < 0x000EE510: 00000000 000007D5 000059DF 1D049C28 |.........Y..(...|
    < 0x000EE520: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE530: 00000002 FFF40003 FFFF0026 C4100402 |........&.......|
    < 0x000EE540: 00000000 000007D7 00005DC7 1D049C28 |.........]..(...|
    < 0x000EE550: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE560: 146D0002 FFF40003 FFFF0026 C4100402 |..m.....&.......|
    < 0x000EE570: 00000000 000007D7 000061AF 1D049C28 |.........a..(...|
    < 0x000EE580: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE590: 146D0002 FFF40003 FFFF0026 C4100402 |..m.....&.......|
    < 0x000EE5A0: 00000000 000007D7 00006597 1D049C28 |.........e..(...|
    < 0x000EE5B0: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE5C0: 146D0002 FFF40003 FFFF0026 C4100402 |..m.....&.......|
    < 0x000EE5D0: 00000000 000007D7 0000697F 1D049C28 |.........i..(...|
    < 0x000EE5E0: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE5F0: 146D0002 FFF40003 FFFF0026 C4100402 |..m.....&.......|
    < 0x000EE600: 00000000 000007D7 00006D67 1D049C28 |........gm..(...|
    < 0x000EE610: 65E2F7EE 146DA9C1 656F9674 B15B635F |...e..m.t.oe_c[.|
    < 0x000EE620: 146D0002 FFFFFFFF FFFFFFFF FFFFFFFF |..m.............|
    ---
    > 0x000EE090: FFFF0026 C4110402 00000000 000003EB |&...............|
    > 0x000EE0A0: 000003EC 1D049C28 6538672A C7766CA3 |....(...*g8e.lv.|
    > 0x000EE0B0: 3307B21B B45FB38F 0AB10002 FFF40007 |...3.._.........|
    > 0x000EE0C0: FFFF0020 F4338CEC 094B7121 1C369312 | .....3.!qK...6.|
    > 0x000EE0D0: 3218A5D4 A1FD3457 87E9CB2B 13F752D6 |...2W4..+....R..|
    > 0x000EE0E0: 17361FE3 FFF40003 FFFF0026 C4110402 |..6.....&.......|
    > 0x000EE0F0: 00000000 000007D4 000007D4 1D049C28 |............(...|
    > 0x000EE100: 6538672A C7766CA3 3307B21B B45FB38F |*g8e.lv....3.._.|
    > 0x000EE110: 00000002 FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE120: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE130: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE140: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE150: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE160: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE170: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE180: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE190: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE1A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE1B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE1C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE1D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE1E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE1F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE200: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE210: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE220: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE230: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE240: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE250: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE260: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE270: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE280: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE290: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE2A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE2B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE2C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE2D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE2E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE2F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE300: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE310: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE320: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE330: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE340: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE350: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE360: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE370: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE380: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE390: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE3A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE3B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE3C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE3D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE3E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE3F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE400: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE410: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE420: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE430: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE440: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE450: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE460: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE470: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE480: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE490: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE4A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE4B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE4C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE4D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE4E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE4F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE500: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE510: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE520: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE530: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE540: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE550: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE560: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE570: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE580: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE590: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE5A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE5B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE5C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE5D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE5E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE5F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE600: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE610: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    > 0x000EE620: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    65025c65025
    < 0x000FE000: CB0B2FB5 00000002 00000002 00000001 |./..............|
    ---
    > 0x000FE000: 40FFE85D 00000002 00000001 00000001 |]..@............|
    65029,65062c65029,65062
    < 0x000FE040: 00000000 00000000 00066000 00000000 |.........`......|
    < 0x000FE050: 00000000 00000000 00000000 FFFFFFFF |................|
    < 0x000FE060: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE070: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE080: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE090: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE0A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE0B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE0C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE0D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE0E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE0F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE100: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE110: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE120: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE130: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE140: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE150: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE160: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE170: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE180: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE190: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE1A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE1B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE1C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE1D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE1E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE1F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE200: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE210: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE220: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE230: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE240: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FE250: FFFFFFFF FFFFFFFF FFFFFFFF F0678FEF |..............g.|
    ---
    > 0x000FE040: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE050: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE060: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE070: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE080: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE090: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE0A0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE0B0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE0C0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE0D0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE0E0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE0F0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE100: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE110: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE120: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE130: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE140: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE150: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE160: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE170: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE180: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE190: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE1A0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE1B0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE1C0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE1D0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE1E0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE1F0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE200: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE210: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE220: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE230: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE240: 00000000 00000000 00000000 00000000 |................|
    > 0x000FE250: 00000000 00000000 00000000 CE832C27 |............',..|
    65067c65067
    < 0x000FE2A0: 805A0100 00001EC7 00000000 00000000 |..Z.............|
    ---
    > 0x000FE2A0: 60720100 0000CED2 00000000 00000000 |..r`............|
    65281c65281
    < 0x000FF000: CB0B2FB5 00000002 00000002 00000001 |./..............|
    ---
    > 0x000FF000: 40FFE85D 00000002 00000001 00000001 |]..@............|
    65285,65318c65285,65318
    < 0x000FF040: 00000000 00000000 00066000 00000000 |.........`......|
    < 0x000FF050: 00000000 00000000 00000000 FFFFFFFF |................|
    < 0x000FF060: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF070: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF080: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF090: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF0A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF0B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF0C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF0D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF0E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF0F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF100: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF110: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF120: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF130: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF140: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF150: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF160: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF170: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF180: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF190: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF1A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF1B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF1C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF1D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF1E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF1F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF200: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF210: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF220: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF230: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF240: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
    < 0x000FF250: FFFFFFFF FFFFFFFF FFFFFFFF F0678FEF |..............g.|
    ---
    > 0x000FF040: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF050: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF060: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF070: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF080: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF090: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF0A0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF0B0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF0C0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF0D0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF0E0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF0F0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF100: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF110: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF120: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF130: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF140: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF150: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF160: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF170: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF180: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF190: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF1A0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF1B0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF1C0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF1D0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF1E0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF1F0: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF200: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF210: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF220: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF230: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF240: 00000000 00000000 00000000 00000000 |................|
    > 0x000FF250: 00000000 00000000 00000000 CE832C27 |............',..|
    65323c65323
    < 0x000FF2A0: 805A0100 00001EC7 00000000 00000000 |..Z.............|
    ---
    > 0x000FF2A0: 60720100 0000CED2 00000000 00000000 |..r`............|

  • It is the FW images that are interesting to compare in this case. If they are identical, then that indicates that everything from receiving the FW image to the QSPI to storing it to bank 0 is being handled correctly. 

    Another thing you can try is to generate the settings page with nrfutil and see if it gives the same CRC value as the one computed by the bootloader. 

    $ nrfutil nrf5sdk-tools settings generate --application <your application hex> --application-version 2 --bl-settings-version 2 --bootloader-version 1 --family NRF52840 settings.hex

  • Yes, I found the same thing in the initial logs from background_dfu_state.c. There was a CRC that matched the computed CRC in the bootloader. Consequently, I made some changes to the code, and it's currently functioning as expected. Now, I'm in the process of testing it for the final version.

    This log is from the point where the first CRC was printed.

      

    This is the code I modified in the parse_trigger() function within the background_dfu_state.c file to store that CRC in the external QSPI flash.

     

    static bool parse_trigger(background_dfu_context_t       * p_dfu_ctx,
                              const background_dfu_trigger_t * p_trigger)
    {
        uint8_t trigger_version = (p_trigger->flags & TRIGGER_FLAGS_VERSION_MASK)
                                        >> TRIGGER_FLAGS_VERSION_OFFSET;
    
        if (trigger_version <= TRIGGER_VERSION)
        {
            // Base fields available from version 0.
            p_dfu_ctx->init_cmd_size = uint32_big_decode((const uint8_t *)&p_trigger->init_length);
            p_dfu_ctx->init_cmd_crc  = uint32_big_decode((const uint8_t *)&p_trigger->init_crc);
            p_dfu_ctx->firmware_size = uint32_big_decode((const uint8_t *)&p_trigger->image_length);
            p_dfu_ctx->firmware_crc  = uint32_big_decode((const uint8_t *)&p_trigger->image_crc);
    
            // Mode flag was added in DFU Trigger version 1.
            if (trigger_version >= 1)
            {
                p_dfu_ctx->dfu_mode = (background_dfu_mode_t)((p_trigger->flags
                                        & TRIGGER_FLAGS_MODE_MASK) >> TRIGGER_FLAGS_MODE_OFFSET);
                p_dfu_ctx->reset_suppress = (p_trigger->flags & TRIGGER_FLAGS_RESET_MASK) >>
                                              TRIGGER_FLAGS_RESET_OFFSET;
    
            }
            else
            {
                p_dfu_ctx->dfu_mode = BACKGROUND_DFU_MODE_UNICAST;
            }
    
            NRF_LOG_INFO("DFU trigger: init (sz=%d, crc=%0X) image (sz=%d, crc=%0X)",
                         p_dfu_ctx->init_cmd_size,
                         p_dfu_ctx->init_cmd_crc,
                         p_dfu_ctx->firmware_size,
                         p_dfu_ctx->firmware_crc);
    
                         printf("Total Number of blocks: %d\r\n",p_dfu_ctx->firmware_size/64);
        
    
        // Get the dynamic value of firmware_crc from p_dfu_ctx whenever needed
        uint32_t CRC_VAL = p_dfu_ctx->firmware_crc;
    
        // Create an array and directly initialize it with the dynamic value using a compound literal
        uint32_t CRC_VAL_BUFF[] = { CRC_VAL };
    
        /* erase the flash */
            
        if(nrf_drv_qspi_erase(sizeof(CRC_VAL_BUFF), FIRMWARE_CRC_ADDR) != NRFX_SUCCESS)
        {
          NRF_LOG_INFO("Failed to errase data blocks for initial firmware crc.\r\n");
        }
        else
        {
          WAIT_FOR_PERIPH();
          NRF_LOG_INFO("Succsessfully Erased Ext Flash block at: 0x%X\r\n\r\n",FIRMWARE_CRC_ADDR);
        }
    
    
    
        if(nrf_drv_qspi_write(CRC_VAL_BUFF, sizeof(CRC_VAL_BUFF),FIRMWARE_CRC_ADDR) != NRFX_SUCCESS)
        {
          WAIT_FOR_PERIPH();
          NRF_LOG_INFO("\r\nFailed storing initial firmware crc.\r\n");
        }
        else
        {
          WAIT_FOR_PERIPH();
          NRF_LOG_INFO("Succsessfully reead initial firmware crc=0x%X  at: 0x%X\r\n", CRC_VAL, FIRMWARE_CRC_ADDR);
        }
        
        
        
        dfu_total_blocks = p_dfu_ctx->firmware_size/64;
    
        if (p_dfu_ctx->firmware_size % 64 != 0) {
            dfu_total_blocks += 1;
        }
    
              
            return true;
        }
    
        return false;
    }
    

    I later modified the code in the nrf_dfu_validation_boot_validate() function within the nrf_dfu_validation.c file to read the same CRC and validate it against the computed CRC. This function is called twice: first after downloading the complete image in the external flash and then after a bootloader reset as well.

    after first call of this function:

    the second call of this function which comes at the end

    the code which i changed 

    bool nrf_dfu_validation_boot_validate(boot_validation_t const * p_validation, uint32_t data_addr, uint32_t data_len)
    {
        uint8_t const * p_data = (uint8_t*) data_addr;
        switch(p_validation->type)
        {
            case NO_VALIDATION:
                return true;
    
            case VALIDATE_CRC:
            {
                uint32_t current_crc = *(uint32_t *)p_validation->bytes;
                uint32_t crc = crc32_compute(p_data, data_len, NULL);
    
                //qspi read
                uint32_t read_buffer[1]; // Buffer to store the read value
    
                // Read the value from QSPI memory into read_buffer (assumed nrf_drv_qspi_read is used)
                if (nrf_drv_qspi_read(read_buffer, sizeof(read_buffer), FIRMWARE_CRC_ADDR) != NRFX_SUCCESS)
                {
                    // Error handling if read fails
                    WAIT_FOR_PERIPH();
                    NRF_LOG_INFO("\r\nFailed reading initial firmware crc.\r\n");
                }
                else
                {
                    // Successful read
                    WAIT_FOR_PERIPH();
    
                    CRC_VAL = read_buffer[0]; // Extract the read value from the buffer
                    NRF_LOG_INFO("Succsessfully reead initial firmware crc=0x%X  at: 0x%X\r\n", CRC_VAL, FIRMWARE_CRC_ADDR);
                }
    
    
                NRF_LOG_INFO("Validate CRC\r\nCuurent CRC: 0x%08x, Computed CRC: 0x%08x, initial crc: 0x%08x\r\n",current_crc,crc,CRC_VAL);
    
                if (!(crc == current_crc || crc == CRC_VAL))
                {
                    // CRC does not match with what is stored.
                    NRF_LOG_DEBUG("CRC check of app failed. Return %d \r\nCuurent CRC: 0x%08x, Computed CRC: 0x%08x", NRF_DFU_DEBUG,current_crc,crc);
                    return NRF_DFU_DEBUG;
                }
                return true;
            }
    
            case VALIDATE_SHA256:
                return nrf_dfu_validation_hash_ok(p_validation->bytes, data_addr, data_len, false);
    
            case VALIDATE_ECDSA_P256_SHA256:
            {
                nrf_dfu_result_t res_code = nrf_dfu_validation_signature_check(
                                                DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256,
                                                p_validation->bytes,
                                                NRF_CRYPTO_ECDSA_SECP256R1_SIGNATURE_SIZE,
                                                p_data,
                                                data_len);
                return (res_code == NRF_DFU_RES_CODE_SUCCESS);
            }
    
            default:
                ASSERT(false);
                return false;
        }
    }

    Afterward, I updated the app_activate() function in nrf_bootloader_fw_activation.c to perform the same validation against the computed CRC, and this part is also functioning correctly.

    log of this function

    the code which i changed

    static uint32_t app_activate(void)
    {
        // This function is only in use when new app is present in Bank 1
        uint32_t const image_size  = s_dfu_settings.bank_1.image_size;
    
        uint32_t src_addr    = s_dfu_settings.progress.update_start_address;
        uint32_t ret_val     = NRF_SUCCESS;
        uint32_t target_addr = nrf_dfu_bank0_start_addr() + s_dfu_settings.write_offset;
        uint32_t length_left = (image_size - s_dfu_settings.write_offset);
        uint32_t crc;
    
        NRF_LOG_DEBUG("Enter nrf_dfu_app_continue");
    
        src_addr += s_dfu_settings.write_offset;
    
        if (src_addr == target_addr)
        {
            length_left = 0;
        }
    
        ret_val = image_copy(target_addr, src_addr, length_left, NRF_BL_FW_COPY_PROGRESS_STORE_STEP);
        if (ret_val != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("Failed to copy firmware.");
            return ret_val;
        }
    
        // Check the CRC of the copied data. Enable if so.
        crc = crc32_compute((uint8_t*)nrf_dfu_bank0_start_addr(), image_size, NULL);
        
        //qspi read
        uint32_t read_buffer[1]; // Buffer to store the read value
    
        // Read the value from QSPI memory into read_buffer (assumed nrf_drv_qspi_read is used)
        if (nrf_drv_qspi_read(read_buffer, sizeof(read_buffer), FIRMWARE_CRC_ADDR) != NRFX_SUCCESS)
        {
            // Error handling if read fails
            WAIT_FOR_PERIPH();
            NRF_LOG_INFO("\r\nFailed reading initial firmware crc.\r\n");
        }
        else
        {
            // Successful read
            WAIT_FOR_PERIPH();
    
            CRC_VAL_INI = read_buffer[0]; // Extract the read value from the buffer
            NRF_LOG_INFO("Succsessfully reead initial firmware crc=0x%X  at: 0x%X\r\n", CRC_VAL_INI, FIRMWARE_CRC_ADDR);
        }
    
    
    
        if (crc == s_dfu_settings.bank_1.image_crc || crc == CRC_VAL_INI)
        {
            NRF_LOG_DEBUG("Setting app as valid");
            s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_VALID_APP;
            s_dfu_settings.bank_0.image_crc = crc;
            s_dfu_settings.bank_0.image_size = image_size;
        }
        else
        {
            NRF_LOG_ERROR("CRC computation failed for copied app: "
                          "src crc: 0x%08x, res crc: 0x%08x",
                          s_dfu_settings.bank_1.image_crc,
                          crc);
        }
    
        return ret_val;
    }

    As of now i have done this process four times and it's working

      

    I've nearly completed the task at hand, and currently, everything is functioning smoothly. I'm in the process of conducting final tests to ensure everything is perfect. If any difficulties arise, I'll return here for further assistance.

    Thank you for your support throughout this process.

  • Thank you for the update. I'm glad to hear that you found the problem.

  • Hello  ,

    The recent changes have been effective most of the time, but occasional failures still occur in the CRC calculation following image copying. The CRC obtained from the QSPI sometimes doesn't align with the computed CRC after the image copy process. To address this, I implemented a modification: before copying the image, I perform a CRC calculation on the image stored in the external flash. Subsequently, I added a condition that allows the image to be copied only if these two CRC values match. This solution has been functioning properly. However, a problem arises when a CRC mismatch occurs. I've implemented a flag that triggers the start of the Bank 0 application, but I'm uncertain about the logic behind it.

    I'm considering adjustments to the settings that would prompt the bootloader to restart the Bank 0 application. Any insights on which settings should be modified for this purpose?

    static uint32_t app_activate(void) {
      // This function is only in use when new app is present in Bank 1
      uint32_t const image_size = s_dfu_settings.bank_1.image_size;
    
      uint32_t src_addr = s_dfu_settings.progress.update_start_address;
      uint32_t ret_val = NRF_SUCCESS;
      uint32_t target_addr = nrf_dfu_bank0_start_addr() + s_dfu_settings.write_offset;
      uint32_t length_left = (image_size - s_dfu_settings.write_offset);
      uint32_t crc;
    
      NRF_LOG_DEBUG("Enter nrf_dfu_app_continue");
    
      src_addr += s_dfu_settings.write_offset;
    
      if (src_addr == target_addr) {
        length_left = 0;
      }
    
      //qspi read
      uint32_t read_buffer[1]; // Buffer to store the read value
    
      // Read the value from QSPI memory into read_buffer (assumed nrf_drv_qspi_read is used)
      if (nrf_drv_qspi_read(read_buffer, sizeof(read_buffer), FW_CRC_ADDR) != NRFX_SUCCESS) {
        // Error handling if read fails
        WAIT_FOR_PERIPH();
        NRF_LOG_INFO("Failed to read initial firmware crc.\r\n");
      } else {
        // Successful read
        WAIT_FOR_PERIPH();
    
        downloaded_crc_val = read_buffer[0]; // Extract the read value from the buffer
        NRF_LOG_INFO("Initial firmware crc=0x%X  at: 0x%X\r\n", downloaded_crc_val, FW_CRC_ADDR);
      }
    
      //crc verification on external image
      uint16_t firmware_blocks = image_size / FIRMWARE_BLOCK_SIZE;
      uint8_t rest_block = image_size % FIRMWARE_BLOCK_SIZE;
      uint32_t computed_crc = 0; 
    
    
      for(uint16_t i=0; i <= firmware_blocks; i++)
      {
    
        uint8_t m_buffer_rx[FIRMWARE_BLOCK_SIZE];
    
        if(i == firmware_blocks)
        {
            if(nrf_drv_qspi_read(m_buffer_rx, rest_block,FIRMWARE_FLASH_ADDR + (FIRMWARE_BLOCK_SIZE * i)) != NRFX_SUCCESS)
            {
                WAIT_FOR_PERIPH();
                NRF_LOG_INFO("\r\nFailed read data blocks in Ext Flash.\r\n");
            }
            else
            {
                WAIT_FOR_PERIPH();
                computed_crc = crc32_compute(m_buffer_rx, rest_block, &computed_crc);
            }
        }
        else
        {
            if(nrf_drv_qspi_read(m_buffer_rx, FIRMWARE_BLOCK_SIZE,FIRMWARE_FLASH_ADDR + (FIRMWARE_BLOCK_SIZE * i)) != NRFX_SUCCESS)
            {
                WAIT_FOR_PERIPH();
                NRF_LOG_INFO("\r\nFailed read data blocks in Ext Flash.\r\n");
            }
            else
            {
                WAIT_FOR_PERIPH();
                computed_crc = crc32_compute(m_buffer_rx, FIRMWARE_BLOCK_SIZE, &computed_crc);
            }
        }
      }
      
      NRF_LOG_INFO("Computed QSPI CRC: 0x%X\r\n", computed_crc);
    
      if(computed_crc == downloaded_crc_val)
      {
          ret_val = image_copy(target_addr, src_addr, length_left, NRF_BL_FW_COPY_PROGRESS_STORE_STEP);
          if (ret_val != NRF_SUCCESS) {
            NRF_LOG_ERROR("Failed to copy firmware.");
            return ret_val;
          }
      }
      else
      {
          NRF_LOG_INFO("ERROR: CRC mismatch app activation failed");
          s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_VALID_APP;
          s_dfu_settings.bank_current == NRF_DFU_CURRENT_BANK_0;
          re_start = true;
          ret_val = NRF_ERROR_INVALID_DATA;
          return ret_val;
      }
    
      // Check the CRC of the copied data. Enable if so.
      crc = crc32_compute((uint8_t *)nrf_dfu_bank0_start_addr(), image_size, NULL);
      
      if (crc == s_dfu_settings.bank_1.image_crc || crc == downloaded_crc_val || crc == computed_crc) {
        NRF_LOG_DEBUG("Setting app as valid");
        s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_VALID_APP;
        s_dfu_settings.bank_0.image_crc = crc;
        s_dfu_settings.bank_0.image_size = image_size;
      } else {
        NRF_LOG_ERROR("CRC computation failed for copied app: "
                      "src crc: 0x%08x, res crc: 0x%08x",
            s_dfu_settings.bank_1.image_crc,
            crc);
      }

Related