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

MBR after DFU not working

Hi,

I am currently working on an internal dfu modeled after the secure_bootloader_uart/ example in SDK 15.3.0. I have gotten the dfu to perform a successful dfu with the blinky example, but the application does not start. I have compared the output to the output of the secure_bootloader_uart_debug/ example and I find no unexpected differences. What I ended up doing to make sure that the blinky example is correct is using nrfjprog --sectorerase --program mbr_nrf52_2.4.1_mbr.hex and press the reset button and it works. This leads me to believe that some how the MBR is being disabled or needs to be reenabled, but I do not know how to do this or if this is actually the case. I checked to see if the MBR was being overwritten and that is not the case. If anyone has any ideas as to how I should go about fixing this, please let me know!

Parents
  • Hi 

    Are you using one of the standard Nordic development kits?
    If so, which one?

    When the DFU operation works with the blinky example, how do you send the update to the board?

    Best regards
    Torbjørn

  • I am using the nrf52840 dk with the 15.3.0 SDK. The way I am currently doing it is storing the update in the external memory. When the bootloader goes into dfu mode, it will check specific addresses in external memory for the init packet and the firmware packet. When they are found, the dfu will do the same protocol as it would in the secure_bootloader_uart/ example, but instead it will copy from external and write to flash memory. Sending the update to the external memory is done in the application, which I will be working on after I can get the dfu to work with the external memory. So far, I am only focusing on getting the dfu to work.

Reply
  • I am using the nrf52840 dk with the 15.3.0 SDK. The way I am currently doing it is storing the update in the external memory. When the bootloader goes into dfu mode, it will check specific addresses in external memory for the init packet and the firmware packet. When they are found, the dfu will do the same protocol as it would in the secure_bootloader_uart/ example, but instead it will copy from external and write to flash memory. Sending the update to the external memory is done in the application, which I will be working on after I can get the dfu to work with the external memory. So far, I am only focusing on getting the dfu to work.

Children
  • Hi 

    The MBR is stored in the first 4k of the flash. Have you tried to read out the content of this region after running your custom bootloader, and see if it changes once you run 'nrfjprog --sectorerase --program mbr_nrf52_2.4.1_mbr.hex' ?

    If there is no change I don't understand how programming the MBR would fix the issue. 

    Also, are you able to debug your bootloader application?

    Then you can check if something goes wrong when the bootloader tries to load the application, and you can also verify that the start address of the application is correct (0x1000 I assume, if the application starts just after the MBR region).  

    Best regards
    Torbjørn

  • Hi, 

    I did as you said and see that there is one line of code that is different between my internal dfu program and when I manually reprogram the MBR after it. I am attaching a picture of the hex file compare result I used to compare the content.

      

    On the left is the code after I reprogram the MBR and is working while on the left is the code read after the internal dfu is performed. I do not know where the first line of code is coming from since nowhere in my external memory does that line of code exist as seen in the mem.hex file attached. 

     8664.mem.hex

  • Hi

    Then I assume it must be the internal DFU that is somehow writing to address 0xFF8, inside the MBR region?

    Do you have a check in the code to verify that you are not writing outside the application area? 

    Maybe you could try to debug the bootloader when it is running to verify if or when it tries to write to this region?

    Best regards
    Torbjørn

  • Hi,

    I was able to program the debugger onto my board and before executing anything, and it turnd out that 0xFF8 is written to when programming the bootloader code onto the nrf52840 DK. Afterwards I did a comparison between the flash output of my internal bootloader and the secure_uart_bootloader/ example and found that they both have the same flash read values for the MBR and the application code, including address 0xFF8, yet the secure_uart_bootloader example works while the internal does not. So going back to my original question, is there anything that needs to be done in the bootloader to activate the MBR? If not is there any other possible reason why this is occurring that you could think of?

    I also debugged the internal dfu and see that it is in fact starting at the 0x1000 as it is supposed to. I am attaching the debug output below

    <info> app: Inside main
    <debug> app: In nrf_bootloader_init
    <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    <warning> nrf_dfu_settings: Resetting bootloader settings since neither the settings page nor the backup are valid (CRC error).
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 0
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x20003D2C, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x200040AC, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0
    <debug> app: Enter nrf_bootloader_fw_activate
    <info> app: No firmware to activate.
    <info> app: Boot validation failed. No valid app to boot.
    <debug> app: DFU mode because app is not valid.
    <info> nrf_bootloader_wdt: WDT is not enabled
    <debug> app: in weak nrf_dfu_init_user
    <debug> app: timer_stop (0x2000005C)
    <info> app: Entering DFU mode.
    <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_MTU_GET
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_SELECT (command)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (command)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (command)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (command)
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (command)
    <debug> nrf_dfu_validation: PB: Init packet data len: 62
    <debug> app: Enter nrf_dfu_cache_prepare()
    <debug> app: required_size: 0x5E4.
    <debug> app: single_bank: false.
    <debug> app: keep_app: false.
    <debug> app: keep_softdevice: false.
    <debug> app: SD_PRESENT: false.
    <debug> app: Bank contents:
    <debug> app: Bank 0 code: 0x00: Size: 0x0
    <debug> app: Bank 1 code: 0x00: Size: 0x0
    <debug> app: pass: 0.
    <debug> app: cache_address: 0x1000.
    <debug> app: cache_too_small: false.
    <debug> app: keep_firmware: false.
    <debug> app: delete_more: false.
    <debug> nrf_dfu_validation: Write address set to 0x00001000
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x20003D2C, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x200040AC, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0
    <debug> nrf_dfu_req_handler: Writing valid init command to flash.
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_SELECT (data)
    <debug> nrf_dfu_req_handler: crc = 0x0, offset = 0x0, max_size = 0x1000
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_CREATE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x00001000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x00001000, pending 0
    <debug> nrf_dfu_req_handler: Creating object with size: 1508. Ofa)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x20003D2C, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x200040AC, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0
    <debug> nrf_dfu_req_handler: All flash operations have completed. DFU completed.
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> app: Resetting bootloader.
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <info> app: Inside main
    <debug> app: In nrf_bootloader_init
    <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    <debug> nrf_dfu_settings: Using settings page.
    <debug> nrf_dfu_settings: Copying forbidden parts from backup page.
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <debug> app: Enter nrf_bootloader_fw_activate
    <debug> app: Valid App
    <debug> app: Enter nrf_dfu_app_continue
    <debug> app: No copy needed
    <debug> app: Setting app as valid
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 0
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x20003D2C, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x200040AC, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0
    <debug> app: Resetting bootloader.
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <info> app: Inside main
    <debug> app: In nrf_bootloader_init
    <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    <debug> nrf_dfu_settings: Using settings page.
    <debug> nrf_dfu_settings: Copying forbidden parts from backup page.
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <debug> app: Enter nrf_bootloader_fw_activate
    <info> app: No firmware to activate.
    <debug> app: App is valid
    <warning> nrf_dfu_settings: No additional data erased
    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    <debug> app: Running nrf_bootloader_app_start with address: 0x00001000
    <debug> app: Disabling interrupts. NVIC->ICER[0]: 0x0
    

  • Hi Amarin, 
    I'm taking over the case from Torbjørn. 
    As you have noticed, the address 0xFF8 is written when you flash the bootloader (at least in the stock bootloader). What written at address 0xFF8 is the address of the bootloader. Note that the bootloader address is written at 2 locations: inside the MBR (0xFF8) and UICR (for backward compatibility). 

    In your case I'm not so sure what could be wrong. But you need to verify that the bootloader is running after you do DFU. You can try testing with the debug bootloader and put a breakpoint or you can use logging. 

    After that you verify if the bootloader jumps to the application at address 0x1000. You can test with very simple application, for example the MBR blinky example. 

    If it jumped to the application but the application doesn't run, we need to compare the flash hex dump to see if the new image copied to 0x1000 matched with the image you write using nrfjprog. If it doesn't match, there must be something wrong when copying the image from the xternal flash to the internal one. 

Related