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

trouble with nrf_dfu_mbr_copy_bl

Hi,

I'm trying to implement a custom bootloader update on the nRF52840 using SoftDevice s140 and SDK 13.0.0. With my new bootloader staged in a scratch region of flash, I'm trying to use nrf_dfu_mbr_copy_bl() to copy the new bootloader. The relevant code is:

res = nrf_dfu_mbr_compare( bootloader_address, scratchpad_address, update_len );
if ( NRF_SUCCESS != res )
{
  res = nrf_dfu_mbr_copy_bl( scratchpad_address, update_len );
}
else
{
  scratchpad_erase();
}

What happens is nrf_dfu_mbr_copy_bl() triggers a reset (as expected), but the next time around nrf_dfu_mbr_compare() still returns NRF_ERROR_NULL, and so the device continually calls nrf_dfu_mbr_copy_bl() and resets. Is there some initialization I'm missing? Do I need to disable the SoftDevice before doing this? I'm not using anything else from the DFU module, and I have the bootloader start address and MBR params page programmed into UICR. Any help would be appreciated!

Update 2017/8/7:

As I mentioned in the comments below, the behavior I'm seeing now is rather than constantly resetting, the code gets stuck in nrf_dfu_mbr_copy_bl(). Attaching a debugger I see I'm getting a hard fault. It appears to be a bus fault at address 0x10040013 that is escalated to a hard fault. Stack dump is:

r0	0x20000400
r1	0x000008E5
r2	0x00000579
r3	0x000008C5
r12	0x00000583
lr	0x0000058D
pc	0x00000597
psr	0x00000000

Update 2017/8/8:

I've reproduced the problem with a really simple project: copy_bl_test.zip

  • We need to see how you call the nrf_dfu_mbr_copy_bl(). Can you create a simple example where you have a minimum bootloader that do only one task: replace it self ? You then can flash a dummy bootloader in the swap area and let the bootloader to replace it with the dummy one. If you can reproduce the issue with that example, the it would be possible for us to dig down to the MBR to see what wrong.

  • Ok, I was able to create a simple project like you described, and I get exactly the same behavior as in my main project (same hardfault after call to nrf_dfu_mbr_copy_bl(), same stack dump). It's attached to the question.

  • I am able to reproduce this with Steve's example project.

    It certainly looks like the HardFault occurs while the MBR is updating its PARAMS page. The data at 0xd2000 doesn't get disturbed so the MBR is encountering the problem and hanging on the next reset. The troublesome PARAMS page looks like this:

    0x000FE000: 0065C007 FFFFFFAA 200047E0 00010000 0x000FE010: 000FE000 00000319 00078000 FFFFFFF9 0x000FE020: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 0x000FE030: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 0x000FE040: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 0x000FE050: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 0x000FE060: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 0x000FE070: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 0x000FE080: 00000000 00078000 00004000 00000000 0x000FE090: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 0x000FE0A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 0x000FE0B0: 00000000 00004000 00078000 00000000

  • Hi Daniel and Steve,

    I also reproduced the issue here and only after that got to know the nrf_dfu_mbr_copy_bl() is not supported on nRF52840. The reason is BPROT peripheral is removed on nRF52840. If you have a look at the release note of s140_nrf52840_5.0.0-2.alpha you can find:

    The SV-calls sd_mbr_command_vector_table_base_set() and sd_mbr_command_copy_bl() are not supported (DRGN-8197). Using these calls leads to undefined behavior.
    
  • Oh and it's in the release note of the SDK also, next time I should also read the manual :)

     - The S140 SoftDevice currently does not support updating of the bootloader.
    
Related