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

OTA DFU: CRC Error Fixed after re-program bootloader

situation:

We are developing an nRF51 application with OTA DFU. we use SDK 9.0.0 and the DFU bootloader version is v8. We have prepared different two packages. Single OTA DFU works with the each package. Other conditions are as follows:

  • IC: nRF51822 CEAA
  • softdevice: s110
  • bootloader: built ourselves based on SDK 9.0.0 example with gcc
    • Difference with example code: RAM layout, GPIO pin layout, Clock source to internal, BLE Tx power
  • OTA DFU packaging: pc-nrfutil
  • Controller of OTA DFU: iOS nRF Toolbox

symptoms:

  • When we try OTA DFU with one package after other package is already updated, CRC error is responded. And OTA DFU does not work any more even with the first package.
    • works: Package A -> Package A -> Package A -> ...
    • works: Package B -> Package B -> Package B -> ...
    • not works: Package A -> Package B, not work any more even with A
    • not works: Package B -> Package A, not work any more even with B
  • After erase the all images and re-program bootloader via JLink, we can use OTA DFU.

Because of this symptoms, we can update the firmware only once with OTA. Do you have any ideas?

  • It seems to have failed that the bootloader erase flash for preparing swap before receiving application or bootloader image.

    Reason I think so:

    When I edit bootloader code to skip CRC check and I do OTA DFU with packages that just different device name with three characters, it almost works but the device name is strange. The device name become close from "ZZZ" to "AAA".

  • I solved the problem by replace pstorage_platform.h of bootloader to example one. However, I don't know which configuration caused the symptoms for now.

  • The Workaround Fix: Edit dfu_types.h and change DFU_APP_DATA_RESERVED from 0 to 0x6000 and rebuild your bootloader.

    I had the exact same problem today and tracked it down to a bug in the bootloader erase functionality when your device has 256K Flash. It works fine on a 128K device.

    The dfu_prepare_func_swap_erase function attempts to erase a swap area to temporarily store the image. It calculates the size of the swap area by subtracting the size of the Softdevice and the bootloader from the total (256K) and dividing by two. In my case this worked out to DFU_IMAGE_MAX_SIZE_BANKED=0x12000.

    This gets passed to pstorage_clear which has a uint16_t for the size parameter, resulting in the erase size getting truncated to 0x2000. As a result, only 0x2000 bytes are being erased instead of 0x12000 which causes a CRC error when an app larger than this updates since the entire region has not been erased.

    I ended up setting DFU_APP_DATA_RESERVED 0x6000 to consume some extra space in the calculations and I'm now able to update apps and bootloader OTA from either the android app or the PC based Master Control Panel app.

    A better fix would be to fix the erase function to erase more than 0x10000 bytes but the above fix was easier and quicker for me.

  • Ran into a similar issue here.

    As GlennEngel noted, the issue is related to erasing the swap area. And as R. Kawajiri noted replacing pstorage_platform.h with an example resolved his issue. The confluence of these observations revealed that pstorage_size_t is important when attempting to use pstorage for large data blocks. The bootloader examples properly define it as uint32_t, but many of the application examples use uint16_t. You'll need something like this in your bootloader pstorage_platform.h:

    typedef uint32_t pstorage_size_t;      /** Size of length and offset fields. */
    

    Thanks for pointing the way, all.

  • This worked for me too.l A much cleaner fix than mine. Hopefully Nordic has some mechanism to update all their examples with the correct pstorage_size_t definition!

Related