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

How do I change the application/bootloader start address?

My ultimate issue is trying to get a bootloader working on custom hardware with an nRF52832. The bootloader is mostly the base UART DFU bootloader from the Nordic SDK, with a few customizations to work with our hardware. I've been able to get the bootloader up and running by using the following flash set up that I have for the application: FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x5a000. However, when I try to change the start address (e.g. to FLASH (rx) : ORIGIN = 0x25000, LENGTH = 0x5b000), the bootloader no longer appears to run. Similarly, I can use Eclipse to step into the debug code of the bootloader when it starts at 0x26000, but not at 0x25000.

To try to eliminate as many variables as possible, I also tried changing the start address of one of the SDK examples and running it on an nRF52 dev kit. In the same way as the bootloader on custom hardware, building the ble_central/ble_app_blinky_c produces an hex file that will run successfully on the dev kit, while building it with the start address changed to 0x25000 produces a hex file that will not run successfully. Below is a diff of my complete changes to the blinky example.

diff --git a/examples/ble_central/ble_app_blinky_c/pca10040/s132/armgcc/ble_app_blinky_c_gcc_nrf52.ld b/examples/ble_central/ble_app_blinky_c/pca10040/s132/armgcc/ble_app_blinky_c_gcc_nrf52.ld
index 1cdf99f61..f4c14ecb0 100644
--- a/examples/ble_central/ble_app_blinky_c/pca10040/s132/armgcc/ble_app_blinky_c_gcc_nrf52.ld
+++ b/examples/ble_central/ble_app_blinky_c/pca10040/s132/armgcc/ble_app_blinky_c_gcc_nrf52.ld
@@ -5,7 +5,7 @@ GROUP(-lgcc -lc -lnosys)

 MEMORY
 {
-  FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x5a000
+  FLASH (rx) : ORIGIN = 0x25000, LENGTH = 0x5b000
   RAM (rwx) :  ORIGIN = 0x20001d70, LENGTH = 0xe290
 }

In both the custom code/hardware and stock SDK/dev kit situations I'm using GCC as my compiler and SDK 15.2.0, with softdevice s132_nrf52_6.1.0_softdevice.hex. My programming procedure in each case is:

nrfjprog -f nrf52 --eraseall
nrfjprog -f nrf52 --chiperase --program <path_to_softdevice>
nrfjprog -f nrf52 --sectorerase --program <application or bootloader>.hex
nrfjprog -f nrf52 --reset

What am I missing about changing the starting address of either the application or the bootloader? What configuration needs to be done to get an application and bootloader running together?

Thanks.

  • No, I am not able to debug with that configuration. I have been able to debug the bootloader with the FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x5a000 configuration.

  • I think the issue is that the length value is to large as ORIGIN+LENGTH is 0x81000. The bootloader should stop at the start of the MBR Params page at 0x7E000, i.e. LENGTH = 0x78000 - ORIGIN = 0x57000.

    I tested the following setting with the bootlaoder in SDK v15.2.0 and I had no issues. 

     FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0x57000

  • I've noticed that my custom bootloader isn't setting the bootloader start address in the UICR registers. Is there anything specific in the project setup that signals nrfjprog that a given application is a bootloader and thus that the UICR registers should be set? I'm using the same ld file for my bootloader as for the example in the SDK, so maybe I'm missing something in the makefile?

  • Hi Kathleen,
    as long as you have the following memory regions and sections set in your linker script

    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0x57000
      RAM (rwx) :  ORIGIN = 0x200057b8, LENGTH = 0xa848
      mbr_params_page (r) : ORIGIN = 0x0007E000, LENGTH = 0x1000
      bootloader_settings_page (r) : ORIGIN = 0x0007F000, LENGTH = 0x1000
      uicr_mbr_params_page (r) : ORIGIN = 0x10001018, LENGTH = 0x4
      uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4
    }
    
    SECTIONS
    {
      .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_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
      .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
    }

    specifically the uicr_bootloader_start_address section, then you should be fine. Could you search through your .map file and see if uicr_bootloader_start_address section is included in the generated binary?

  • I've got this line  under Memory Configuration:

    uicr_bootloader_start_address 0x10001014         0x00000004         r

    And this later on in the map file:

    .uicr_bootloader_start_address
                    0x10001014        0x0
                    [!provide]                PROVIDE (__start_uicr_bootloader_start_address = .)
     *(SORT_BY_NAME(.uicr_bootloader_start_address*))
                    [!provide]                PROVIDE (__stop_uicr_bootloader_start_address = .)

Related