Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Linker Placement (RAM_START and RAM_SIZE) in SES 3.34: how to modify?

I'm following the Custom BLE Service Example, and using:

  • Segger Embedded Studio Release 3.34a
  • macOS 10.13.4 (aka High Sierra)
  • nRF52 DK (PCA10040, nRF52832)
  • nRF5_SDK_15.0.0_a53641a

I downloaded the git repository verbatim and the project builds without error.  But when I download and run it, it dies inside the function:

main() => peer_manager_init() => pm_init() => pds_init() => fds_init()

with an FDS_ERR_NO_PAGES error.

My guess is that this is because I did not set RAM_START to 0x20002220 and RAM_SIZE to 0xDDE0 in the linker placement file, as instructed by the README file, which says to open Project => Edit Options => Common Configuration and then select Linker => Section Placement Macros.

The problem with that is that, in my case, Edit Options shows only a Code section, not a Linker section.

My questions are therefore:

  • Am I correct that the crash is (probably) because I haven't modified the RAM_START and RAM_SIZE placement macros?
  • If so, how do I modify those values?
Parents Reply Children
  • Hello Bjørn!

    Here's the screenshot of the window I get by clicking Project => Edit Options...

    And the contents of ble_pp_template_gcc_nfr52.ld are as follows:

    /* Linker script to configure memory regions. */
    
    SEARCH_DIR(.)
    GROUP(-lgcc -lc -lnosys)
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x5a000
      RAM (rwx) :  ORIGIN = 0x20002220, LENGTH = 0xdde0
    }
    
    SECTIONS
    {
    }
    
    SECTIONS
    {
      . = ALIGN(4);
      .mem_section_dummy_ram :
      {
      }
      .log_dynamic_data :
      {
        PROVIDE(__start_log_dynamic_data = .);
        KEEP(*(SORT(.log_dynamic_data*)))
        PROVIDE(__stop_log_dynamic_data = .);
      } > RAM
      .fs_data :
      {
        PROVIDE(__start_fs_data = .);
        KEEP(*(.fs_data))
        PROVIDE(__stop_fs_data = .);
      } > RAM
      .cli_sorted_cmd_ptrs :
      {
        PROVIDE(__start_cli_sorted_cmd_ptrs = .);
        KEEP(*(.cli_sorted_cmd_ptrs))
        PROVIDE(__stop_cli_sorted_cmd_ptrs = .);
      } > 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
      .log_const_data :
      {
        PROVIDE(__start_log_const_data = .);
        KEEP(*(SORT(.log_const_data*)))
        PROVIDE(__stop_log_const_data = .);
      } > FLASH
        .nrf_balloc :
      {
        PROVIDE(__start_nrf_balloc = .);
        KEEP(*(.nrf_balloc))
        PROVIDE(__stop_nrf_balloc = .);
      } > 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
      .sdh_req_observers :
      {
        PROVIDE(__start_sdh_req_observers = .);
        KEEP(*(SORT(.sdh_req_observers*)))
        PROVIDE(__stop_sdh_req_observers = .);
      } > FLASH
        .nrf_queue :
      {
        PROVIDE(__start_nrf_queue = .);
        KEEP(*(.nrf_queue))
        PROVIDE(__stop_nrf_queue = .);
      } > 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
    
    } INSERT AFTER .text
    
    INCLUDE "nrf_common.ld"
    

  • For completeness, here is a screenshot of SES just after it got the error. It has just returned from a call to `pages_init()`, and `init_opts` has a value of NO_PAGES.   

  • I believe I fixed the problem, even if I don't completely understand why:

    Short form: I erased the part and restarted.  Works.

    Details:

    I noticed that the system was looking for two or more free pages in `pages_init()`, but the call to `page_is_erased()` was returning false.  (I don't know what was written there...).  So in the Target menu item, I selected 'Erase All' and re-loaded the program.  

    This time it ran without error.

    Lingering question: Is there a reason the pages in question aren't getting initialized?

  • : You have opened the options for the fds.c file and not the project itself (SES is a bit annoying regarding this). You have to select Project 'ble_app_template_pca10040_s132' in the Project explorer and then click Project => Edit Options... or just right-click on  Project 'ble_app_template_pca10040_s132' in the Project explorer and then select Edit Options...

     

     

  • FDS will use the last two pages in flash memory to store data and your application linker script is configured to use the entire flash area above the SoftDevice, i.e.

      FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x5a000

    so whenever you flash the application you should also clear the FDS pages. 

Related