Cannot download multiple load files because they overlap (external gcc with load script)

The Project (on a NRF52840) is setup to use an external toolchain (for C++) and we use the S140 softdevice (v7.2.0) for BLE stuff.

1. without loading the  S140 hex file and disable all related stuff in code and the following memory placement defined in the linker script:

MEMORY
{
  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000
  RAM (rwx) :  ORIGIN = 0x20000000, LENGTH = 0x00040000
}

OK

2. now I add the S140 hex as additional load file and change the memory placement to:

MEMORY
{
  FLASH (rx) : ORIGIN = 0x00027000, LENGTH = 0x000D9000
  RAM (rwx) :  ORIGIN = 0x20001678, LENGTH = 0x0003E900
}

build and link is OK but when download the the target i get 

I see a lot of problems in the Q&A but all with the SES section placement macros.

sources: Adjust RAM/Flash memory

EDIT 2022-02-03 14:14

When adjust the RAM/Flash values to something way bigger, it can flash but code is not working now: __NVIC_ClearPendingIRQ() in core_cm4.h fails.

MEMORY
{
  FLASH (rx) : ORIGIN = 0x00030000, LENGTH = 0x00070000
  RAM (rwx) :  ORIGIN = 0x20003000, LENGTH = 0x00030000
}

Downloading ‘s140_nrf52_7.2.0_softdevice.hex’ to J-Link
Programming 2.7 KB of addresses 00000000 — 00000aff
Programming 149.5 KB of addresses 00001000 — 00026633
J-Link: Flash download: Bank 0 @ 0x00000000: Skipped. Contents already match
Download successful
Downloading ‘Node.elf’ to J-Link
Programming 88.5 KB of addresses 00030000 — 0004621f
Programming 2.4 KB of addresses 00046220 — 00046beb
J-Link: Flash download: Bank 0 @ 0x00000000: 1 range affected (94208 bytes)
J-Link: Flash download: Total: 5.758s (Prepare: 0.277s, Compare: 0.065s, Erase: 1.929s, Program & Verify: 3.291s, Restore: 0.193s)
J-Link: Flash download: Program & Verify speed: 27 KB/s
Download successful

  • Hi

    The program should not be a problem, it already worked prior to switching to external toolchain. I think the problem is in how the Flash/RAM/Softdevice are setup and initialized, because this differs from the SES with internal toolchain project. 

    What I think why the RAM ORIGIN is 0x20003000 and not 0x200016XX is because of the alignment and page size?

    I debugged further in asm and compared to example projects. So there is the NVIC_SetPendingIRQ where it descends into the S140 0x00025F.. but fails when try to load the address in R3 (what was in 0x20000004) . So I maybe the RAM is not initialized correctly? 

    my linker script:

    /* Linker script to configure memory regions. */
    
    SEARCH_DIR(.)
    GROUP(-lgcc -lc -lnosys)
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x00030000/*0x00000000*/, LENGTH = 0x000D0000/*0x00100000*/
      RAM (rwx) :  ORIGIN = 0x20003000/*0x20002260*//*0x20000000*/, LENGTH = 0x00030000/*0x0003DDA0*//*0x00040000*/
    }
    
    SECTIONS
    {
    }
    
    SECTIONS
    {
        . = ALIGN(4);
        .mem_section_dummy_ram :
        {
        }
    
        .cli_sorted_cmd_ptrs :
        {
            PROVIDE(__start_cli_sorted_cmd_ptrs = .);
            KEEP(*(.cli_sorted_cmd_ptrs))
            PROVIDE(__stop_cli_sorted_cmd_ptrs = .);
        } > RAM
    
        .fs_data :
        {
            PROVIDE(__start_fs_data = .);
            KEEP(*(.fs_data))
            PROVIDE(__stop_fs_data = .);
        } > RAM
    
        .log_dynamic_data :
        {
            PROVIDE(__start_log_dynamic_data = .);
            KEEP(*(SORT(.log_dynamic_data*)))
            PROVIDE(__stop_log_dynamic_data = .);
        } > RAM
    
        .log_filter_data :
        {
            PROVIDE(__start_log_filter_data = .);
            KEEP(*(SORT(.log_filter_data*)))
            PROVIDE(__stop_log_filter_data = .);
        } > 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
    
        .pwr_mgmt_data :
        {
            PROVIDE(__start_pwr_mgmt_data = .);
            KEEP(*(SORT(.pwr_mgmt_data*)))
            PROVIDE(__stop_pwr_mgmt_data = .);
        } > FLASH
    
        .sdh_req_observers :
        {
            PROVIDE(__start_sdh_req_observers = .);
            KEEP(*(SORT(.sdh_req_observers*)))
            PROVIDE(__stop_sdh_req_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
    
        .nrf_queue :
        {
            PROVIDE(__start_nrf_queue = .);
            KEEP(*(.nrf_queue))
            PROVIDE(__stop_nrf_queue = .);
        } > FLASH
    
        .nrf_balloc :
        {
            PROVIDE(__start_nrf_balloc = .);
            KEEP(*(.nrf_balloc))
            PROVIDE(__stop_nrf_balloc = .);
        } > 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
    
        .log_const_data :
        {
            PROVIDE(__start_log_const_data = .);
            KEEP(*(SORT(.log_const_data*)))
            PROVIDE(__stop_log_const_data = .);
        } > FLASH
    
        .sdh_ble_observers :
        {
            PROVIDE(__start_sdh_ble_observers = .);
            KEEP(*(SORT(.sdh_ble_observers*)))
            PROVIDE(__stop_sdh_ble_observers = .);
        } > FLASH
    
        .log_backends :
        {
            PROVIDE(__start_log_backends = .);
            KEEP(*(SORT(.log_backends*)))
            PROVIDE(__stop_log_backends = .);
        } > FLASH
    
    } INSERT AFTER .text
    
    INCLUDE "nrf_common.ld"

    and the project uses the gcc_startup_nrf52840.s (borrowed from an BLE example project).

  • Hi, 

    It needs to set the flash address as I explained at the first. The SoftDevice expects the application to be located at 0x27000. 

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

    We guess the problem is that you do not place the application right after the softdevice in flash, so the application vector table is not where the softdevice thinks it is: https://infocenter.nordicsemi.com/topic/sds_s140/SDS/s1xx/processor_avail_interrupt_latency/interrupt_forwarding_to_application.html?cp=4_7_4_0_15_0_0

    "For the SoftDevice to locate the application interrupt vectors, the application must define its interrupt vector table at the bottom of the Application Flash Region illustrated in Memory resource map. When the base address of the application code is directly after the top address of the SoftDevice, the code can be developed as a standard ARMRegistered CortexRegistered -M4 application project with the compiler creating the interrupt vector table."

    Maybe you have some additional load files in the project settings that will overlap with the application. Could you provide the Segger programming fail log?

    -Amanda

  • Hi

    So I set the flash placement back to 0x27000

    /* Linker script to configure memory regions. */
    
    SEARCH_DIR(.)
    GROUP(-lgcc -lc -lnosys)
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0xd9000
      RAM (rwx) :  ORIGIN = 0x20002300, LENGTH = 0x3dd00
    }
    
    SECTIONS
    {
    }
    
    SECTIONS
    {
      . = ALIGN(4);
      .mem_section_dummy_ram :
      {
      }
      .cli_sorted_cmd_ptrs :
      {
        PROVIDE(__start_cli_sorted_cmd_ptrs = .);
        KEEP(*(.cli_sorted_cmd_ptrs))
        PROVIDE(__stop_cli_sorted_cmd_ptrs = .);
      } > RAM
      .fs_data :
      {
        PROVIDE(__start_fs_data = .);
        KEEP(*(.fs_data))
        PROVIDE(__stop_fs_data = .);
      } > RAM
      .log_dynamic_data :
      {
        PROVIDE(__start_log_dynamic_data = .);
        KEEP(*(SORT(.log_dynamic_data*)))
        PROVIDE(__stop_log_dynamic_data = .);
      } > RAM
      .log_filter_data :
      {
        PROVIDE(__start_log_filter_data = .);
        KEEP(*(SORT(.log_filter_data*)))
        PROVIDE(__stop_log_filter_data = .);
      } > 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
      .pwr_mgmt_data :
      {
        PROVIDE(__start_pwr_mgmt_data = .);
        KEEP(*(SORT(.pwr_mgmt_data*)))
        PROVIDE(__stop_pwr_mgmt_data = .);
      } > FLASH
      .sdh_ble_observers :
      {
        PROVIDE(__start_sdh_ble_observers = .);
        KEEP(*(SORT(.sdh_ble_observers*)))
        PROVIDE(__stop_sdh_ble_observers = .);
      } > FLASH
      .sdh_req_observers :
      {
        PROVIDE(__start_sdh_req_observers = .);
        KEEP(*(SORT(.sdh_req_observers*)))
        PROVIDE(__stop_sdh_req_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
        .nrf_queue :
      {
        PROVIDE(__start_nrf_queue = .);
        KEEP(*(.nrf_queue))
        PROVIDE(__stop_nrf_queue = .);
      } > FLASH
        .nrf_balloc :
      {
        PROVIDE(__start_nrf_balloc = .);
        KEEP(*(.nrf_balloc))
        PROVIDE(__stop_nrf_balloc = .);
      } > 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
      .log_const_data :
      {
        PROVIDE(__start_log_const_data = .);
        KEEP(*(SORT(.log_const_data*)))
        PROVIDE(__stop_log_const_data = .);
      } > FLASH
      .log_backends :
      {
        PROVIDE(__start_log_backends = .);
        KEEP(*(SORT(.log_backends*)))
        PROVIDE(__stop_log_backends = .);
      } > FLASH
    
    } INSERT AFTER .text
    
    
    INCLUDE "nrf_common.ld"
    

    Target Output:

    Preparing target for download
    Executing Reset script TargetInterface.resetAndStop()
    Reset: Halt core after reset via DEMCR.VC_CORERESET.
    Reset: Reset device via AIRCR.SYSRESETREQ.
    

    Where do I find the "Segger programming fail log"?

  • The target output doesn't show any error message. Does it just stop there? 

    Are you using nRF52840DK or the custom board? Are you able to test on nRF52840DK?

    Can you try to load other examples such as BLE Blinky Application/s140 which use the same flash address setting? Does it also have the same issue?

    -Amanda 

  • Yes it stops there with the Error "cannot download because overlap" (posted in the initial Question).

    It is the nRF52840-DK

    No these work fine. Also our own project is OK when using the flash_placement.xml and SES internal gcc. 

    The problem arises when switching to external gcc toolchain and using the linker script. The problem is probably in the linker script (I copied these from the examples) or in the project settings. 

Related