ST意法半导体
直播中

艾玛

12年用户 803经验值
擅长:模拟技术 EDA/IC设计 RF/无线
私信 关注
[问答]

“新”运算符导致C++项目崩溃要如何处理?

大家好,
我正在将一个 C++ 项目从 STM32H7 EVAL 板移植到 STM32H7 Nucleo 144。
该项目使用CubeMX 生成项目,然后我移植所有源代码并设置c/c++/linker 目录、符号和设置。
该项目使用 FreeRTOS,当在库实例上调用 new() 时,RTOS 的一个线程将在默认错误处理程序 (_exit()) 中进入无限循环。其他线程继续运行正常。
链接器将用户数据放在 RAMD1 中,因为它是最大的部分,我需要空间。
我检查/尝试过的一些事情:
  • 库使用与项目相同的 C++ 版本 (C++ 14) 编译
  • 启用硬件 FPU(库使用浮点数)
  • 链接器脚本中的最小堆栈和堆就足够了
  • RTOS 线程分配的堆栈/堆大小足够
  • RMD1 部分启用时钟
  • 尝试在链接器中将数据对齐到 4 字节和 8 字节
  • 128 / 4096 字节 malloc() 页面大小
逐步执行说明,我可以看到这是导致问题的行。
  • bl   0x80aa7fe <_Znwj>
这是我的链接器脚本,以防有任何帮助
  • /*
  • *****************************************************************************
  • **
  • **  File        : stm32_flash.ld
  • **
  • **  Abstract    : Linker script for STM32H743ZI Device with
  • **                2048KByte FLASH, 1056KByte 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
  • **
  • **  Environment : Atollic TrueSTUDIO(R)
  • **
  • **  Distribution: The file is distributed as is, without any warranty
  • **                of any kind.
  • **
  • **  (c)Copyright Atollic AB.
  • **  You may use this file as-is or modify it according to the needs of your
  • **  project. This file may only be built (assembled or compiled and linked)
  • **  using the Atollic TrueSTUDIO(R) product. The use of this file together
  • **  with other tools than Atollic TrueSTUDIO(R) is not permitted.
  • **
  • *****************************************************************************
  • */
  • /* Entry Point */
  • ENTRY(Reset_Handler)
  • /* Highest address of the user mode stack */
  • _estack = 0x24080000;
  • /* Generate a link error if heap and stack don't fit into RAM */
  • _Min_Heap_Size = 0x20000;      /* required amount of heap  */
  • _Min_Stack_Size = 0x20000; /* required amount of stack */
  • /* Specify the memory areas */
  • MEMORY
  • {
  • DTCMRAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 128K
  • RAM_D1 (xrw)      : ORIGIN = 0x24000000, LENGTH = 512K
  • RAM_D2 (xrw)      : ORIGIN = 0x30000000, LENGTH = 288K
  • RAM_D3 (xrw)      : ORIGIN = 0x38000000, LENGTH = 64K
  • ITCMRAM (xrw)      : ORIGIN = 0x00000000, LENGTH = 64K
  • FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 2048K
  • }
  • /* 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 */
  •     . = ALIGN(4);
  •     _edata = .;        /* define a global symbol at data end */
  •   } >RAM_D1 AT> FLASH
  •   /* 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_D1
  •   /* User_heap_stack section, used to check that there is enough RAM left */
  •   ._user_heap_stack :
  •   {
  •     . = ALIGN(4);
  •     PROVIDE ( end = . );
  •     PROVIDE ( _end = . );
  •     . = . + _Min_Heap_Size;
  •     . = . + _Min_Stack_Size;
  •     . = ALIGN(4);
  •   } >RAM_D1
  •   /* Remove information from the standard libraries */
  •   /DISCARD/ :
  •   {
  •     libc.a ( * )
  •     libm.a ( * )
  •     libgcc.a ( * )
  •   }
  •   .ARM.attributes 0 : { *(.ARM.attributes) }
  • }

该库被认为是好的,并且已经在不同硬件上的同一个 IC 上运行。
非常感谢任何帮助!






回帖(1)

李金云

2023-2-1 10:06:41
它与不使用 FreeRTOS 堆栈的 new、new[] 和 malloc() 有关。需要通过 RTOS 路由所有内容的新版本 syscalls.cpp 以防止动态分配崩溃。
我很惊讶在 CubeMX 中生成 FreeRTOS 项目时没有提到这一点。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分