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

Can't flash debug bootloader from SDK 12.1.0. ERROR: The area to write is not erased.

Hi.

I have a BLE peripheral app for the nRF51822. I'm using SDK 12.1.0 with SD 130 v2.0.1 and gcc. I'm implementing DFU OTA at the moment and I notice there are two builds of the example bootloader_secure app for each board, eg. one called pca10028 and another called pca10028_debug. The debug one includes logging statements and so on, so we can use it to debug a bootloader that's not working, I presume. I've managed to get the size of my application down to the point where I have room for it along with the debug bootloader.

To flash my board, I use separate calls to nrfproj, one for each hex file, in my Makefile, like this:

flash: all
	$(NRFPROJ) --eraseall
	$(NRFPROJ) --program $(SOFTDEVICE)
	$(NRFPROJ) --program bootloader/biketracker_debug/armgcc/_build/bootloader_s130.hex
	$(NRFPROJ) --program $(HEX)
	$(NRFPROJ) --reset

I can flash my application along with the NON debug bootloader, but not with the debug one.

eliot-macbook-pro:biketracker-firmware Eliot$ make flash
/Users/Eliot/dev/nRF5x_tools/nrfjprog/nrfjprog -f NRF51 -c 1000 --eraseall
Erasing code and UICR flash areas.
Applying system reset.
/Users/Eliot/dev/nRF5x_tools/nrfjprog/nrfjprog -f NRF51 -c 1000 --program /Users/Eliot/dev/nRF5_SDK_12.1.0_0d23e2a/components/softdevice/s130/hex/s130_nrf51_2.0.1_softdevice.hex
Parsing hex file.
Reading flash area to program to guarantee it is erased.
Checking that the area to write is not protected.
Programing device.
/Users/Eliot/dev/nRF5x_tools/nrfjprog/nrfjprog -f NRF51 -c 1000 --program bootloader/biketracker_debug/armgcc/_build/bootloader_s130.hex
Parsing hex file.
Reading flash area to program to guarantee it is erased.
Checking that the area to write is not protected.
Programing device.
/Users/Eliot/dev/nRF5x_tools/nrfjprog/nrfjprog -f NRF51 -c 1000 --program _build/biketracker_app_s130.hex
Parsing hex file.
Reading flash area to program to guarantee it is erased.
ERROR: The area to write is not erased.
make: *** [flash] Error 58

If I try to merge the hex files for my application and the debug bootloader, that also fails, confirming there's a conflict somewhere in memory, but not where:

eliot-macbook-pro:biketracker-firmware Eliot$ /Users/Eliot/dev/nRF5x_tools/mergehex/mergehex --merge bootloader/biketracker_debug/armgcc/_build/bootloader_s130.hex _build/biketracker_app_s130.hex -o merged.hex
Parsing input hex files.
Merging files.
ERROR: The hex files cannot be merged since there are conflicts.

Here's the linker script for the NON debug bootloader:

/* Linker script to configure memory regions. */

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

MEMORY
{
  /** Flash start address for the bootloader. This setting will also be stored in UICR to allow the
   *  MBR to init the bootloader when starting the system. This value must correspond to
   *  BOOTLOADER_REGION_START found in dfu_types.h. The system is prevented from starting up if
   *  those values do not match. The check is performed in main.c, see
   *  APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
   *
   * Currently ~18.6 kB, leaving 128.4 kB for the application.
   */
  FLASH (rx) : ORIGIN = 0x3AC00, LENGTH = 0x5000 /* end: 0x3FC00, length: 20 kB */

  /** RAM Region for bootloader. This setting is suitable when used with s110, s120, s130, s310. */
  RAM (rwx) :  ORIGIN = 0x20002C00, LENGTH = 0x5380

  /** Location of non initialized RAM. Non initialized RAM is used for exchanging bond information
   *  from application to bootloader when using buttonluss DFU OTA.
   */
  NOINIT (rwx) :  ORIGIN = 0x20007F80, LENGTH = 0x80

  /** Location of bootloader setting in at the last flash page. */
  BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x0003FC00, LENGTH = 0x0400

  /** Location in UICR where bootloader start address is stored. */
  UICR_BOOTLOADER (r) : ORIGIN = 0x10001014, LENGTH = 0x04
}

SECTIONS
{
  /* Ensures the bootloader settings are placed at the last flash page. */
  .bootloaderSettings(NOLOAD) :
  {

  } > BOOTLOADER_SETTINGS

  /* Ensures the Bootloader start address in flash is written to UICR when flashing the image. */
  .uicrBootStartAddress :
  {
    KEEP(*(.uicrBootStartAddress))
  } > UICR_BOOTLOADER

  /* No init RAM section in bootloader. Used for bond information exchange. */
  .noinit(NOLOAD) :
  {

  } > NOINIT
  /* other placements follow here... */
}

SECTIONS
{
  . = ALIGN(4);
  .fs_data :
  {
    PROVIDE(__start_fs_data = .);
    KEEP(*(.fs_data))
    PROVIDE(__stop_fs_data = .);
  } > RAM

  . = ALIGN(4);
  .svc_data :
  {
    PROVIDE(__start_svc_data = .);
    KEEP(*(.svc_data))
    PROVIDE(__stop_svc_data = .);
  } > RAM

  . = ALIGN(4);
  .dfu_trans :
  {
    PROVIDE(__start_dfu_trans = .);
    KEEP(*(.dfu_trans))
    PROVIDE(__stop_dfu_trans = .);
  } > RAM

} INSERT AFTER .data

INCLUDE "nrf51_common.ld"

and the same for the debug bootloader:

/* Linker script to configure memory regions. */

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

MEMORY
{
  /** Flash start address for the bootloader. This setting will also be stored in UICR to allow the
   *  MBR to init the bootloader when starting the system. This value must correspond to
   *  BOOTLOADER_REGION_START found in dfu_types.h. The system is prevented from starting up if
   *  those values do not match. The check is performed in main.c, see
   *  APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
   *
   * Currently ~30.5 kB, leaving ~116.5 kB for the application.
   */
  FLASH (rx) : ORIGIN = 0x37800, LENGTH = 0x7C00 /* end: 0x3F400, length: 31 kB */

  /** RAM Region for bootloader. This setting is suitable when used with s110, s120, s130, s310. */
  RAM (rwx) :  ORIGIN = 0x20002C00, LENGTH = 0x5380

  /** Location of non initialized RAM. Non initialized RAM is used for exchanging bond information
   *  from application to bootloader when using buttonluss DFU OTA.
   */
  NOINIT (rwx) :  ORIGIN = 0x20007F80, LENGTH = 0x80

  /** Location of bootloader setting in at the last flash page. */
  BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x0003FC00, LENGTH = 0x0400

  /** Location in UICR where bootloader start address is stored. */
  UICR_BOOTLOADER (r) : ORIGIN = 0x10001014, LENGTH = 0x04
}

SECTIONS
{
  /* Ensures the bootloader settings are placed at the last flash page. */
  .bootloaderSettings(NOLOAD) :
  {

  } > BOOTLOADER_SETTINGS

  /* Ensures the Bootloader start address in flash is written to UICR when flashing the image. */
  .uicrBootStartAddress :
  {
    KEEP(*(.uicrBootStartAddress))
  } > UICR_BOOTLOADER

  /* No init RAM section in bootloader. Used for bond information exchange. */
  .noinit(NOLOAD) :
  {

  } > NOINIT
  /* other placements follow here... */
}

SECTIONS
{
  . = ALIGN(4);
  .fs_data :
  {
    PROVIDE(__start_fs_data = .);
    KEEP(*(.fs_data))
    PROVIDE(__stop_fs_data = .);
  } > RAM

  . = ALIGN(4);
  .svc_data :
  {
    PROVIDE(__start_svc_data = .);
    KEEP(*(.svc_data))
    PROVIDE(__stop_svc_data = .);
  } > RAM

  . = ALIGN(4);
  .dfu_trans :
  {
    PROVIDE(__start_dfu_trans = .);
    KEEP(*(.dfu_trans))
    PROVIDE(__stop_dfu_trans = .);
  } > RAM

} INSERT AFTER .data

INCLUDE "nrf51_common.ld"

And here are the hex files for each bootloader:

bootloader_s130.hex

bootloader_debug_s130.hex

Where is the conflict? I don't see it.

Edit 1

And the linker script for the application. Note that the experimental_ble_app_buttonless_dfu example application has no .bootloaderSettings section and subsequently doesn't work. I've tried to make it work here.

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

MEMORY
{
  /* Total flash: 256 kB (0x40000) */

  /* BUILD_PROD, larger */
  /* FLASH (rx) :                ORIGIN = 0x1B000,    LENGTH = 0x20F00 */ /* end: 0x3BF00, length: 131.75kB */

  /* BUILD_DFU_TEST, 114 kB */
  FLASH (rx) :                ORIGIN = 0x1B000,    LENGTH = 0x1C800 /* end: 0x37800, length: 114 kB */

  /* Total RAM: 32 kB (0x8000) */
  /* The Soft Device can tell us what it needs here at runtime. Run "make test" and expect a warning when we enable the SD. See:
       <SDK>/softdevice/common/softdevice_handler/softdevice_handler.c L486.
  */
  RAM (rwx) :                 ORIGIN = 0x20002008, LENGTH = 0x5FF8  /* just under 24 kB */

  /** Location of non initialized RAM. Non initialized RAM is used for exchanging bond information
   *  from application to bootloader when using buttonluss DFU OTA.
   */
  NOINIT (rwx) :  ORIGIN = 0x20007F80, LENGTH = 0x80

  /** Location of bootloader setting in at the last flash page. */
  BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x0003FC00, LENGTH = 0x0400

  /** Location in UICR where bootloader start address is stored. */
  UICR_BOOTLOADER (r) : ORIGIN = 0x10001014, LENGTH = 0x04
}

/* This is copied over from the bootloader verbatim. */
SECTIONS
{
  /* Ensures the bootloader settings are placed at the last flash page. */
  .bootloaderSettings(NOLOAD) :
  {

  } > BOOTLOADER_SETTINGS

  /* Ensures the Bootloader start address in flash is written to UICR when flashing the image. */
  .uicrBootStartAddress :
  {
    KEEP(*(.uicrBootStartAddress))
  } > UICR_BOOTLOADER

  /* No init RAM section in bootloader. Used for bond information exchange. */
  .noinit(NOLOAD) :
  {

  } > NOINIT
  /* other placements follow here... */
}

SECTIONS
{
  .fs_data :
  {
    PROVIDE(__start_fs_data = .);
    KEEP(*(.fs_data))
    PROVIDE(__stop_fs_data = .);
  } > RAM
} INSERT AFTER .data;

/* This is in <SDK>/components/toolchain/gcc. */
INCLUDE "nrf51_common.ld"
  • Are you sure? This looks like it only applies to an NRF52 build. Mine is NRF51. The NRF51 has no MBR params page and the bit of nrf_dfu_settings.c that post mentions is correctly wrapped in #if defined ( NRF52 )

  • In the end, this was nothing to do with the bootloader settings or the MBR params. I just had my application FLASH overlapping with my bootloader FLASH. I managed to put my app on a diet and get it down to 116 kB, leaving 31 kB for the debug bootloader.

    Using objdump on the hex files (not the elf files) to show the sections was helpful:

    /Users/Eliot/dev/gcc-arm-none-eabi-4_9-2015q3/bin/arm-none-eabi-objdump -d -S -marm -h -t _build/biketracker_app_s130.hex
    
    _build/biketracker_app_s130.hex:     file format ihex
    
    Sections:
    Idx Name          Size      VMA               LMA               File off  Algn
      0 .sec1         00005000  0001b000  0001b000  00000011  2**0
                      CONTENTS, ALLOC, LOAD
      1 .sec2         00010000  00020000  00020000  0000e122  2**0
                      CONTENTS, ALLOC, LOAD
      2 .sec3         00007f50  00030000  00030000  0003b133  2**0
                      CONTENTS, ALLOC, LOAD
    SYMBOL TABLE:
    no symbols
    
    
    /Users/Eliot/dev/gcc-arm-none-eabi-4_9-2015q3/bin/arm-none-eabi-objdump -d -S -marm -h -t bootloader/biketracker_debug/armgcc/_build/bootloader_s130.hex
    
    bootloader/biketracker_debug/armgcc/_build/bootloader_s130.hex:     file format ihex
    
    Sections:
    Idx Name          Size      VMA               LMA               File off  Algn
      0 .sec1         00007a48  00038000  00038000  00000011  2**0
                      CONTENTS, ALLOC, LOAD
      1 .sec2         00000004  10001014  10001014  00015831  2**0
                      CONTENTS, ALLOC, LOAD
    SYMBOL TABLE:
    no symbols
    
Related