Почему malloc работает только сразу после прошивки cortex-m3?

#malloc #heap-memory #cortex-m3 #newlib

#malloc #куча-память #cortex-m3 #newlib

Вопрос:

Я пытаюсь динамически выделить память, используя malloc от newlib, работающий на cortex-m3 («голый металл»), и я столкнулся с озадачивающей проблемой. Сразу после прошивки устройства malloc и free работают должным образом. Однако, как только я перезагружаю устройство, malloc возвращает только NULL. Все остальное работает, кроме malloc. Есть какие-либо подсказки о том, что может вызвать такое поведение?

Вот мой скрипт компоновщика:

 MEMORY
{
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
    SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 32K
}

/* Section Definitions */
SECTIONS
{
   .text :
  {
    KEEP(*(.isr_vector .isr_vector.*))
    *(.text .text.*)
    *(.gnu.linkonce.t.*)
    *(.glue_7)
    *(.glue_7t)
    *(.gcc_except_table)
    *(.rodata .rodata*)
    *(.gnu.linkonce.r.*)
    _etext = .;
  } > FLASH

  __exidx_start = .;
  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > FLASH
  __exidx_end = .;

  /*.data : AT (_etext)*/
  .data : AT (__exidx_end)
  {
    _data = .;
    *(vtable vtable.*)
    *(.data .data.*)
    *(.gnu.linkonce.d*)
    . = ALIGN(4);
    _edata = . ;
  } > SRAM

  /* .bss section which is used for uninitialized data */
  .bss (NOLOAD) :
  {
    _bss = . ;
    *(.bss .bss.*)
    *(.gnu.linkonce.b*)
    *(COMMON)
    . = ALIGN(4);
    _ebss = . ;
  } > SRAM

  .stackarea (NOLOAD) :
  {
    . = ALIGN(8);
    *(.stackarea .stackarea.*)
    . = ALIGN(8);
  } > SRAM

  . = ALIGN(4);
  _end = . ;
  PROVIDE (end = .);

}
  

И это из моей карты памяти:

 .stackarea      0x10000d3c        0x4
                0x10000d40                . = ALIGN (0x8)
 *fill*         0x10000d3c        0x4 00
 *(.stackarea .stackarea.*)
                0x10000d40                . = ALIGN (0x8)
                0x10000d40                . = ALIGN (0x4)
                0x10000d40                _end = .
                0x10000d40                PROVIDE (end, .)
  

Когда malloc завершается успешно, он начинает выделение с 0x10000d48.

Комментарии:

1. что возвращает ‘mallinfo()’ после сброса?

Ответ №1:

Я не совсем уверен, как это работает на вашем Cortext-M3, но некоторое время назад у меня были некоторые проблемы с управлением памятью на RX62N. В конце концов, я решил заняться собственным управлением памятью, создав большую кучу, а затем выделить память с помощью моих собственных функций API. Я использовал простой связанный список для управления памятью. Таким образом, я могу гарантировать, что он будет работать каждый раз на моей плате и в коде 🙂

Надеюсь, это поможет 🙂 Приветствия!

Ответ №2:

Стек должен иметь более высокий адрес, чем куча.

Стек растет вниз, а куча вверх. Итак, поместите начало стека на последний адрес в SRAM. Куча начинается с метки «_end» и заканчивается в нижней части стека, поэтому попробуйте поместить метку «_end» сразу после метки «_ebss».

например.

   /* .bss section which is used for uninitialized data */  
  .bss (NOLOAD) :  
  {  
    _bss = . ;  
    *(.bss .bss.*)  
    *(.gnu.linkonce.b*)  
    *(COMMON)  
    . = ALIGN(4);  
    _ebss = . ;  
    **_end = . ;**  
  } > SRAM