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

Unable to flash after adding bootloader

Hi,

So I've made a post that I was unable to debug my app with the bootloader. But I've found out that it is entirely different problem. So my app is runnning whit FreeRTOS and I am using the buttonless bootloader debug example on the SDK15.0.0 with the softdevice compiling with armgcc. When I try to flash trough eclipse, the application restart but does not change.So I think that probably the flash fails.

Then I tried it on nrfGo studio and I get the message "Unable to erase UICR" when I try to flash my application. I did try to erase the UICR before but I don't think that is the problem. I tried reajustring my linker file since I thought that maybe I was writting on the bootloader.  Since the bootloader starts at 0x72000 I've five the length of the flash.

Here is my .ld file of my application:

/* Linker script to configure memory regions. */

SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)

MEMORY
{
  FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x4c000
  RAM (rwx) :  ORIGIN = 0x200057b8, LENGTH = 0xa848
  uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4
}

SECTIONS
{
  .uicr_bootloader_start_address :
  {
    PROVIDE(__start_uicr_bootloader_start_address = .);
    KEEP(*(SORT(.uicr_bootloader_start_address*)))
    PROVIDE(__stop_uicr_bootloader_start_address = .);
  } > uicr_bootloader_start_address
}

SECTIONS
{
  . = ALIGN(4);
  .mem_section_dummy_ram :
  {
  }
  .log_dynamic_data :
  {
    PROVIDE(__start_log_dynamic_data = .);
    KEEP(*(SORT(.log_dynamic_data*)))
    PROVIDE(__stop_log_dynamic_data = .);
  } > RAM
  .fs_data :
  {
    PROVIDE(__start_fs_data = .);
    KEEP(*(.fs_data))
    PROVIDE(__stop_fs_data = .);
  } > RAM
  .cli_sorted_cmd_ptrs :
  {
    PROVIDE(__start_cli_sorted_cmd_ptrs = .);
    KEEP(*(.cli_sorted_cmd_ptrs))
    PROVIDE(__stop_cli_sorted_cmd_ptrs = .);
  } > RAM

} INSERT AFTER .data;

SECTIONS
{
  .mem_section_dummy_rom :
  {
  }
  .sdh_soc_observers :
  {
    PROVIDE(__start_sdh_soc_observers = .);
    KEEP(*(SORT(.sdh_soc_observers*)))
    PROVIDE(__stop_sdh_soc_observers = .);
  } > FLASH
  .sdh_ble_observers :
  {
    PROVIDE(__start_sdh_ble_observers = .);
    KEEP(*(SORT(.sdh_ble_observers*)))
    PROVIDE(__stop_sdh_ble_observers = .);
  } > FLASH
  .log_const_data :
  {
    PROVIDE(__start_log_const_data = .);
    KEEP(*(SORT(.log_const_data*)))
    PROVIDE(__stop_log_const_data = .);
  } > FLASH
    .nrf_balloc :
  {
    PROVIDE(__start_nrf_balloc = .);
    KEEP(*(.nrf_balloc))
    PROVIDE(__stop_nrf_balloc = .);
  } > FLASH
  .sdh_state_observers :
  {
    PROVIDE(__start_sdh_state_observers = .);
    KEEP(*(SORT(.sdh_state_observers*)))
    PROVIDE(__stop_sdh_state_observers = .);
  } > FLASH
  .svc_data :
  {
    PROVIDE(__start_svc_data = .);
    KEEP(*(.svc_data))
    PROVIDE(__stop_svc_data = .);
  } > FLASH
  .sdh_stack_observers :
  {
    PROVIDE(__start_sdh_stack_observers = .);
    KEEP(*(SORT(.sdh_stack_observers*)))
    PROVIDE(__stop_sdh_stack_observers = .);
  } > FLASH
  .sdh_req_observers :
  {
    PROVIDE(__start_sdh_req_observers = .);
    KEEP(*(SORT(.sdh_req_observers*)))
    PROVIDE(__stop_sdh_req_observers = .);
  } > FLASH
    .nrf_queue :
  {
    PROVIDE(__start_nrf_queue = .);
    KEEP(*(.nrf_queue))
    PROVIDE(__stop_nrf_queue = .);
  } > FLASH
    .cli_command :
  {
    PROVIDE(__start_cli_command = .);
    KEEP(*(.cli_command))
    PROVIDE(__stop_cli_command = .);
  } > FLASH
  .crypto_data :
  {
    PROVIDE(__start_crypto_data = .);
    KEEP(*(SORT(.crypto_data*)))
    PROVIDE(__stop_crypto_data = .);
  } > FLASH
  .pwr_mgmt_data :
  {
    PROVIDE(__start_pwr_mgmt_data = .);
    KEEP(*(SORT(.pwr_mgmt_data*)))
    PROVIDE(__stop_pwr_mgmt_data = .);
  } > FLASH

} INSERT AFTER .text

INCLUDE "nrf_common.ld"

After a reset: When I flash the bootloader after a reset, if I send an image through the dfu service, it boots. If I flash direcly it doesn't since it does not pass the CRC check. So first I flash a working image through the DFU service and then I try to develop and debug the app by flashing normaly through my IDE/Jlink, but then nothing changes as described in the post.

Any help is appreciated.

Parents
  • Hi Xavier, 

    If the bootloader starts at 0x72000, then the linker settings are correct. 

    We do not recommend using nRFGO Studio as it is deprecated for the nRF52 Series, use the nRF Programmer app in nRF Connect for Desktop or the latest version of the nRF Command Line Tools instead. 

    When debugging an application with the bootloader present you need to generate the bootloader settings page that contains the CRC of the application. This is done with pc-nrfutil, see https://github.com/NordicSemiconductor/pc-nrfutil#settings

    So my advice would be to add a build step in your IDE calls nrfutil and generates the settings.hex file and then flashes this using nrfjprog. 

    Best regards

    Bjørn

  • Hi Bjørn, thanks for the input.

    I tried to merge the settings the bootloader and the app hexfiles by using these commands

    ../../../nrfutil/nrfutil.exe settings generate --family NRF52 --application ./_build/nrf52832_xxaa.hex --application-version 1 --bootloader-version 1 --bl-settings-version 1 setting.hex
    mergehex -m ../../bootloader/_build/nrf52832_xxaa_s132.hex setting.hex -o bootloader_and_setting.hex
    mergehex -m ./_build/nrf52832_xxaa.hex bootloader_and_setting.hex -o app_bootloader_and_setting.hex
     

    But I get the error "The hex files cannot be merged since there are conflicts" on the last command to merge the bootloader with settings and the app. Since you said my linker settings are correct I am a bit confused.

    Here is my linker setting for the Bootloader: (I used the one form the buttonless dfu example so it should work in theory) 

    /* Linker script to configure memory regions. */
    
    SEARCH_DIR(.)
    GROUP(-lgcc -lc -lnosys)
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x72000, LENGTH = 0xc000
      RAM (rwx) :  ORIGIN = 0x200057b8, LENGTH = 0xa848
      uicr_mbr_params_page (r) : ORIGIN = 0x10001018, LENGTH = 0x4
      mbr_params_page (r) : ORIGIN = 0x0007E000, LENGTH = 0x1000
      bootloader_settings_page (r) : ORIGIN = 0x0007F000, LENGTH = 0x1000
      uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4
    }
    
    SECTIONS
    {
      .uicr_mbr_params_page :
      {
        PROVIDE(__start_uicr_mbr_params_page = .);
        KEEP(*(SORT(.uicr_mbr_params_page*)))
        PROVIDE(__stop_uicr_mbr_params_page = .);
      } > uicr_mbr_params_page
      .mbr_params_page(NOLOAD) :
      {
        PROVIDE(__start_mbr_params_page = .);
        KEEP(*(SORT(.mbr_params_page*)))
        PROVIDE(__stop_mbr_params_page = .);
      } > mbr_params_page
      .bootloader_settings_page(NOLOAD) :
      {
        PROVIDE(__start_bootloader_settings_page = .);
        KEEP(*(SORT(.bootloader_settings_page*)))
        PROVIDE(__stop_bootloader_settings_page = .);
      } > bootloader_settings_page
      .uicr_bootloader_start_address :
      {
        PROVIDE(__start_uicr_bootloader_start_address = .);
        KEEP(*(SORT(.uicr_bootloader_start_address*)))
        PROVIDE(__stop_uicr_bootloader_start_address = .);
      } > uicr_bootloader_start_address
    }
    
    SECTIONS
    {
      . = ALIGN(4);
      .mem_section_dummy_ram :
      {
      }
      .log_dynamic_data :
      {
        PROVIDE(__start_log_dynamic_data = .);
        KEEP(*(SORT(.log_dynamic_data*)))
        PROVIDE(__stop_log_dynamic_data = .);
      } > RAM
      .fs_data :
      {
        PROVIDE(__start_fs_data = .);
        KEEP(*(.fs_data))
        PROVIDE(__stop_fs_data = .);
      } > RAM
    
    } INSERT AFTER .data;
    
    SECTIONS
    {
      .mem_section_dummy_rom :
      {
      }
      .crypto_data :
      {
        PROVIDE(__start_crypto_data = .);
        KEEP(*(SORT(.crypto_data*)))
        PROVIDE(__stop_crypto_data = .);
      } > FLASH
        .nrf_queue :
      {
        PROVIDE(__start_nrf_queue = .);
        KEEP(*(.nrf_queue))
        PROVIDE(__stop_nrf_queue = .);
      } > FLASH
      .dfu_trans :
      {
        PROVIDE(__start_dfu_trans = .);
        KEEP(*(SORT(.dfu_trans*)))
        PROVIDE(__stop_dfu_trans = .);
      } > FLASH
      .log_const_data :
      {
        PROVIDE(__start_log_const_data = .);
        KEEP(*(SORT(.log_const_data*)))
        PROVIDE(__stop_log_const_data = .);
      } > FLASH
        .nrf_balloc :
      {
        PROVIDE(__start_nrf_balloc = .);
        KEEP(*(.nrf_balloc))
        PROVIDE(__stop_nrf_balloc = .);
      } > FLASH
        .svc_data :
      {
        PROVIDE(__start_svc_data = .);
        KEEP(*(.svc_data))
        PROVIDE(__stop_svc_data = .);
      } > FLASH
      .sdh_ble_observers :
      {
        PROVIDE(__start_sdh_ble_observers = .);
        KEEP(*(SORT(.sdh_ble_observers*)))
        PROVIDE(__stop_sdh_ble_observers = .);
      } > FLASH
      .sdh_state_observers :
      {
        PROVIDE(__start_sdh_state_observers = .);
        KEEP(*(SORT(.sdh_state_observers*)))
        PROVIDE(__stop_sdh_state_observers = .);
      } > FLASH
      .sdh_stack_observers :
      {
        PROVIDE(__start_sdh_stack_observers = .);
        KEEP(*(SORT(.sdh_stack_observers*)))
        PROVIDE(__stop_sdh_stack_observers = .);
      } > FLASH
      .sdh_req_observers :
      {
        PROVIDE(__start_sdh_req_observers = .);
        KEEP(*(SORT(.sdh_req_observers*)))
        PROVIDE(__stop_sdh_req_observers = .);
      } > FLASH
      .sdh_soc_observers :
      {
        PROVIDE(__start_sdh_soc_observers = .);
        KEEP(*(SORT(.sdh_soc_observers*)))
        PROVIDE(__stop_sdh_soc_observers = .);
      } > FLASH
    
    } INSERT AFTER .text
    
    INCLUDE "nrf_common.ld"
    

    And as you can see the bootloader does start at 0x72000. 

    Thank you.

Reply
  • Hi Bjørn, thanks for the input.

    I tried to merge the settings the bootloader and the app hexfiles by using these commands

    ../../../nrfutil/nrfutil.exe settings generate --family NRF52 --application ./_build/nrf52832_xxaa.hex --application-version 1 --bootloader-version 1 --bl-settings-version 1 setting.hex
    mergehex -m ../../bootloader/_build/nrf52832_xxaa_s132.hex setting.hex -o bootloader_and_setting.hex
    mergehex -m ./_build/nrf52832_xxaa.hex bootloader_and_setting.hex -o app_bootloader_and_setting.hex
     

    But I get the error "The hex files cannot be merged since there are conflicts" on the last command to merge the bootloader with settings and the app. Since you said my linker settings are correct I am a bit confused.

    Here is my linker setting for the Bootloader: (I used the one form the buttonless dfu example so it should work in theory) 

    /* Linker script to configure memory regions. */
    
    SEARCH_DIR(.)
    GROUP(-lgcc -lc -lnosys)
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x72000, LENGTH = 0xc000
      RAM (rwx) :  ORIGIN = 0x200057b8, LENGTH = 0xa848
      uicr_mbr_params_page (r) : ORIGIN = 0x10001018, LENGTH = 0x4
      mbr_params_page (r) : ORIGIN = 0x0007E000, LENGTH = 0x1000
      bootloader_settings_page (r) : ORIGIN = 0x0007F000, LENGTH = 0x1000
      uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4
    }
    
    SECTIONS
    {
      .uicr_mbr_params_page :
      {
        PROVIDE(__start_uicr_mbr_params_page = .);
        KEEP(*(SORT(.uicr_mbr_params_page*)))
        PROVIDE(__stop_uicr_mbr_params_page = .);
      } > uicr_mbr_params_page
      .mbr_params_page(NOLOAD) :
      {
        PROVIDE(__start_mbr_params_page = .);
        KEEP(*(SORT(.mbr_params_page*)))
        PROVIDE(__stop_mbr_params_page = .);
      } > mbr_params_page
      .bootloader_settings_page(NOLOAD) :
      {
        PROVIDE(__start_bootloader_settings_page = .);
        KEEP(*(SORT(.bootloader_settings_page*)))
        PROVIDE(__stop_bootloader_settings_page = .);
      } > bootloader_settings_page
      .uicr_bootloader_start_address :
      {
        PROVIDE(__start_uicr_bootloader_start_address = .);
        KEEP(*(SORT(.uicr_bootloader_start_address*)))
        PROVIDE(__stop_uicr_bootloader_start_address = .);
      } > uicr_bootloader_start_address
    }
    
    SECTIONS
    {
      . = ALIGN(4);
      .mem_section_dummy_ram :
      {
      }
      .log_dynamic_data :
      {
        PROVIDE(__start_log_dynamic_data = .);
        KEEP(*(SORT(.log_dynamic_data*)))
        PROVIDE(__stop_log_dynamic_data = .);
      } > RAM
      .fs_data :
      {
        PROVIDE(__start_fs_data = .);
        KEEP(*(.fs_data))
        PROVIDE(__stop_fs_data = .);
      } > RAM
    
    } INSERT AFTER .data;
    
    SECTIONS
    {
      .mem_section_dummy_rom :
      {
      }
      .crypto_data :
      {
        PROVIDE(__start_crypto_data = .);
        KEEP(*(SORT(.crypto_data*)))
        PROVIDE(__stop_crypto_data = .);
      } > FLASH
        .nrf_queue :
      {
        PROVIDE(__start_nrf_queue = .);
        KEEP(*(.nrf_queue))
        PROVIDE(__stop_nrf_queue = .);
      } > FLASH
      .dfu_trans :
      {
        PROVIDE(__start_dfu_trans = .);
        KEEP(*(SORT(.dfu_trans*)))
        PROVIDE(__stop_dfu_trans = .);
      } > FLASH
      .log_const_data :
      {
        PROVIDE(__start_log_const_data = .);
        KEEP(*(SORT(.log_const_data*)))
        PROVIDE(__stop_log_const_data = .);
      } > FLASH
        .nrf_balloc :
      {
        PROVIDE(__start_nrf_balloc = .);
        KEEP(*(.nrf_balloc))
        PROVIDE(__stop_nrf_balloc = .);
      } > FLASH
        .svc_data :
      {
        PROVIDE(__start_svc_data = .);
        KEEP(*(.svc_data))
        PROVIDE(__stop_svc_data = .);
      } > FLASH
      .sdh_ble_observers :
      {
        PROVIDE(__start_sdh_ble_observers = .);
        KEEP(*(SORT(.sdh_ble_observers*)))
        PROVIDE(__stop_sdh_ble_observers = .);
      } > FLASH
      .sdh_state_observers :
      {
        PROVIDE(__start_sdh_state_observers = .);
        KEEP(*(SORT(.sdh_state_observers*)))
        PROVIDE(__stop_sdh_state_observers = .);
      } > FLASH
      .sdh_stack_observers :
      {
        PROVIDE(__start_sdh_stack_observers = .);
        KEEP(*(SORT(.sdh_stack_observers*)))
        PROVIDE(__stop_sdh_stack_observers = .);
      } > FLASH
      .sdh_req_observers :
      {
        PROVIDE(__start_sdh_req_observers = .);
        KEEP(*(SORT(.sdh_req_observers*)))
        PROVIDE(__stop_sdh_req_observers = .);
      } > FLASH
      .sdh_soc_observers :
      {
        PROVIDE(__start_sdh_soc_observers = .);
        KEEP(*(SORT(.sdh_soc_observers*)))
        PROVIDE(__stop_sdh_soc_observers = .);
      } > FLASH
    
    } INSERT AFTER .text
    
    INCLUDE "nrf_common.ld"
    

    And as you can see the bootloader does start at 0x72000. 

    Thank you.

Children
Related