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

Adding conditions for DFU

Hi, 

I am doing some customization for the secure DFU example (SDK15) and i want to add conditions for the update process (battery level for example).

I wonder if there is a place in the code where you recommend to add these conditions? 

Thanks in advance, 

Danny

Parents
  • Hello Danny,

    The easiest way would be to do this from main(), and simply skip nrf_bootloader_init() if the battery level is too low. However there are some cases where it wouldn't make sense to skip the DFU mode even if the battery is low, e.g. if there is no valid application on the chip.

    I suggest that you look in the file nrf_bootloader.c, function nrf_bootloader_init(nrf_dfu_observer_t observer).

    This is where the bootloader decides whether to enter DFU mode or not. If the check "if (dfu_enter)" is true, it will enter bootloader mode, so you want to do this check before this, so that you can set dfu_enter = false.

    The activation results are:

    ACTIVATION_NONE, //!< No new update was found.
    ACTIVATION_SUCCESS, //!< Update was successfully activated.
    ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE, //!< Update was successfully activated, but there might be additional update(s) to be transferred.
    ACTIVATION_ERROR, //!< Activation of an update failed.

    ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE means that the softdevice has been updated, and the chances are that if you run the old appliation, it may crash, and it may be difficult to get back into bootloader mode if you run directly to the application. In this case, you should always run into DFU mode.

    If you get ACTIVATION_SUCCESS, you should also let it reset. Don't interfere with this case. It means that there were no firmware to activate. You probably have a valid app, and it will reset and start the app. 

    If you get ACTIVATION_NONE,  you want to check what the reason it want to go into DFU is: So depending on what happens inside dfu_enter_check, you need to decide for each case:

    if (!nrf_dfu_app_is_valid(crc_on_valid_app_required())) // you don't have a valid app to start. No point in reading battery. The device will re-enter the bootloader with the same result the next time either way.

    if (NRF_BL_DFU_ENTER_METHOD_BUTTON &&
    (nrf_gpio_pin_read(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN) == 0)) // you probably have a valid app, but the DFU button was held during startup. Here you can override this decision.

    if (NRF_BL_DFU_ENTER_METHOD_PINRESET &&
    (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk)) // you probably have a valid app. You can override this decision.

    if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
    (nrf_power_gpregret_get() & BOOTLOADER_DFU_START)) // The DFU was probably requested by buttonless dfu. You can override this. Just make sure that your mobile app (if you use buttonless dfu) has a timeout.

    if (NRF_BL_DFU_ENTER_METHOD_BUTTONLESS &&
    (s_dfu_settings.enter_buttonless_dfu == 1)) // same as above. I don't know the difference between these.

    The function will return false if none of the above are true, and the bootloader will start the application. No need to interfere.

    All of the checks above are described in dfu_enter_check() in nrf_bootloader.c.

    Best of luck, and best regards,

    Edvin

  • Hi, 

    Thank you for the very detailed answer. 

    I understand the way to condition the DFU mode itself. However it is not what i want. 

    I want to add conditions for the update itself and not the DFU mode. 

    In example i want to allow the user to enter DFU mode but prevent the update from starting (like for example when the init package is with incorrect data)

  • Now I don't understand what you are meaning. Do you want to add the battery level requirement in the DFU packet instead of in the bootloader?

  • Basically what i want to do is to allow the user to enter DFU mode without conditioning. I am using NRF_BL_DFU_ENTER_METHOD_GPREGRET as the method to enter

    After that I want to check the battery level and allow the user to update only if the level is enough or if a charger is connected. I want the conditioning to happen when an update request is being sent to the device, not as part of the DFU packet but in the stage it is being sent. 

  • Ok. So you want to do it in the application, rather than in the bootloader?

    Well. Then I guess you just have to check the battery level before you enter DFU mode from the application. Now, I can't tell you exactly where that is, because it depends on your application, but in the ble_app_buttonless_dfu example, it would be somewhere around the on_hvc() in ble_dfu.c.

    This is where it starts to prepare for DFU mode. 

    Is this where you want it?

Reply
  • Ok. So you want to do it in the application, rather than in the bootloader?

    Well. Then I guess you just have to check the battery level before you enter DFU mode from the application. Now, I can't tell you exactly where that is, because it depends on your application, but in the ble_app_buttonless_dfu example, it would be somewhere around the on_hvc() in ble_dfu.c.

    This is where it starts to prepare for DFU mode. 

    Is this where you want it?

Children
No Data
Related