0

我正在使用 STM32H755ZI MCU。这个MCU有1MB RAM,其中512KB可以被M7 Core直接访问。我必须存储 45000 个浮点样本,其大小约为 180KB。

我的第一个问题是,在存储了大约 12000 个样本后,我的程序崩溃了......当我只存储 30000 个样本时,程序正常工作......

1-第一个问题:可能是什么原因?

我决定将两个数组存储在 RAM 中,并将第三个数组存储在 DTCMRAM 中。每个阵列的大小约为 60KB,DTCM RAM 的大小为 128KB。我应该更改 linker_script 文件。

这就是我定义数组的方式:

作为局部变量进入主函数:float Data_Set_X[12000]={0}; 浮动 Data_Set_Y[12000]={0};

作为全局变量: attribute ((section(".dtcmram"))) float Data_Set_Z[12000];

这是我使用的内存映射文件 MCU: 在此处输入图像描述

这是默认的链接器脚本:

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



The changed linker script file is presented as follows:
enter code here
    
    /*
    ******************************************************************************
    **
    ** 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_Heap_Size = 0x200 ;*/
    _Min_Stack_Size = 0x400 ; /* required amount of stack */      /* _Min_Stack_Size = 0x400 */
     
    
        /* Specify the memory areas */
        MEMORY
        {
        RAM_DTCM (rw)   : ORIGIN = 0x20000000, LENGTH = 128K 
        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
     
     .dtcm (NOLOAD) :
     {
       *(.dtcmram)
       *(.dtcmram*)
     } >RAM_DTCM
     
     /* 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) }
    }

我检查了从 0x20000000 开始的 DTCMRAM 的地址。现在,在这些更改之后,程序的性能变得更糟,在将 3640 个样本存储到 RAM 后,程序停止工作....它崩溃了....对我来说似乎很奇怪的另一件事是构建分析器显示了128KB ....也许如果我找到增加它的方法,那可以在不使用DTCM RAM的情况下解决我的问题...有人知道这个问题吗? 在此处输入图像描述

为了使用 DTCM RAM,我应该如何更改链接描述文件?有没有其他方法可以解决上述存储 450000 个样本的问题?

对于上述问题,我将不胜感激并提供帮助或反馈。先感谢您。

4

1 回答 1

0

我已将链接器文件更改为包括:

/* 使用 RAM_D2 保存“.myvarsRAM_D2”变量 */

.myvarsRAM_D2 : { . =对齐(4);*(.myvarsRAM_D2) (.myvarsRAM_D2); } >RAM_D2

并在 .h 文件中定义了以下宏,然后我将其用作前缀覆盖:

#define MY_VARS_RAM_D2 属性((section(".myvarsRAM_D2")))

在我的代码中,我使用类似的东西:

MY_VARS_RAM_D2 uint_8 变量XXXX[10000];// 这会将数组放入 RAM_D2

您可以对所有其他 RAM 区域执行相同的技巧,包括 DTCMRAM 祝你好运

于 2022-02-17T20:22:55.783 回答