Hi, I would like to share some valuable information regarding the BLE DFU (secure bootloader) and a MESH application which uses persistent storage for provisioning data. I do see there are quite a few topics on it in the devzone. There is already a comprehensive step by step guide on BLE DFU:
Although this guide helped a lot, I still could not get my application to work with a bootloader. Obviously because the setup is different as well.
Setup:
- SDK V15.3
- SDK MESH V3.10
- NRF52840 DK
- SEGGER Embedded Studio V4.12
- Softdevice S140 V6.1.1
- PERSISTENT STORAGE ENABLED (#define PERSISTENT_STORAGE 1 in sdk_config.h)
Information: MBR, UICR, Soft device
As far as my knowledge goes, when reset, the MBR (Master Boot Record) will read the UICR BOOTLOADER address. In the SDK this is the address of NRF_UICR->NRFFW[0]. If there is something in that register, the reset handler of the bootloader will be called. If there is nothing (0xFFFFFFFF for erased flash) the soft device reset handler is called which runs the application (if there is one).
Issue 1: Bootloader settings incorrect flash placement
When you create the bootloader settings (.hex file), the guide states to run the following command:
nrfutil settings generate --family NRF52 --application yourApplication.hex --application-version 0 --bootloader-version 0 --bl-settings-version 1 bootloader_setting.hex
This is not incorrect, but it is not correct for the NRF52840
Navigating to the nrfutils directory and file:
C:\Python27\Lib\site-packages\nordicsemi\dfu\bl_dfu_sett.py
This is where nrfutils decide where to place the bootloader settings in flash. Note that for --family NRF52 the settings will be placed in 0x0007F000 (line 106). For --family NRF52840 the settings are placed in 0x000FF000.
Looking at the secure bootloader flash_placement.xml file:
<MemorySegment name="bootloader_settings_page" start="0x000FF000" size="0x1000">
The settings page is read from 0x000FF000. So when generating the bootloader settings for the NRF52840, instead of:
nrfutil settings generate --family NRF52 --application yourApplication.hex --application-version 0 --bootloader-version 0 --bl-settings-version 1 bootloader_setting.hex
Use:
nrfutil settings generate --family NRF52840 --application yourApplication.hex --application-version 0 --bootloader-version 0 --bl-settings-version 1 bootloader_setting.hex
This will place the bootloader settings in the correct flash address.
The bootloader_setting.hex file can be added to nRF Connect to see the flash placement of the file. Also, you can run the secure bootloader debug version to get an output log. The log will tell you if a valid application was found or not. That should sort out the bootloader settings issue.
Issue 2: BLE Secure bootloader causes mesh application to hang
After creating the correct bootloader settings (issue mentioned above), my application was detected and executed. But the application hung up.
HEX files present on the device are:
bootloader.hex, bootloader_settings.hex, s140_nrf52_6.1.1_softdevice.hex, application.hex
The problem occurred can be explained by navigating to:
mesh_stack_init()->nrf_mesh_init()->mesh_config_init()->mesh_config_backend_init()->mesh_config_backend_glue_init()->flash_manager_init()->flash_manager_defrag_init().
In flash_manager_defrag.c line 598 if (BOOTLOADERADDR()... the application reads the NRF_UICR->NRFFW[0] register. Even with the bootloader present in flash, this kept returning 0xFFFFFFFF. This results in the wrong location of mp_recovery_area which causes an ASSERT further down the call stack.
Solution:
Read back the register with nrfjprog:
nrfjprog --memrd 0x10001014
The address returns 0xFFFFFFFF
Now write to that register with nrfjprog:
nrfjprog -f nrf52 --memwr 0x10001014 --val 0xf8000
Note that the value 0xf8000 is going to depend on FLASH_START in the SEGGER settings in section placement macros.
Read back the register and verify that the value is changed:
nrfjprog --memrd 0x10001014 should return 0xf8000 (or whatever value you have written).
It is important to note that this will only have an effect once the device is power cycled. Power cycle the device. The application was now detected and executed perfectly. Also, the correct bootloader address was set.
Now I understand that you can do this direct write to the address in your application, it does feel like a hack though. The secure ble dfu already performs that write. But when reading back that address in a debug session or nrfjprog, it is still 0xFFFFFFFF. Not sure why this is happening though. It is happening with the debug and the normal version.
Hope the information is useful:)
Regards
Chris