Hello,
I'm using a Cortex M-4 processor (STM32F4) and I recently encountered strange behavior of my code after minor modifications that were not directly related to the problems I was seeing.
After a bit of digging, I noticed that some of my global variables were modified without being accessed through the code. Looking at the memory mapping, it turned out these variables were located just before the stack. Increasing the stack size in the startup file solved the issue, so obviously this was a stack overflow.
But the thing is, I want to be sure that when a stack overflow occurs, a fault happens, not some random behavior. I thought I was safe because my stack was at the end of the RAM space. But as it turns out, it actually grows backwards.
So the question is: How to configure the stack direction ? And are there other ways to prevent this kind of problem?
Thank you
"I thought I was safe because my stack was at the end of the RAM space. But as it turns out, it actually grows backwards."
Yes - that is normal and, as already noted, I don't think there's any way to change the direction it grows.
But something doesn't make sense here:
1. The stack is placed at the "end" (top) of RAM, and grows backwards.
2. Your program variables start at the "bottom" of RAM, and grow upwards.
So, if your stack was colliding with your program variables, you had filled-up all the available RAM anyhow - so increasing the Stack size would not have helped!
A better idea would be to post a summary in the ST forum, with a link to this tread - then you don't get two unrelated threads on the same topic.
And, of course, post a link here to the ST thread.
"I still don't understand how it could corrupt the last .bss segment"
It could be that changing the stack size was just a red herring ...
Are you using Heap (dynamic allocation) ?
"But something doesn't make sense here: 1. The stack is placed at the "end" (top) of RAM, and grows backwards. 2. Your program variables start at the "bottom" of RAM, and grow upwards. So, if your stack was colliding with your program variables, you had filled-up all the available RAM anyhow - so increasing the Stack size would not have helped!"
I was a bit confused about the meaning of "up" and "down", though I gave the exact addresses in my second message. Now it is clearer to me.
So here is the initial (standard) configuration : - The program variables (.data, .bss) are stored at the bottom of RAM (0x20000000). The size they occupy is determined at compilation. - The stack memory section is located just above the variables. Its size is configurable (in the startup file), by default it is 1 kbyte. - The remaining top part of the RAM is unused
This means, at runtime, the stack starts at variables_size + stack_size, grows downwards, and when full quietly overwrites the last variables.
To ensure maximum RAM usage, one could set the stack memory section start to RAM_start + RAM_size - stack_size, which is the situation you describe (variables at the bottom, stack at the top, unused space between). This way the stack size doesn't actually matter and you only encouter a problem when all RAM is effectively used. But if it does occur, it will still be quietly, without causing an hard fault. So I guess it's not recommended.
What I want to do (but first I didn't know how to phrase it) is to put the stack at the bottom, and the variables above. This way way the stack starts at 0x20000000 + stack_size, grows downwards, and when it overflows, it tries to access an address in 0x1FFFF...., triggering a hard fault.
Alternatively, putting guard words just below the stack and checking them periodically would do the trick.
From what I gathered, it seems like I could either create a scatter file, or modify the startup file.