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

Application is not loading post DFU over serial

Hello,

I am able to get a successful confirmation that my application has been updated using the nordic secure bootloader over serial code example. However, my application doesn't load. Here are the steps I followed:

1) Created an app package using cmd: nrfutil pkg generate --hw-version 52 --sd-req 0x00 --application-version 1 --application app.hex --key-file private.pem app52_1.zip

2) Erased the device and downloaded the bootloader (code based on \examples\dfu\secure_bootloader\pca10040_uart projoct.

3) Generated and programmed the setting.hex file

4) Recycled power and uploaded my app using cmd: nrfutil dfu serial -pkg app52_1.zip -p COM14 -fc 0. I got a confirmation message that the DFU is 100% done.

5) Recycled power but my app didn't load properly and neither did the bootloader. I know that because I cannot upload an app using step 3 anymore nor the correct DFU GPIO pattern is outputted.
Any ideas how to troubleshoot this issue? I did see other tickets referring to the boatload button being the issue so I disable that feature in the sdk_config.h file and still not working. I also tried to manually reset using nrfjprg --reset and that didn't help either. Any ideas? Thanks!
Parents
  • Hi,

    It is difficult to say what the problem is without knowing more. Can you test with the debug bootloader project and upload the log here? You can find the debug bootloader under <SDK>\examples\dfu\secure_bootloader\pca10040_uart_debug\. It would be interesting to see the log both during the DFU, and (even more importantly) afterward, when it should start the application. It should show what the bootloader does, and if there is an error.

  • Einar, can I enable the logger even though there is only one UART interface which is used for boot-loading? I have never used the logger before so if you can please send me the steps you need to follow that would be greatly appreciated. I read the info referenced in https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.0.0%2Flib_nrf_log.html&cp=4_0_0_3_26 and I tried to enable the logger but no luck. Also, do I have to switch to pca10040_uart_debug project or could I just stick with my project which is very similar to pca10040_uart? I see the logger as an option in the sdk_config.h file.

    Btw, I am not sure if this is related but I am experiencing the same symptom when I also try to download an example with a softdevice. 

  • Hi,

    moose said:
    Einar, can I enable the logger even though there is only one UART interface which is used for boot-loading?

    Yes, but not logging over UART. Instead, you should use RTT logging. The example bootloader projects come in pairs, one with debug logging over RTT and one without. Since you have used <SDK>\examples\dfu\secure_bootloader\pca10040_uart, I would like you to try <SDK>\examples\dfu\secure_bootloader\pca10040_uart_debug instead, and observe the logs using Segger RTT Viewer.

  • Hello Einar,

    I was able to get the RTT log after getting help from @jeff.scott and here is the log for your info

     0> <info> nrf_dfu_serial_uart: Allocated buffer 20000AF4
     0> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
     0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0000D280, src=0x20000B7C, len=64 bytes), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash write success: addr=0x0000D280, pending 0
     0> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
     0> <info> nrf_dfu_serial_uart: Allocated buffer 20000B78
     0> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
     0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0000D2C0, src=0x20000AF8, len=64 bytes), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash write success: addr=0x0000D2C0, pending 0
     0> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
     0> <info> nrf_dfu_serial_uart: Allocated buffer 20000AF4
     0> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
     0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0000D300, src=0x20000B7C, len=64 bytes), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash write success: addr=0x0000D300, pending 0
     0> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
     0> <info> nrf_dfu_serial_uart: Allocated buffer 20000B78
     0> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
     0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0000D340, src=0x20000AF8, len=64 bytes), queue usage: 1
     0> <info> nrf_dfu_serial_uart: Allocated buffer 20000BFC
     0> <info> nrf_dfu_serial_uart: Allocated buffer 20000BFC
     0> <debug> nrf_dfu_flash: Flash write success: addr=0x0000D340, pending 0
     0> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
     0> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
     0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0000D380, src=0x20000B7C, len=12 bytes), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash write success: addr=0x0000D380, pending 0
     0> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
     0> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (data)
     0> <debug> nrf_dfu_req_handler: Offset:50060, CRC:0xB8C06AE1
     0> <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
     0> <debug> nrf_dfu_serial: Sending Response: [0x3, 0x1]
     0> <info> nrf_dfu_serial_uart: Allocated buffer 20000BFC
     0> <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (data)
     0> <debug> nrf_dfu_req_handler: Whole firmware image received. Postvalidating.
     0> <debug> nrf_dfu_validation: Hash verification. start address: 0x1000, size: 0xC38C
     0> <debug> nrf_dfu_validation: Invalidating old application in bank 0.
     0> <debug> nrf_dfu_serial: Sending Response: [0x4, 0x1]
     0> <debug> nrf_dfu_settings: Writing settings...
     0> <debug> nrf_dfu_settings: Erasing old settings at: 0x0007F000
     0> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007F000, len=1 pages), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash erase success: addr=0x0007F000, pending 0
     0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007F000, src=0x20000CE0, len=896 bytes), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash write success: addr=0x0007F000, pending 0
     0> <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
     0> <debug> nrf_dfu_settings: Writing settings...
     0> <debug> nrf_dfu_settings: Erasing old settings at: 0x0007E000
     0> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007E000, len=1 pages), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash erase success: addr=0x0007E000, pending 0
     0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007E000, src=0x20001060, len=896 bytes), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash write success: addr=0x0007E000, pending 0
     0> <debug> nrf_dfu_req_handler: All flash operations have completed. DFU completed.
     0> <debug> app: Shutting down transports (found: 1)
     0> <debug> app: Resetting bootloader.
     0> <info> app: Inside main
     0> <info> app: Inside main
     0> <debug> app: In nrf_bootloader_init
     0> <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
     0> <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
     0> <debug> nrf_dfu_settings: Using settings page.
     0> <debug> nrf_dfu_settings: Copying forbidden parts from backup page.
     0> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
     0> <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
     0> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
     0> <debug> app: Enter nrf_bootloader_fw_activate
     0> <debug> app: Valid App
     0> <debug> app: Enter nrf_dfu_app_continue
     0> <debug> app: No copy needed
     0> <debug> app: Setting app as valid
     0> <debug> nrf_dfu_settings: Writing settings...
     0> <debug> nrf_dfu_settings: Erasing old settings at: 0x0007F000
     0> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007F000, len=1 pages), queue usage: 0
     0> <debug> nrf_dfu_flash: Flash erase success: addr=0x0007F000, pending 0
     0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007F000, src=0x20000CE0, len=896 bytes), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash write success: addr=0x0007F000, pending 0
     0> <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
     0> <debug> nrf_dfu_settings: Writing settings...
     0> <debug> nrf_dfu_settings: Erasing old settings at: 0x0007E000
     0> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007E000, len=1 pages), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash erase success: addr=0x0007E000, pending 0
     0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007E000, src=0x20001060, len=896 bytes), queue usage: 1
     0> <debug> nrf_dfu_flash: Flash write success: addr=0x0007E000, pending 0
     0> <debug> app: Resetting bootloader.
     0> <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
     0> <debug> nrf_dfu_settings: D<info> app: Inside main
     0> <debug> app: In nrf_bootloader_init
     0> <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
     0> <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
     0> <debug> nrf_dfu_settings: Using settings page.
     0> <debug> nrf_dfu_settings: Copying forbidden parts from backup page.
     0> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
     0> <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
     0> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
     0> <debug> app: Enter nrf_bootloader_fw_activate
     0> <info> app: No firmware to activate.
     0> <debug> app: App is valid
     0> <warning> nrf_dfu_settings: No additional data erased
     0> <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
     0> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
     0> <debug> app: Running nrf_bootloader_app_start with address: 0x00001000
     0> <debug> app: Disabling interrupts. NVIC->ICER[0]: 0x0
    

    I also attached the prompt window output and the nrf Connect read image. Hope this help. I noticed that the logger saying the bootloader is jumping to address: 0x00001000 which doesn't match my application start address as I read it from nRFConnect read image. Not sure if this the issue.

  • Hi,

    moose said:
    I also attached the prompt window output and the nrf Connect read image. Hope this help.

    Thank you, this is useful in narrowing down the issue, though I don't understand the problem yet.

    moose said:
    I noticed that the logger saying the bootloader is jumping to address: 0x00001000 which doesn't match my application start address as I read it from nRFConnect read image. Not sure if this the issue.

    This is not a problem. The start address is always 0x1000, which is immediately after the MBR (which resides on page 0). This is correct and works the same both when using SoftDevice and not. If using DFU but no SoftDevice, the application starts at 0x1000, and that is started. If using a SoftDevice, the SoftDevice starts at 0x1000, and that will in turn forward interrupts to the application and start the application (which must start immediately after the SoftDevice, with the application start address being identical to the size of the SoftDevice).

    Everything looks good in the bootloader log, and it should have started the application. Could it be an issue in the application, that somehow is only triggered when you use a bootloader? How have you verified that the application does not load? Can you try to toggle a GPIO a few times as the very first thing you do in the application, and see if you can detect that from a logic analyzer? If you do, that would show clearly that the app is started, and then we should continue looking there.

  • Hello Eina,

    If using DFU but no SoftDevice, the application starts at 0x1000,

    I just wanted to point out that according to the nRF connect read image, my application does NOT start at location 0x1000. It show it starting at location 0x0FF8 instead. Is that okay?

    ould it be an issue in the application, that somehow is only triggered when you use a bootloader? How have you verified that the application does not load?

    When I program my application directly on an erased device (no bootloader), it works fine. I just did that again and read the image and attached it here for reference. The section in the top is my emulated eeprom user parameters. I also added my application code flash placement file for your reference.

    Can you try to toggle a GPIO a few times as the very first thing you do in the application, and see if you can detect that from a logic analyzer?

    I will do that next but I thought I send these info your way first in case it is useful.

    <!DOCTYPE Linker_Placement_File>
    <Root name="Flash Section Placement">
      <MemorySegment name="FLASH" start="$(FLASH_PH_START)" size="$(FLASH_PH_SIZE)">
        <ProgramSection load="no" name=".reserved_flash" start="$(FLASH_PH_START)" size="$(FLASH_START)-$(FLASH_PH_START)" />
        <ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START)" />
        <ProgramSection alignment="4" load="Yes" name=".init" />
        <ProgramSection alignment="4" load="Yes" name=".init_rodata" />
        <ProgramSection alignment="4" load="Yes" name=".text" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_const_data" inputsections="*(SORT(.log_const_data*))" address_symbol="__start_log_const_data" end_symbol="__stop_log_const_data" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_backends" inputsections="*(SORT(.log_backends*))" address_symbol="__start_log_backends" end_symbol="__stop_log_backends" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".nrf_balloc" inputsections="*(.nrf_balloc*)" address_symbol="__start_nrf_balloc" end_symbol="__stop_nrf_balloc" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections" address_symbol="__start_nrf_sections" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".fs_data"  inputsections="*(.fs_data*)" runin=".fs_data_run"/>
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_dynamic_data"  inputsections="*(SORT(.log_dynamic_data*))" runin=".log_dynamic_data_run"/>
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_filter_data"  inputsections="*(SORT(.log_filter_data*))" runin=".log_filter_data_run"/>
        <ProgramSection alignment="4" load="Yes" name=".dtors" />
        <ProgramSection alignment="4" load="Yes" name=".ctors" />
        <ProgramSection alignment="4" load="Yes" name=".rodata" />
        <ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
        <ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
        <ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
        <ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
      </MemorySegment>
      <MemorySegment name="RAM" start="$(RAM_PH_START)" size="$(RAM_PH_SIZE)">
        <ProgramSection load="no" name=".reserved_ram" start="$(RAM_PH_START)" size="$(RAM_START)-$(RAM_PH_START)" />
        <ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START)" address_symbol="__app_ram_start__"/>
        <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run" address_symbol="__start_nrf_sections_run" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".fs_data_run" address_symbol="__start_fs_data" end_symbol="__stop_fs_data" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".log_dynamic_data_run" address_symbol="__start_log_dynamic_data" end_symbol="__stop_log_dynamic_data" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".log_filter_data_run" address_symbol="__start_log_filter_data" end_symbol="__stop_log_filter_data" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run_end" address_symbol="__end_nrf_sections_run" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".emulated_eeprom" address_symbol="__emulated_eeprom_start" end_symbol="__emulated_eeprom_end" size_symbol="__emulated_eeprom_size"/>
        <ProgramSection alignment="4" keep="Yes" load="No" name=".emulated_eeprom_crc" address_symbol="__emulated_eeprom_crc_start" end_symbol="__emulated_eeprom_crc_end" size_symbol="__emulated_eeprom_crc_size"/>
        <ProgramSection alignment="4" load="No" name=".fast_run" />
        <ProgramSection alignment="4" load="No" name=".data_run" />
        <ProgramSection alignment="4" load="No" name=".tdata_run" />
        <ProgramSection alignment="4" load="No" name=".bss" />
        <ProgramSection alignment="4" load="No" name=".tbss" />
        <ProgramSection alignment="4" load="No" name=".non_init" />
        <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
        <ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack"  address_symbol="__StackLimit" end_symbol="__StackTop"/>
        <ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
      </MemorySegment>
    </Root>
    

Reply
  • Hello Eina,

    If using DFU but no SoftDevice, the application starts at 0x1000,

    I just wanted to point out that according to the nRF connect read image, my application does NOT start at location 0x1000. It show it starting at location 0x0FF8 instead. Is that okay?

    ould it be an issue in the application, that somehow is only triggered when you use a bootloader? How have you verified that the application does not load?

    When I program my application directly on an erased device (no bootloader), it works fine. I just did that again and read the image and attached it here for reference. The section in the top is my emulated eeprom user parameters. I also added my application code flash placement file for your reference.

    Can you try to toggle a GPIO a few times as the very first thing you do in the application, and see if you can detect that from a logic analyzer?

    I will do that next but I thought I send these info your way first in case it is useful.

    <!DOCTYPE Linker_Placement_File>
    <Root name="Flash Section Placement">
      <MemorySegment name="FLASH" start="$(FLASH_PH_START)" size="$(FLASH_PH_SIZE)">
        <ProgramSection load="no" name=".reserved_flash" start="$(FLASH_PH_START)" size="$(FLASH_START)-$(FLASH_PH_START)" />
        <ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START)" />
        <ProgramSection alignment="4" load="Yes" name=".init" />
        <ProgramSection alignment="4" load="Yes" name=".init_rodata" />
        <ProgramSection alignment="4" load="Yes" name=".text" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_const_data" inputsections="*(SORT(.log_const_data*))" address_symbol="__start_log_const_data" end_symbol="__stop_log_const_data" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_backends" inputsections="*(SORT(.log_backends*))" address_symbol="__start_log_backends" end_symbol="__stop_log_backends" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".nrf_balloc" inputsections="*(.nrf_balloc*)" address_symbol="__start_nrf_balloc" end_symbol="__stop_nrf_balloc" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections" address_symbol="__start_nrf_sections" />
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".fs_data"  inputsections="*(.fs_data*)" runin=".fs_data_run"/>
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_dynamic_data"  inputsections="*(SORT(.log_dynamic_data*))" runin=".log_dynamic_data_run"/>
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".log_filter_data"  inputsections="*(SORT(.log_filter_data*))" runin=".log_filter_data_run"/>
        <ProgramSection alignment="4" load="Yes" name=".dtors" />
        <ProgramSection alignment="4" load="Yes" name=".ctors" />
        <ProgramSection alignment="4" load="Yes" name=".rodata" />
        <ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
        <ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
        <ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
        <ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
      </MemorySegment>
      <MemorySegment name="RAM" start="$(RAM_PH_START)" size="$(RAM_PH_SIZE)">
        <ProgramSection load="no" name=".reserved_ram" start="$(RAM_PH_START)" size="$(RAM_START)-$(RAM_PH_START)" />
        <ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START)" address_symbol="__app_ram_start__"/>
        <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run" address_symbol="__start_nrf_sections_run" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".fs_data_run" address_symbol="__start_fs_data" end_symbol="__stop_fs_data" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".log_dynamic_data_run" address_symbol="__start_log_dynamic_data" end_symbol="__stop_log_dynamic_data" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".log_filter_data_run" address_symbol="__start_log_filter_data" end_symbol="__stop_log_filter_data" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".nrf_sections_run_end" address_symbol="__end_nrf_sections_run" />
        <ProgramSection alignment="4" keep="Yes" load="No" name=".emulated_eeprom" address_symbol="__emulated_eeprom_start" end_symbol="__emulated_eeprom_end" size_symbol="__emulated_eeprom_size"/>
        <ProgramSection alignment="4" keep="Yes" load="No" name=".emulated_eeprom_crc" address_symbol="__emulated_eeprom_crc_start" end_symbol="__emulated_eeprom_crc_end" size_symbol="__emulated_eeprom_crc_size"/>
        <ProgramSection alignment="4" load="No" name=".fast_run" />
        <ProgramSection alignment="4" load="No" name=".data_run" />
        <ProgramSection alignment="4" load="No" name=".tdata_run" />
        <ProgramSection alignment="4" load="No" name=".bss" />
        <ProgramSection alignment="4" load="No" name=".tbss" />
        <ProgramSection alignment="4" load="No" name=".non_init" />
        <ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
        <ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack"  address_symbol="__StackLimit" end_symbol="__StackTop"/>
        <ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
      </MemorySegment>
    </Root>
    

Children
  • Hi, 

    moose said:
    I just wanted to point out that according to the nRF connect read image, my application does NOT start at location 0x1000. It show it starting at location 0x0FF8 instead. Is that okay?

    That is just an issue with nRF Connect Programmer. Since the last two words in the MBR page contain data (which was written either when you programmed the bootloader hex or the first reset after programming the bootloader depending on SDK version), the programmer app thinks the application starts there. But that is not the case. This is not an issue.

    I suspect there is something that causes an error in the application when the bootloader runs first, but it will be interesting to see what you find when trying to verify if the application runs or not.

  • Hello Einar,

    So I did the test you asked me to do. I added the following code right after my main in my application

    int main(void)
    {
        if(!nrfx_gpiote_is_init())
          APP_ERROR_CHECK(nrfx_gpiote_init());
       
        nrfx_gpiote_out_config_t out_config = NRFX_GPIOTE_CONFIG_OUT_SIMPLE(false);
        APP_ERROR_CHECK(nrfx_gpiote_out_init(LED1_PIN , &out_config));
    
        for(uint16_t i=0; i<1000; i++)
          nrfx_gpiote_out_set(LED1_PIN);
        for(uint16_t i=0; i<1000; i++)
          nrfx_gpiote_out_clear(LED1_PIN);
        for(uint16_t i=0; i<1000; i++)
          nrfx_gpiote_out_set(LED1_PIN);
        for(uint16_t i=0; i<1000; i++)
          nrfx_gpiote_out_clear(LED1_PIN);
        for(uint16_t i=0; i<1000; i++)
          nrfx_gpiote_out_set(LED1_PIN);
        for(uint16_t i=0; i<1000; i++)
          nrfx_gpiote_out_clear(LED1_PIN);
        for(uint16_t i=0; i<1000; i++)
          nrfx_gpiote_out_set(LED1_PIN);
        for(uint16_t i=0; i<1000; i++)
          nrfx_gpiote_out_clear(LED1_PIN);

    After programming my board and resetting it, I can capture the expected LED pulses on my scope and I can repeat it every time I reset the board.

    I used nrfutil and this new app hex file to generate a new zip package, segger studio to erase and downloaded the debug boatloader and nrfutil to upload the app zip package. Here are the nrfutil commands I used. I skipped the setting.hex since I am just downloading a fresh bootloader. 

    nrfutil pkg generate --hw-version 52 --sd-req 0x00 --application-version 1 --application apppulse.hex --key-file private.pem app52_1pulse.zip
    nrfutil dfu serial -pkg app52_1pulse.zip -p COM14 -fc 0

    I was able to get a successful upload but my app is still not loading and I did not detect any LED pulses on my scope. Resetting the board does not help. How would you recommend to proceed? Please keep in mind that my app use freeRTOS. Not sure if that is a factor. Below is the log file for your reference. I did a reset at the end.

    <info> nrf_dfu_serial_uart: Allocated buffer 20000AF4
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_WRITE (data)
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0000D480, src=0x20000B7C, len=64 bytes), queue usage: 1
    <info> nrf_dfu_serial_uart: Allocated buffer 20000AF4
    <debug> nrf_dfu_flash: Flash write success: addr=0x0000D480, pending 0
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_CRC_GET (data)
    <debug> nrf_dfu_req_handler: Offset:50368, CRC:0x932409F1
    <debug> nrf_dfu_req_handler: Request handling complete. Result: 0x1
    <debug> nrf_dfu_serial: Sending Response: [0x3, 0x1]
    <info> nrf_dfu_serial_uart: Allocated buffer 20000AF4
    <debug> nrf_dfu_req_handler: Handle NRF_DFU_OP_OBJECT_EXECUTE (data)
    <debug> nrf_dfu_req_handler: Whole firmware image received. Postvalidating.
    <debug> nrf_dfu_validation: Hash verification. start address: 0x1000, size: 0xC4C0
    <debug> nrf_dfu_validation: Invalidating old application in bank 0.
    <debug> nrf_dfu_serial: Sending Response: [0x4, 0x1]
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x0007F000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007F000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x0007F000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007F000, src=0x20000CE0, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x0007F000, pending 0
    <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x0007E000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007E000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x0007E000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007E000, src=0x20001060, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x0007E000, pending 0
    <debug> nrf_dfu_req_handler: All flash operations have completed. DFU completed.
    <debug> app: Shutting down transports (found: 1)
    <debug> app: Resetting bootloader.
    <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 0x7E000.
    <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: 0x0007F000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007F000, len=1 pages), queue usage: 0
    <debug> nrf_dfu_flash: Flash erase success: addr=0x0007F000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007F000, src=0x20000CE0, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x0007F000, pending 0
    <info> nrf_dfu_settings: Backing up settings page to address 0x7E000.
    <debug> nrf_dfu_settings: Writing settings...
    <debug> nrf_dfu_settings: Erasing old settings at: 0x0007E000
    <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007E000, len=1 pages), queue usage: 1
    <debug> nrf_dfu_flash: Flash erase success: addr=0x0007E000, pending 0
    <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007E000, src=0x20001060, len=896 bytes), queue usage: 1
    <debug> nrf_dfu_flash: Flash write success: addr=0x0007E000, pending 0
    <debug> app: Resetting bootloader.
    <info> nrf_dfu_settings: Backing up settings page to address 0x7<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 0x7E000.
    <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 0x7E000.
    <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
    <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 0x7E000.
    E000.
    001000
    <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 0x7E000.
    <debug> nrf_dfu_settings: Destination settings are identical to E000.
    <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,

    This is my current understanding of the situation:

    • According to the bootloader log, the application is started and everything looks OK.
    • The applications normally toggle a GPIO at the beginning of the main, which works without a bootloader. When using a bootloader, the GPIO is not toggled indicating that the application is not started or at least not running at this point.
    • Anything happening later in your application is irrelevant (at this point) since the GPIO toggling happens first. (So the FreeRTOS scheduler is not started yet, and thus this can be disregarded for).

    I find this a bit strange and would like to try to debug this on my side. Is it possible to run your code on a DK? If so, can you upload your complete project (both application and bootloader) together with instructions on how to perform the test so that I can do it on my side? You can upload it in a private case if you don't want it to be public. In so, please refer to this case so that the new case is assigned to me.

  • So I finally was able to solve the problem. In short the documentation for the serial DFU bootlader with no softdevice is really missing few key steps. I would highly suggest they get updated.

    Basically beside the application hex and the booloader hex you also need the mbr hex. This code that actually reside at memory address 0x0. It is already included in the softdevice but if you are not using a softdevice then you need to do few additional steps:

    1) Add mbr_nrf52_2.4.1_mbr.hex. In segger you could do so under project options, debug, loader, additional load files. The relative path is ../../../../../../components/softdevice/mbr/hex/mbr_nrf52_2.4.1_mbr.hex

    2) Add MBR_PRESENT to the preprocessor defines. In segger you could do so under project options, code, preprocessor, preprocessor definitions.

    3) Include mbr and cmsis headers if they are not already included. In segger you could do so under project options, code, preprocessor, user include directories. The relatives file are 

    ../../../../../../components/softdevice/mbr/headers

    ../../../../../../components/toolchain/cmsis/include

    4) Change the flash start address to 0x1000 and update the size (substract 0x1000). In segger you could do so under project options, code, linker, section placement macros. 

    5) Change the RAM start address to 0x20000010 and update the size (substract 0x10). In segger you could do so under project options, code, linker, section placement macros. 

    This worked for me. You could do the same changes plenty other ways but this is how I did it. Good luck!

  • WOW - this!!!

    I've just spent ***quite a bit of time*** independently discovering exactly the same thing.

    Once you know it's about mbr_nrf52_2.4.1_mbr.hex - then you can search for the answer - but by then you already know!

    PLEASE, PLEASE update the guidance in the DFU SDK examples to include this information.

Related