cancel
Showing results for 
Search instead for 
Did you mean: 

How to change linker script file in order to put data into CCMRAM?

STork.1
Associate III

Hello everybody! I need to store dataset into the RAM of my MCU. I use STM32H755ZIT6, Dual Core M7+M4. The problem is that when I define buffer for my data the ram will overflow. The Ram size is 1MB but the whole data set's size is around 250KB. it seems that the RAM is not contiguous and based on my search on the internet the clue I have is to use Core Coupled Memory RAM. Around 2/3 of my data fits into the RAM and I want to store the rest of it into the CCRAM area. Sofar I unly could understood that using this statement I can store variable in CCRAM:

__attribute__((section(".ccmram-strings"))) float Data_Set_Z[15000];

When I want to assign a value into this variable, the compiler shows the RAM overflow error. I read some application notes of ST and some block of memories have different address but I don't know how to use the in linker script.

Here is the Linker script file:

here is also the RAM.ld file

/*

******************************************************************************

**

** File    : LinkerScript.ld

**

**

** Abstract  : Linker script for STM32H7 series

**        256Kbytes RAM_EXEC and 256Kbytes 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) 2019 STMicroelectronics.

** All rights reserved.

**

** This software component is licensed by ST under BSD 3-Clause license,

** the "License"; You may not use this file except in compliance with the

** License. You may obtain a copy of the License at:

**            opensource.org/licenses/BSD-3-Clause

**

****************************************************************************

*/

/* Entry Point */

ENTRY(Reset_Handler)

/* Highest address of the user mode stack */

_estack = 0x24080000;  /* end of RAM */

/* 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

{

RAM_EXEC (rx)   : ORIGIN = 0x24000000, LENGTH = 256K

RAM (xrw)   : ORIGIN = 0x24040000, LENGTH = 256K

}

/* Define output sections */

SECTIONS

{

 /* The startup code goes first into RAM_EXEC */

 .isr_vector :

 {

  . = ALIGN(4);

  KEEP(*(.isr_vector)) /* Startup code */

  . = ALIGN(4);

 } >RAM_EXEC

 /* The program code and other data goes into RAM_EXEC */

 .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 */

 } >RAM_EXEC

 /* Constant data goes into RAM_EXEC */

 .rodata :

 {

  . = ALIGN(4);

  *(.rodata)     /* .rodata sections (constants, strings, etc.) */

  *(.rodata*)    /* .rodata* sections (constants, strings, etc.) */

  . = ALIGN(4);

 } >RAM_EXEC

 .ARM.extab  : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >RAM_EXEC

 .ARM : {

  __exidx_start = .;

  *(.ARM.exidx*)

  __exidx_end = .;

 } >RAM_EXEC

 .preinit_array   :

 {

  PROVIDE_HIDDEN (__preinit_array_start = .);

  KEEP (*(.preinit_array*))

  PROVIDE_HIDDEN (__preinit_array_end = .);

 } >RAM_EXEC

 .init_array :

 {

  PROVIDE_HIDDEN (__init_array_start = .);

  KEEP (*(SORT(.init_array.*)))

  KEEP (*(.init_array*))

  PROVIDE_HIDDEN (__init_array_end = .);

 } >RAM_EXEC

 .fini_array :

 {

  PROVIDE_HIDDEN (__fini_array_start = .);

  KEEP (*(SORT(.fini_array.*)))

  KEEP (*(.fini_array*))

  PROVIDE_HIDDEN (__fini_array_end = .);

 } >RAM_EXEC

 /* 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 */

  . = ALIGN(4);

  _edata = .;    /* define a global symbol at data end */

 } >RAM AT> RAM_EXEC

  

 /* Uninitialized data section */

 . = ALIGN(4);

 .bss :

 {

  /* This is used by the startup in order to initialize the .bss secion */

  _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;

 } >RAM

 /* 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);

 } >RAM

  

 /* Remove information from the standard libraries */

 /DISCARD/ :

 {

  libc.a ( * )

  libm.a ( * )

  libgcc.a ( * )

 }

 .ARM.attributes 0 : { *(.ARM.attributes) }

}

  

another thing I am considering is that the RAM blocks are as follows:0693W000006HdaLQAS.png 

based on Linker script file I mentioned before, a 256KB block is only used . that is the reason of RAM overflow ,I think... .

2) How Can I use a bigger block? for example the block the name of which is SRAM mapped onto AXI bus 512 in the table below?

0693W000006HddUQAS.png 

Despite the searches I did I could not understand how to change the linker-script files. Is there anybody who has time to help me regarding the mentioned two questions??

I think the more logical choice is to just select the bigger RAM In D1 domain which is also provided to M7 Core I am using ....

I tried changing the address space of the ram in the .ld file . at first, it was from /* : ORIGIN = 0x24000000, LENGTH = 256K */ to /* : ORIGIN = 0x24040000, LENGTH = 256K */.

then I changed it from 0x24000000, LENGTH = 512K to : ORIGIN = 0x2407FFFF, LENGTH = 512K according to memory-map file in the user manuals but after biulding the project I still get the ram overflow messege...... Please Help :)))

here are the error messeges.

0693W000006HdfzQAC.png 

Looking forward to your replies.

Best Regards

10 REPLIES 10

That was a really nice answer, Thank you !!

My first problem is that after storing around 12000 samples, without changing the linker-script file, my program crashed.... when I store only 30000 samples, the program works correctly...

1- What can be the reason?

I checked the address of the DTCMRAM which starts from 0x20000000 (in your answer it was 0x00000000). now after I changed it, the performance of the program gets even worse and after storing 3640 samples into RAM the program stopped working.... it crashed.... Can you please inform me what I am supposed to do ?...

0693W00000AMJ8rQAH.pngAnother thing that seems strange to me is that the build analyzer shows the ram amount for 128KB . The M7 core I am using access directly to AXI SRAM the size of which is 512KB. maybe if I find a way to increase the memory which is shown in build analyzer, that can solve my problem without using DTCM RAM... What do you think in this regard?

About changing the statup.s file, maybe that is too much to be asked.... can you also help me in this regard?