How can I align stack to the end of SRAM?

499 views Asked by At

I have a STM32F103VCT6 microcontroller with 48kb of SRAM, and recently i've got a memory collision:

I have some static variable (lets call it A) located in heap with size of 0x7000 and I wrote some simple function to get info about stack and heap:

void check(int depth) {
    char c;
    char *ptr = malloc(1);
    printf("stack at %p, heap at %p\n", &c, ptr);
    if (depth <= 0) return;
    check(depth-1);
}

So I got something like this:

stack at 2000939b, heap at 20008fd0
stack at 20009383, heap at 20008fe0
stack at 2000936b, heap at 20008ff0
stack at 20009353, heap at 20009000
stack at 2000933b, heap at 20009010
stack at 20009323, heap at 20009020
stack at 2000930b, heap at 20009030
stack at 200092f3, heap at 20009040
stack at 200092db, heap at 20009050
stack at 200092c3, heap at 20009060
stack at 200092ab, heap at 20009070

All static variables (incliding A) already got their heap, so heap is located at 0x8fd0. And seems like, originally, stack pointer is located at 0x939b, that is far away from 48kb (0xc000)

And when I changed the A variable size to 0x4000 I've got this picture:

stack at 2000639b, heap at 20005fd0
stack at 20006383, heap at 20005fe0
stack at 2000636b, heap at 20005ff0
stack at 20006353, heap at 20006000
stack at 2000633b, heap at 20006010
stack at 20006323, heap at 20006020
stack at 2000630b, heap at 20006030
stack at 200062f3, heap at 20006040
stack at 200062db, heap at 20006050
stack at 200062c3, heap at 20006060
stack at 200062ab, heap at 20006070

So, seems like stack location is not located at the end of SRAM but, some how, rely on user defined variables.

How can I align the stack to be at the very end of SRAM (at the 48kb)?

I am using the CooCox IDE with GNU Tools ARM Embedded toolchain.

Thank you!

EDIT:

Sorry for some misunderstanding here, A isn't const, i've called it static only because of keyword:

static uint8_t A[A_SIZE];    
printf("A is at %p\n", &A);

This shows that A is located at the begginning of the memory:

A is at 20000c08
2

There are 2 answers

2
desertkun On BEST ANSWER

I've found the reason: that's because stack size is actually fixed and it is located in heap (if I could call it heap).

In file startup_stm32f10x*.c there is a section:

/*----------Stack Configuration----------*/  
#define STACK_SIZE       0x00000100      /*!< The Stack size suggest using even number     */

And at then very next line:

__attribute__ ((section(".co_stack")))
unsigned long pulStack[STACK_SIZE];    

I've changed this value to 0x00000500 and got everything working.

2
Clifford On

The GNU toolchain uses a target specific linker script (conventionally with a .ld file name extension). That will describe the memory layout of your target and can be customised to suit.

The manner in which you have deduced stack and heap location is somewhat non-deterministic and over-complicated. It is far simpler and entirely accurate to simply look at the map file output generated by the linker (ld command line option -Map <mapfile>).

The heap is by definition for dynamic allocation, so implicitly not use to allocate static data; that is a misconception on your part. The linker will allocate static data locations at build time. The linker script is likely to then allocate a fixed size stack, and then allocate all that remains and not reserved for other purposes to the heap. A customised script may also allocate areas for other purposes such as DMA buffers or battery-backed domains for example.

Either way, placement of the stack is hardly likely to be a solution to your actual problem; that just moves things around; it won't increase available memory; any stack overflow will simply collide with something else.