简体   繁体   English

已初始化与未初始化的全局变量,存储在 RAM 的哪一部分?

[英]Initialized vs uninitialized global variables, in which part of the RAM are the stored?

The problem is that When I define the arrays like this:问题是当我像这样定义 arrays 时:

float Data_Set_X[15000];
float Data_Set_Y[15000];
float Data_Set_Z[15000];

I get the RAM overflow error which is: .bss will not fit in region RAM Timer-Blink-Test_CM7 C/C++ Problem我收到 RAM 溢出错误,即: .bss不适合区域RAM Timer-Blink-Test_CM7 C/C++ 问题

When I initilaze at least one of the arrays or three of them, the error will be disappeared.当我至少启动 arrays 中的一个或三个时,错误将消失。

float Data_Set_X[15000]={0};
float Data_Set_Y[15000];
float Data_Set_Z[15000];

My variables are global.我的变量是全局的。

In linker script file it is written that:在 linker 脚本文件中写道:

/* Specify the memory areas */ 

MEMORY
{
    RAM_EXEC (rx)   : ORIGIN = 0x24000000, LENGTH = 256K   
    RAM (xrw)   : ORIGIN = 0x24040000, LENGTH = 256K     
}

/* The startup code goes first into RAM_EXEC */
/* The program code and other data goes into RAM_EXEC */
/* Constant data goes into RAM_EXEC */
/* Initialized data sections goes into RAM, load LMA copy after code */

And there is a separated part of the RAM for /* Uninitialized data section */ according to the linker script.根据 linker 脚本, /* Uninitialized data section */有一个单独的 RAM 部分。

The RAM size is 1MB and around 800KB is accessible for the user. RAM 大小为 1MB,用户可以访问大约 800KB。 MCU has dual core and I use the M7 Core. MCU有双核,我使用M7 Core。 this core can access to a 512KB RAM area as it is mentioned in the Linker Script file.如 Linker 脚本文件中所述,此内核可以访问 512KB RAM 区域。 the whole size of these three arrays are 180KB这三个arrays的总大小是180KB

Here is the linker Script file of my Micro Controller这是我的 Micro Controller 的 linker 脚本文件

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

Thank you!谢谢!

Then using this linker script the initialized static storage objects will be stored in the RAM memory section as the .data segment is stored there.然后使用这个 linker 脚本初始化的 static 存储对象将存储在RAM memory 部分中,因为.data段存储在那里。

The initial values will be stored in the RAM_EXEC memory section.初始值将存储在RAM_EXEC memory 部分中。 The startup code will have to copy this data from the RAM_EXEC to RAM .启动代码必须将此数据从RAM_EXEC复制到RAM

The problem is that something (probably the debug probe or the bootloader) will have to program the RAM_EXEC memory section first问题是某些东西(可能是调试探针或引导加载程序)必须首先对RAM_EXEC memory 部分进行编程

The not initialized static storage objects will be stored in the RAM memory section as the .bss section is located there.未初始化的 static 存储对象将存储在RAM memory 部分中,因为.bss部分位于那里。 The startup code will have to zero those启动代码必须将那些归零

The best way is to see what is actually in the memory and where.最好的方法是查看 memory 中的实际内容和位置。 Generate the .map file to see the exact placement (you can increase the size of the RAM to pass the linking. It will not be the valid executable, but you will be able to generate the.map file)生成.map文件以查看确切位置(您可以增加 RAM 的大小以通过链接。它不是有效的可执行文件,但您将能够生成 .map 文件)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM