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?

Parents
  • 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.

Reply
  • 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.

Children
No Data
Related