I've implemented a buttonless DFU with bonds, as well as a button-based DFU. These are in separate branches, but ultimately for my project, I want both ways integrated. However I can't go into the bootloader with both methods in my project. I have some questions below:
My questions are:
- How reliable is the buttonless DFU?
On the tutorial "nRF5 SDK v17.1.0 Secure DFU Hands-on Tutorial",
it mentions at the bottom "It is important if at all possible, to provide a fail-safe for the DFU process if the buttonless process becomes inoperative, usually via a programming mistake in the application code. A coding mistake that breaks the buttonless process will render the device unable to be updated".
nRF5 SDK v17.1.0 Secure DFU Hands-on Tutorial
The reason for having both a button-based approach and a buttonless approach is based on this statement, which makes sense if the device can't do a DFU then it can be useless. I assume this mainly comes from a lack of testing, before doing a DFU out to all devices in the field. But providing that the tests pass, what are the chances that the service itself stops working? - It makes sense to have both methods, with the button-based way as a backup. The problem is, this way isn't encrypted. I've seen a few posts about how to add encryption manually, but it's a bit more work that I don't have time to do. I've already tested buttonless DFU with bonds, and this works with encrypting the DFU process as the bond is kept. How can I keep bonds when going into the bootloader to do a DFU with a button-based approach?
- I've tried to merge both my branches that contain a button-based DFU and a buttonless DFU. The buttonless DFU works, but I can't go into the bootloader with the button-based method. I've had this problem before when I didn't want the do a DFU with buttonless, by clearing NRF_SDH_BLE_SERVICE_CHANGED and NRF_DFU_BLE_REQUIRES_BONDS in the bootloader SDK_Config. I'm not sure why this doesn't work, as my device resets, but just doesn't go into the bootloader. To go into DFU I manually do it by writing to the GPREGRET.
void enter_dfu_mode(void) { static uint32_t gpregret_reg; ret_code_t err_code; err_code = sd_power_gpregret_get(0, &gpregret_reg); VERIFY_SUCCESS(err_code); gpregret_reg |= BOOTLOADER_DFU_START; err_code = sd_power_gpregret_set(0, gpregret_reg); VERIFY_SUCCESS(err_code); err_code = sd_power_gpregret_get(0, &gpregret_reg); VERIFY_SUCCESS(err_code); sd_nvic_SystemReset(); }
Ultimately what I would want is to have both methods, but keep the bonds despite either method. By keeping the bonds, I'd assume that both methods would encrypt the DFU process.