cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7~How to allocate arrays to a certain location

CFran.1
Associate II

I tried adding this to the linker file

/* used by the startup to initialize data */

 _sidata_RAM_D3 = LOADADDR(.data_RAM_D3);

 /* Initialized data sections goes into RAM_D3, load LMA copy after code */

 .data_RAM_D3 : 

 {

  . = ALIGN(4);

  _sdata_RAM_D3 = .;    /* create a global symbol at data start */

  *(.data_RAM_D3)      /* .data sections */

  *(.data_RAM_D3*)     /* .data* sections */

  . = ALIGN(4);

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

 } >RAM_D3 AT> FLASH 

  

 /* Uninitialized data section */

 . = ALIGN(4);

 .bss_RAM_D3 :

 {

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

  _sbss_RAM_D3 = .;     /* define a global symbol at bss start */

  __bss_start__ = _sbss_RAM_D3;

  *(.bss_RAM_D3)

  *(.bss_RAM_D3*)

  *(COMMON)

  . = ALIGN(4);

  _ebss_RAM_D3 = .;     /* define a global symbol at bss end */

  __bss_end__ = _ebss_RAM_D3;

 } >RAM_D3

 .RAM_D3 : { *(.RAM_D3) } >RAM_D3 AT> FLASH

Then tried array[16] __attribute__((section(".RAM_D3"))), this is from an example. Every time I run the code, the location never changes from 0x2xxxxxxx, I know about data coherence. but shouldn't it be displaying an address in the range of RAM3?

9 REPLIES 9
TDK
Guru

What location is RAM_D3 defined at? Did you change it from the default 0x20000000? Should be something similar in your linker file:

/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 20K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 64K
}

If you feel a post has answered your question, please click "Accept as Solution".
CFran.1
Associate II

I added, RAM_D3 (xrw)   : ORIGIN = 0x38000000, LENGTH = 64K to the file, was there anything else I needed to add? or do I replace RAM with RAM_D3?

I added, RAM_D3 (xrw)   : ORIGIN = 0x38000000, LENGTH = 64K to the file, was there anything else I needed to ad? or do I replace RAM with RAM_D3?

It’d probably be easier to decipher if you just posted the whole file.
If you feel a post has answered your question, please click "Accept as Solution".
/*
******************************************************************************
**
**  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
RAM_D3 (xrw)      : ORIGIN = 0x38000000, LENGTH = 64K
}
 
/* 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
 
  /* used by the startup to initialize data */
  _sidata_RAM_D3 = LOADADDR(.data_RAM_D3);
 
  /* Initialized data sections goes into RAM_D3, load LMA copy after code */
  .data_RAM_D3 : 
  {
    . = ALIGN(4);
    _sdata_RAM_D3 = .;        /* create a global symbol at data start */
    *(.data_RAM_D3)           /* .data sections */
    *(.data_RAM_D3*)          /* .data* sections */
 
    . = ALIGN(4);
    _edata_RAM_D3 = .;        /* define a global symbol at data end */
  } >RAM_D3 AT> FLASH 
 
  
  /* Uninitialized data section */
  . = ALIGN(4);
  .bss_RAM_D3 :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _sbss_RAM_D3 = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss_RAM_D3;
    *(.bss_RAM_D3)
    *(.bss_RAM_D3*)
    *(COMMON)
 
    . = ALIGN(4);
    _ebss_RAM_D3 = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss_RAM_D3;
  } >RAM_D3
 
  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }
  
 
  
  .ARM.attributes 0 : { *(.ARM.attributes) }
  .RAM_D3 : { *(.RAM_D3) } >RAM_D3 AT> FLASH
}
 
 

Please put in a link to your other thread to give context.

I believe in your program you are trying to allocate variables using

__attribute__((section(".RAM_D3")));

while not having defined a .RAM_D3 input section here in the linker script.

[EDIT] I overlooked that it's in the last statement in the script. Have a look at the .map file, how did the linker allocate the variable in question.

Try to remove the AT> FLASH statement, as you are trying to allocate uninitialized data, IIRC.

Alternatively, try to assign those variables into .bss_RAM_D3

JW

TDK
Guru

To put data somewhere else, you need three things.

Create a memory area, which you've done:

RAM_D3 (xrw)      : ORIGIN = 0x38000000, LENGTH = 64K

Then create a section (optionally, define it as NOLOAD if it shouldn't be initialized from flash):

.DATA_RAM_D3 (NOLOAD) :
  {
  } >RAM_D3

Then define your array using that section as an attribute:

uint8_t my_array[2048] __attribute__ ((section (".DATA_RAM_D3")));

You're doing some interesting things in that linker script which I doubt are intentional. You're storing data+code in RAM, but then also using it in a different section of RAM. You also don't have the FLASH memory defined, but are trying to use it. The linker throws a warning about this.

If you feel a post has answered your question, please click "Accept as Solution".

> .DATA_RAM_D3 (NOLOAD) :

> {

> } >RAM_D3

I believe you need to define input sections within that output section, too.

 

(If not and this works, then there may be some automatism in current versions of the GNU linker which e.g. generates some default input section with the same name as output section - it's been quite some time I looked last time at the ld's internals, and I tend to avoid making any changes to working toolchains unless there's some serious reason to do so.)

Okay I found it, https://stackoverflow.com/questions/17054882/what-is-the-effect-of-a-section-command-with-an-empty-list-of-input-sections-i - it was probably there all the time, not very systematic and may lead to confusion, but not surprising given the nature of the GNU toos.

JW

I checked, it worked in gcc/stm32cubeide. Perhaps there is a more correct syntax.
If you feel a post has answered your question, please click "Accept as Solution".