I'm using an SES with NRF52840, w/ SDK 15.3, and SoftDevice S140. Im working on DFU and have two components:
- a main app that already takes care of moving a FW image into BANK1 (which I've defined as 0x8a000) in internal flash
- a modified bootloader that skips over DFU transport initialization and moves straight to FW activation
TLDR; what is the proper way of flagging a new FW image is ready for activation to the bootloader?
What I've been able to do with an NRF52840 DK is:
- Manually flash a new FW image in Bank1 using nrfjprog
- Add the following code in nrf_bootloader_init. Whenever the button is pressed, dfu_settings are manually changed to flag that there is a FW image waiting to be activated in Bank1
if(nrf_gpio_pin_read(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN) == 0) { // THESE ARE BEING HARD-CODED TO FORCE FW ACTIVATION s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1; s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP; s_dfu_settings.bank_1.image_size = 1708; s_dfu_settings.progress.update_start_address = 0x8a000; s_dfu_settings.write_offset = 0; //APP_ERROR_CHECK(nrf_dfu_settings_write(NULL)); }
This successfully moves the image from Bank1 to Bank0 and starts the app. I've been able to change the pulsing duration in the blinky code example this way.
Then I tried moving this to my main app. What I did:
- import nrf_dfu_settings.c and it's dependencies
- added the memory sections for the bootloader_settings_page in the flash_placement.xml and Memory Segments in SES
- enable NRF_DFU_IN_APP and NRF_DFU_SETTINGS_COMPATIBILITY_MODE
- called nrf_dfu_settings_init(true) from my main()
- then, in my code, once the FW was validated and copied into Bank1 I wrote the same settings as above except this time calling nrf_dfu_settings_write(NULL)
//Update BL settings to signal a new valid app is ready s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1; s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP; s_dfu_settings.bank_1.image_size = scratchpad_data.app_len; s_dfu_settings.progress.update_start_address = BANK1_FLASH_ADDR; s_dfu_settings.write_offset = 0; APP_ERROR_CHECK(nrf_dfu_settings_write(NULL));
However, doing this results in the following error:
<warning> nrf_dfu_settings: Settings write aborted since it tries writing to forbidden settings. <error> app: Fatal error: 16385 <warning> app: System reset
So... what is the proper way to mimic the result I saw on the DK but doing it in the main app?