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

non initialized RAM variable

Hi,

Currently I'm working on nRF52 with SDK11 and SoftDevice S132. Till now I've worked with IAR and my code was based on the "ble_app_uart" and the dfu "bootloader" examples. Everything was working fine with IAR and I could also able to send FOTA images with the boot loader.

In my main.c application file I have the following: __no_init static unsigned int need_to_boot @ 0x20003F7C; which is the way to define non initialized RAM variable with IAR, and the same definition in the main.c file in the bootloader project. In my application, whenever a boot is needed I put a "magic" number into that variable and then soft reset (NVIC_SystemReset) the device. then in the bootloader main loop I was checking this variable and if the "magic" number is set I know that I should stay in boot.

Now my problem is when I moved my project to eclipse using GCC. Here again, the projects compiled and work as needed on the device, the problem is that I could not able to get the bootloader to stay in boot when a request received from the application. As I read in a lot of forms and posts, the way to define such a non initialized variable in GCC is as follow: static unsigned int need_to_boot attribute((section(".noinit"))); And of course the required section in the GCC linker (.ld) file:

/* 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);
   */
  FLASH (rx) : ORIGIN = 0x7A000, LENGTH = 0x4000

  /** RAM Region for bootloader. This setting is suitable when used with s132. */
  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 flash. */
  BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x0007F000, LENGTH = 0x1000

  /** Location in UICR where bootloader start address is stored. */
  UICR_BOOTLOADER (r) : ORIGIN = 0x10001014, LENGTH = 0x04
  
  /** Location of mbr params page in flash. */
  MBR_PARAMS_PAGE (rw) : ORIGIN = 0x0007E000, LENGTH = 0x1000
  
  /** Location in UICR where mbr params page address is stored. */
  UICR_MBR_PARAM_PAGE(r) : ORIGIN = 0x10001018, LENGTH = 0x04
}

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

  /* Place the bootloader settings page in flash. */
  .bootloaderSettings(NOLOAD) :
  {
    
  } > BOOTLOADER_SETTINGS

  /* Write the bootloader address in UICR. */
  .uicrBootStartAddress : 
  {
    KEEP(*(.uicrBootStartAddress))
  } > UICR_BOOTLOADER
  
  /* Place the mbr params page in flash. */
    .mbrParamsPage(NOLOAD) :
  {
    
  } > MBR_PARAMS_PAGE
  
  /* Write the bootloader address in UICR. */
  .uicrMbrParamsPageAddress :
  {
    KEEP(*(.uicrMbrParamsPageAddress))
  } > UICR_MBR_PARAM_PAGE

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

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

INCLUDE "nrf52_common.ld"

But currently I did many tries and could not make it to work, so I have few questions:

  1. The non initialized RAM section should be placed only in the bootloader linker file? and if so how does my application project which have the same variable definition will know where to put it?
  2. Is there a way to define such a variable in GCC to a specific address like in the IAR?
  3. And the biggest question, what I'm missing? how could I get it to work
  • btw: I'm not interesting with bond information sharing between the bootloader and the application at the moment, just need it to work with eclipse as was with IAR.
  • Hi, Have you made any progress?

    1. The RAM section should be defined in both linker files. Did you try it already?
    2. I'm pretty sure that is the correct way of doing it.
  • Hello Martin and thank you for your comment, unfortunately no progress at all :(

    I did tried to defined the non init section in both linker files with no success, but perhaps I should try this again. My application linker file is like that:

    /* Linker script to configure memory regions. */
    
    SEARCH_DIR(.)
    GROUP(-lgcc -lc -lnosys)
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x1c000, LENGTH = 0x64000
      RAM (rwx) :  ORIGIN = 0x20002080, LENGTH = 0xdf80
    }
    
    SECTIONS
    {
      .fs_data :
      {
        PROVIDE(__start_fs_data = .);
        KEEP(*(.fs_data))
        PROVIDE(__stop_fs_data = .);
      } > RAM
    } INSERT AFTER .data;
    
    INCLUDE "nrf5x_common.ld"
    

    So since the RAM section is ended in 0x20010000, the non init section should start from there. But when I do the necessary changes in the bootloader linker file (non init section start from 0x20010000) the bootloader is not working at all, not advertising.

    • Question: If I have multiple non init variables defined both in the application and in the bootloader, how they will get the same absolute address? should they defined static or not?
Related