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

How to make sure that the Bootloader starts in DFU mode if a valid app is not present?

Hi,

I am trying to implement a Single Bank DFU over Bluetooth for my nRF51822 (256KB / 16KB RAM) using SDK v7.1 and Softdevice 110. I am using GCC to compile the bootloader and in order to switch from dual bank (which I was doing previously before my application size did not allow it anymore) to single bank mode, I changed from dfu_dual_bank.c to dfu_single_bank.c in the Makefile. The complied bootloader works fine as I can upload new firmware onto the chip using FOTA. But, if however the process is interrupted, the chip bricks and has to be flashed again.

I figured out that upon load, the bootloader checks if the app present in the chip is valid by comparing its crc16 checksum with the checksum saved in the bootloader settings. I believe that here lies my problem because if this check failed after an unsuccessful FOTA attempt, the chip should remain in DFU mode but that is not the case. Can anybody shed some light into where the problem may lie?

Any response is much appreciated.

-ashakya

  • The bootloader in SDK v8.0 might not be compatible to be compiled out of the box with SDK v7. But I don't think there is any reason it shouldn't work after some modification to make it works with older Softdevice (softdevice APIs may slightly change).

  • Right now, I am on my last attempt to compile a (working as expected) bootloader from SDK v7. I still have the problem that if the DFU is somehow stopped, the firmware bricks, even when the DFU is in dual bank mode. I am really trying, and failing, to find the relevant code that sets the behavior of the bootloader to avoid this problem. I suspect it has something to do with the assembly code in bootloader_util_reset but cannot be sure. If you could shed some light in this matter, it would be great. Anyway, I will continue with it and see if I can find what is not correct. If I cannot find the problem, I will attempt to use SDK v8 as you suggest.

    Thanks for your answer.

  • @ashkya: You may want to have a look at my FAQs here.

    Section A and E is recommended.

    I would suggest you to use GDB to step in to the code and check why the application doesn't start. Also you can do hex dump and compare before and after a failed DFU to see what changed. Check if the original application image has been wiped out or modified or not.

  • Hi Hung, I have determined the problem and it is as I suspected. After a failed DFU OTA (I quit the app when the firmware is transferring), I read the bootloader settings from the chip. They were:

    0x0003FC00: 00000001 00000000 00000000 00000000   |................|
    0x0003FC10: 00000000 00000000 00000000 00000000   |................|
    

    From what I understand, the DFU before it starts should set the bank_0 to BANK_INVALID_APP or BANK_ERASED such that if the DFU fails we know that a new application has not been uploaded. But from what we see here, that is not the case. Also, the CRC for the app is not set. If I then erase the page at 0x3fc00 and then write 0xFF(BANK_INVALID_APP) then DFU starts as expected.

    So what I need help with is to isolate the code which sets the bootloader settings at the start of the DFU and make sure it does its job.

  • Hi Ashkya,

    I guess the issue happens created because of the port from dual bank to single bank. When we do dual bank, we will not set the application as INVALID when we are receiving the image. This way when there is any issue when transferring the image, we can always revert to the original application. We set it right before we erase the application bank to swap with the new image.

    Where in your code you erase bank 0 to receive the new image ?

    If you have a look here at line 142 you can see when I erase bank 0 (pstorage_raw_clear) and then write to bootloader setting to mark that the application is invalid (bank0 =BANK_INVALID_APP) with the call bootloader_dfu_update_process(update_status); at line 157

Related