Skip to main content
GreenGuy
Senior III
April 30, 2018
Question

How to put stack and heap in different memroy sections

  • April 30, 2018
  • 2 replies
  • 1395 views
Posted on April 30, 2018 at 22:20

I have heard the benefit of putting the stack at the beginning of DTCMRAM + the minimum size required as then stack accesses exceeding the size of the stack will throw the execution to the exception fault.  However the default directive in the linker for stack location includes the heap (._user_heap_stack), or so I presume.  I do not what the heap in the DTCMRAM due to the possibility of the heap being used for a variable that may end up needing to be accessed by DMA.  So the question; how to separate them.  I gather from reading other linker script posts that I could create two sections; 1) ._user_stack and 2) ._user_heap, but the question is then how to make the rest of the project aware and use the assignments as intended?  Anyone done this before for which you might be able to share an example?

    This topic has been closed for replies.

    2 replies

    Tesla DeLorean
    Guru
    May 1, 2018
    Posted on May 01, 2018 at 04:50

    Well the example .LD files do have this stupid nonsense where they use '. = . + _Min_Stack_Size;' and then use '_estack = 0x2004C000; /* end of RAM */' to set some absolute and unrelated value.

    You could put this in your own region

    . = . + _Min_Stack_Size;

    _estack = .; /* top of stack, descends downward, and predecrements */

    Or the quick-and-dirty way would be to describe the _estack value you want, and then removing the memory you want it to use from that visible to the linker in the MEMORY { } descriptions.

    You'd also need to fix the _sbrk allocator (syscalls.c) that assumes the heap extends between the top of statics thru bottom of stack, again entirely ignoring _Min_Heap_Size

    Code like this will choke if the memory region used for the Stack is below the Heap

    sbrk

    Increase program data space.

    Malloc and related functions depend on this

    */

    caddr_t _sbrk(int incr) {
     extern char _ebss; // Defined by the linker

     static char *heap_end;

     char *prev_heap_end;
     if (heap_end == 0) {

     heap_end = &_ebss;

     }

     prev_heap_end = heap_end;
    char * stack = (char*) __get_MSP();

     if (heap_end + incr > stack)

     {

     _write (STDERR_FILENO, 'Heap and stack collision
    ', 25);

     errno = ENOMEM;

     return (caddr_t) -1;

     //abort ();

     }
     heap_end += incr;

     return (caddr_t) prev_heap_end;
    }

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    GreenGuy
    GreenGuyAuthor
    Senior III
    May 1, 2018
    Posted on May 01, 2018 at 17:46

    Well here is a thought:

    Split the DTCMRAM into two regions with the upper most region for heap_stack.  Then use the MPU to separate the upper most region into two sections one for stack and one heap.  That way if either heap or stack overrun an exception fault is thrown.