-
Notifications
You must be signed in to change notification settings - Fork 28
Replacing Nordic DFU bootloader
While it is typically possible to upgrade bootloader and softdevice via Nordic (secure or legacy) DFU procedure sometimes this may not work at all (by design) or may be too risky and fragile and you may end up with bricked device when trying. Some examples:
-
Relocating bootloader to different address is not possible via DFU. Flashing bootloader package with bootloader made for different address will brick your device. This is due to bootloader address being stored in UICR register at location
0x10001014
which cannot be changed via DFU procedure (there is no code for it in the bootloader). Also there is no information in DFU package about bootloader start address so new bootloader will be written to wrong address it is not compiled for and will crash when started. -
Switching between dual bank and single bank bootloader seems to be not possible too. Most probably it is due to different structures used for storing update progress see also similar issue described here
-
Missing MBR settings stored at
0x10001018
UICR address, this still allows updating application but when trying softdevice or bootloader update the procedure hangs becasue MBR needs to overwrite bootloader or softdevice and cannot do this without MBR settings. This is the case with DaFit watches and also iBAND watches (F07,F10, DK08)
Fortunately with few tricks it is possible to safely erase/update/relocate bootloader over bluetooth while the application is running. Any application can do it, one example is DaFit watch bootloader installer, here I will describe how it can be done via Espruino.
Boot procedure is described in reply here and also in SDK documentation. Both Softdevice and Bootloader is optional. You can have just the application without softdevice or softdevice and application without bootloader. So one procedure to update bootloader in few steps is:
- Disabling bootloader via clearing
0x10001014
UICR address. After reboot application will continue to run without any bootloader being part of boot sequence. - Erasing existing bootloader and storing new bootloader to flash memory.
- Updating UICR to point to new bootloader.
These steps can be done in one step or with application reboot between each step.
UICR is stored in special flash page but same rules apply as erasing and writing ordinary flash pages - it is only possible to clear bits (change 1 to 0) and there are limits for number of writes to single page before erase is needed. So to reset bootloader start address whole UICR page must be cleared.
Another issue is that while SoftDevice is running some hardware registers are protected from writing for stability reasons and NVMC flash controller is one of them. This is mainly because CPU is completely halted while flash memory writing or erasing is done and this would interrupt bluetooth timing. So to allow writing to flash SoftDevice implements API which does the writing in small steps between radio traffic. And unfortunately there is no SoftDevice API to write or erase UICR registers!
So the only way to write and erase UICR registers is to temporarily stop Bluetooth and disable SoftDevice. With small patch this is possible to do with Espruino in relatively easy and safe way. Espruino already allows to restart SoftDevice because some changes in Bluetooth configuration cannot be done without it, so the patch implements executing custom javascript method between stopping and starting it. In such method direct access to NVMC controler is possible and writing and erasing UICR is possible via few poke32
calls.