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
  • Hi, 

    If you are using s140_nrf52_7.2.0_softdevice.hex, the application should start from 0x27000. Because the flash size of SD is 156 kB (0x27000 bytes), RAM is 5.6 kB (0x1678 bytes). You could try the following setting. If it still has the overlapping issue, you could use nRF Connect for Desktop/Programmer to check the memory layout. 

    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0xd9000
      RAM (rwx) :  ORIGIN = 0x20002300, LENGTH = 0x3dd00
    }

    Regards,
    Amanda

  • Hi, 

    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. 

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

  • 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

Reply
  • 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

Children
  • 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

  • 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 

Related