cancel
Showing results for 
Search instead for 
Did you mean: 

Why FLASH and SRAM2 sizes are different in my linker script created by STM32CubeIDE / STM32CubeMX?

alitastan
Associate II

Hello everyone,

I have recently created a new project for my development board NUCLEO-WB15CC from STM32CubeIDE. There are some conflict in sizes of SRAM2 and FLASH. In the RM0473, SRAM2a is described as 32KB and SRAM2b is described as 4KB and these are mirrored (I think mirroring is to protect memory in case some fault occurs). To my understanding, SRAM2a and SRAM2b are defined as RAM_SHARED in linker script and its size is 10KB. In my opinion, something seems wrong here. Also, in the reference manual, FLASH size is mentioned as up to 320KB. However, in my linker script its size is 110KB. According to single bank organization there are 160 pages each being 2KB but there are also 28KB of System Memory, 1KB of OTP area and 128 bytes of option bytes. I think it should be more than 320KB but I am not sure. In addition to that, why SRAM1 is defined as 0x2FFC instead of 12KB or 0x3000? I am really confused and I would be very happy if someone could help me. Thanks.

I am using STM32CubeIDE version 1.8.0 and STM32CubeMX version 6.5.0

Here is my linker script:

/*
******************************************************************************
**
**  File        : LinkerScript.ld
**
**  Author      : STM32CubeIDE
**
**  Abstract    : Linker script for STM32WB15xC Device
**                      320Kbytes FLASH
**                       48Kbytes RAM
**
**                Set heap size, stack size and stack location according
**                to application requirements.
**
**                Set memory bank area and size if external memory is used.
**
**  Target      : STMicroelectronics STM32
**
**  Distribution: The file is distributed as is without any warranty
**                of any kind.
**
*****************************************************************************
** @attention
**
** Copyright (c) 2021 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
*****************************************************************************
*/
 
/* Entry Point */
ENTRY(Reset_Handler)
 
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM1) + LENGTH(RAM1);    /* end of RAM1 */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200 ;      /* required amount of heap  */
_Min_Stack_Size = 0x400 ;   /* required amount of stack */
 
/* Specify the memory areas */
MEMORY
{
FLASH (rx)                 : ORIGIN = 0x08000000, LENGTH = 110K
RAM1 (xrw)                 : ORIGIN = 0x20000004, LENGTH = 0x2FFC
RAM_SHARED (xrw)           : ORIGIN = 0x20030000, LENGTH = 10K
}
 
/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH
 
  /* The program code and other data goes into FLASH */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)
 
    KEEP (*(.init))
    KEEP (*(.fini))
 
    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH
 
  /* Constant data goes into FLASH */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH
 
  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
  .ARM : {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } >FLASH
 
  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FLASH
  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >FLASH
  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >FLASH
 
  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);
 
  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
    *(.RamFunc)        /* .RamFunc sections */
    *(.RamFunc*)       /* .RamFunc* sections */
 
    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM1 AT> FLASH
 
  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)
 
    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM1
 
  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM1
 
  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }
 
  .ARM.attributes 0       : { *(.ARM.attributes) }
   MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM_SHARED
   MB_MEM1 (NOLOAD)       : { *(MB_MEM1) } >RAM_SHARED
   MB_MEM2 (NOLOAD)       : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED
}
 
 

6 REPLIES 6
Piranha
Chief II

> According to single bank organization there are 160 pages each being 2KB but there are also 28KB of System Memory, 1KB of OTP area and 128 bytes of option bytes. I think it should be more than 320KB but I am not sure.

No, this is a memory section in which the linker will put your code and data. This has nothing to do with the System memory, OTP area or Option bytes, all of which are located at a completely different addresses. Just define the LENGTH as "320K".

> In addition to that, why SRAM1 is defined as 0x2FFC instead of 12KB or 0x3000?

Look at the start address... Maybe they are using the first 4 bytes for a bootloader or something like that? If you need those, then define the LENGTH as "12K - 4".

Remy ISSALYS
ST Employee

Hello,

In order to determine the maximum FLASH length available for the application, you can look the value of SFSA option byte after flashing the wireless stack and deduct the length:

Maximum Flash available for the application = (SFSA address - 0x08000000) / 1024

Best Regards

Hello,

From the reference manual, SFSA option bytes are stored at flash memory address 0x1FFF7870.

0693W00000QMHJwQAP.pngFrom the CubeIDE, SFR address location is 0x58004080 and SFSA value is 0x38. I checked both addresses 0x1FFF7870 and 0x58004080 and the value at these addresses are 0x1038. Which one is considered as SFSA address? None of these addresses are giving me the maximum flash available when placed in the formula given above.0693W00000QMHLTQA5.png0693W00000QMHLnQAP.pngSystem and Flash secure. SFSA[7:0] contains the start address of the first 2 Kbytes page of

the secure Flash area. So, in this case SFSA value is 0x38. Is this kind of an offset? How can I use this value?

Also, why do you think RAM_SHARED (SRAM2A and SRAM2B) address length is 10KB instead of 36KB?

Thanks for your time and patience.

Best Regards

Remy ISSALYS
ST Employee

Hello,

In order to read the SFSA option byte, you can use STM32CubeProgrammer tool like this:

0693W00000QMHlHQAX.pngThe SRAM2 is shared between the CPU1 and the CPU2, so only a part of the SRAM2 is dedicated to the CPU1.

Best Regards

Hello,

My SFSA value is 0x0801c000 and this indicates that my FLASH size is 112KB. Am I right? Why this value is different than the values mentioned in the created linker script and in the reference manual?

0693W00000QMh6FQAT.png

Remy ISSALYS
ST Employee

Hello,

Yes you have right, in your case you have 112 KB of flash available for your application (CPU1). The value mentioned in the linker script is the maximum flash size allocated for the application, this value can't exceed the 112 KB in your case. The value mentioned in the reference manual is the total flash size available.

Best Regards