cancel
Showing results for 
Search instead for 
Did you mean: 

How to put stack and heap in different memroy sections

GreenGuy
Lead
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?

2 REPLIES 2
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
Up vote any posts that you find helpful, it shows what's working..
GreenGuy
Lead
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.