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

Parents Reply Children
  • Hi,

    RK01 said:
    Thank you, this is almost what I tired (RAM was different, why 0x20002300 and not 0x20001678?). I do not see any more information in the nRF Connect Programmer. 

    Are you able to flash with nRF Connect Programmer? Would the application work?

    RK01 said:

    If set the section in the flash higher (to 0x00030000 so it will flash but fail __NVIC_ClearPendingIRQ()) the Programmer layout looks like this.

    The application program code should be placed above the SoftDevice at APP_CODE_BASE. See Memory resource map and usage

    -Amanda

  • Why should I programm the device with the nRF Connect Programmer instead of SES? 

    I see the MBR and Softdevice are from 0x0 to 0x26633. So I should be able to load the application into 0x26634 or 0x26700 but that doesn't work. Below 0x30000 it complains about overlapping memory space. 

    So I load it into 0x30000. Debug:

    int main(int argc, char* argv[])
    {
        using namespace std::placeholders; // for _1, _2
        ERROR_CHECK(app_timer_init());     //App Timer Init
        ....

    in the app_timer_init() here it will fail:

    static void timer_list_handler_sched(void)
    {
        NVIC_SetPendingIRQ(SWI_IRQn);
    }

    it jumps to address 0xA60

    Side note: the linked memory map is for the S112, here is the S140 Memory Map

  • Hi, 

    I would suggest to use app_timer2.c which fixes some issues related to timeout handlers firing too soon and is generally much less complex. And it's API compatible with the old app_timer, so it should be an easy replacement. You can take a look at the  Template Application on how to use app_timer_init. 

    -Amanda

  • 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

Related