nRF5 SDK is not maintained anymore
More Info: Consider nRF Connect SDK for new designs
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Customize bootloader to rollback OTA DFU

Hi,

I've been requested a feature regarding buttonless OTA DFU that I'm not sure if it's feasible or advisable to implement.

The feature is that once the OTA is successful and the new application has been successfully flashed, we should check if the app can connect to the client application. If it can not secure a connection due to a bug in the new app, it should rollback the app to the previous app. Since it can not connect to the client, it should store the old app in a "Bank 2" before flashing the new app from Bank 1 into Bank 0. This assumes that there is enough flash memory to store 3 copies of the app. Does this procedure make sense? Is it feasible to implement with the secure bootloader?

How could this be handled in a different way? I think a timer to check if connection is possible (similar to a watchdog timer) and if not send device to bootloader mode for OTA DFU could be an easier approach to implement.

Thanks in advance.

Parents
  • Hi Alberto, 

    I think its feasible and there are multiple alternatives to achieve what you want. Here is the list I can think of: 

    1. Do what you are planning, divide the flash into 3 banks and before you swap the application with the new image you copy the original application to "bank 2".

    2. In stead of using 3 bank you can use 2 banks and copy the original image back to bank 1. You can use one swap page to temporarily store the page you want to copy from bank 0 to bank 1 when overwriting the page on bank 0. 

    3. Third option, is to simply use the phone to revert the image back to the original one via DFU update. This requires you to have a way to enter DFU mode even if the application failed. A physical button would works. You can hold the button when reset to enter DFU mode. Or you can configure a period of time (5 second for example) when you boot up to stay in DFU mode and wait for the phone to connect. 

    Doing option 1 or 2 would require you to significantly change how the swap process works on the bootloader. But I don't see any reason that it would work. Option 1 will limit the size of the application as you would need to divide the flash into 3 parts. 

  • Hi Hung,

    Thank you for your answer.

    Since my board has no buttons available, option 3 would require to enter the DFU mode from the application. My idea would be that if the new application can not secure a connection in (for example) 5 seconds after flashing, it should go into DFU mode and the old application should be uploaded over BLE. Is that the same procedure you are describing?

    I understand that option 3 would the easier to implement that 1 or 2. Do you see any added benefits of options 1 or 2 over option 3?

  • Hi again,

    My idea was that if you dont have a button, you can configure the bootloader so that when you power up the device it will stay in the bootloader mode for 5 seconds, advertising and wait for a connection from the phone. If the phone connect before 5 seconds elapse it will start to do DFU update (so that you can revert to previous application image). If there is no connection the bootloader will continue to start the application. 

    The main draw back of this approach is that you have longer booting up time, an addition of 5 seconds. And it wouldn't work if your device is a battery powered device and never supposed to be reset in its lifetime. 

  • Hi,

    The device is battery powered so this approach could not quite work exactly like that.

    However, I think that if when the new app is initialized after OTA DFU and the connection can not be successful with the central device, sending the device into DFU mode would work as a way to fix for this issue, no?

  • Hi Alberto, 
    The device is battery powered but does it has a power button on it ? So that you can turn off and on the device ? 

    If the connection can not be successful with the central device with the new firmware, how would you put the device to DFU mode ? It's the main challenge here. 

  • Hi,

    The device does not have a button for power on/off. It will be turned off during charging. Based on this discussion, I have tested that I can send the device to DFU mode by calling ble_dfu_buttonless_bootloader_start_finalize();NVIC_SystemReset();.

    If when initializing the device after an OTA DFU update, the application can not connect to the central device in 5 seconds, I would call these 2 methods and the device goes into DFU mode.

    I have checked that the device goes into DFU when calling those 2 commands.

  • Hi Alberto, 

    Yes you can put the device in DFU with these call. However, you are making the assumption that the application can run normally and can trigger the reset after 5 seconds without central connection. But if there is a case that the application crashed before that (if it couldn't boot, or when booting it assert for some reason) then it's not possible to switch to DFU mode. 

    In addition, what if the central couldn't reconnect within 5 seconds for some reason (use turn off the app , or Bluetooth signal was not strong enough) then the device will enter DFU. 

    If you choose to do 5 seconds staying DFU mode when booting, then it would not be dependent on the new application as it's the bootloader handing this first phase of booting. 

Reply
  • Hi Alberto, 

    Yes you can put the device in DFU with these call. However, you are making the assumption that the application can run normally and can trigger the reset after 5 seconds without central connection. But if there is a case that the application crashed before that (if it couldn't boot, or when booting it assert for some reason) then it's not possible to switch to DFU mode. 

    In addition, what if the central couldn't reconnect within 5 seconds for some reason (use turn off the app , or Bluetooth signal was not strong enough) then the device will enter DFU. 

    If you choose to do 5 seconds staying DFU mode when booting, then it would not be dependent on the new application as it's the bootloader handing this first phase of booting. 

Children
  • Hi again.

    I tried answering earlier but for some reason the "reply" button seems to appear and disappear at will.

    In the case that the application would crash, if a watchdog timer is in place, it should take the device into DFU mode, isn't it? Then, that case would be covered.

    In the second case, if the user turned off the app or something similar after an OTA update, then it would go into DFU indeed. But the timeout would happen in 2 minutes and the app would be started so I don't think it would be a big problem.

    The problem I see with staying in DFU mode when booting for 5 seconds is that it is not testing whether the application itself can connect to the central device. What I am worried about is that the new app would not be able to connect to the central device for some misconfiguration of BLE parameters or wrongly called methods. In that case, the device would not be able to be sent into DFU mode because it can not connect and the application itself is not crashing.

  • Hi again, 

    Yes, the watchdog can bring the device to the bootloader. But the bootloader may just start the application again and you will end up in a infinite loop. If there isn't a "5 seconds advertising" at bootloader booting, it would not be possible to connect and do DFU update. Usually the fall back is to have a button pressed and hold when booting to retain in DFU mode but I guess it's not an option for you. In your case you can think of checking the reset reason, if it's watchdog reset then you can start DFU. 

    alberto. said:
    The problem I see with staying in DFU mode when booting for 5 seconds is that it is not testing whether the application itself can connect to the central device. What I am worried about is that the new app would not be able to connect to the central device for some misconfiguration of BLE parameters or wrongly called methods. In that case, the device would not be able to be sent into DFU mode because it can not connect and the application itself is not crashing.

    I see what you meant here, but 5 seconds could be too short to me. I would suggest to try 30seconds to give good user experience. But I guess you would know your application better than me :) 

  • Hi Hung,

    Thanks a lot for all your answers.

    Isn't it so that after the watchdog reset, the DFU mode will be active for 2 minutes (set at #define NRF_BL_DFU_INACTIVITY_TIMEOUT_MS 120000). So there should be a 2 minute window for DFU advertising that the user can connect to the DFU target, no? I believe that has been what I have experienced during testing. After those 2 minutes, the application will start again if it is valid.

    Yes, I agree there should be enough time in DFU mode before starting the app again Slight smile I'm guessing the reason why I have seen those 2 minutes before the timeout was because I called ble_dfu_buttonless_bootloader_start_finalize(); before NVIC_SystemReset();. I assume that it would be possible to do the same from the watchdog reset.

  • Hi Alberto, 

    As far as I know the bootloader wont automatically enter DFU mode if the reset was because of the watchdog. You may want to implement that. It should be added in function dfu_enter_check() in nrf_bootloader.c 

    The bootloader timeout after 2 minutes if the DFU mode is entered, but for normal booting it won't enter DFU mode. 

    Calling ble_dfu_buttonless_bootloader_start_finalize() will write to GPREGRET and will put the bootloader to DFU mode as  you can find in the dfu_enter_check() function. 

  • I see, I understand now what you meant about the 5 seconds after booting to enter DFU mode. It could be certainly be an option. First, I will try to modify the bootloader to use this new Bank 2 for the old app. If I fail, I will look into these other methods.

    I think app_activate() would be the best method where to copy the old app in Bank 0 to the new Bank 2 just before the new app in Bank 1 is copied to Bank 0. Or maybe adding another case in nrf_bootloader_fw_activate() could make more sense.

Related