cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F10X - Stack gets corrupted by using big variables/arrays/structs

bernhard
Associate II
Posted on March 14, 2014 at 16:02

1.  Everything normal

0690X000006056YQAQ.png

2. Already strange behaviour. Stack size doesn't increase although test3 is one Byte larger 

0690X00000604n8QAA.png

3. Same here, stack doesnt grow

0690X00000604aOQAQ.png

4. Stack is corrupted (with test 3 being 232 Bytes large)

0690X000006056XQAQ.png

5. Stack is corrupted with large arrays

0690X000006057pQAA.png

I'm on a STM32F103RB - so I should have 20kBytes of RAM. Can anybody explain what's happening here and how I'm able to fix that?

How do I set the LDFLAGS without having a makefile?

#stm32f10x #stack-size #bug #stack #heap
12 REPLIES 12
Posted on March 14, 2014 at 16:11

Based on your addresses the stack is pitifully small for the allocations you are making.

Make the stack bigger, perhaps in your linker script or startup file, you don't mention a tool chain, and I'm not going to guess.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
bernhard
Associate II
Posted on March 14, 2014 at 16:22

Thanks for the reply! 

I'm on CooCox CoIDE v.1.7.6 with arm-none-eabi-gcc 4.8 2013q4.

The linker setup seems correct to me though:

0690X000006056IQAQ.png

0x5000 = 20480 - so this matches exactly the promised 20kB from the datasheet! What am I missing? :)

Posted on March 14, 2014 at 16:37

You are describing the size of the RAM, not the SIZE and PLACEMENT of the STACK within that space.

In Keil we define the stack within startup_stm32f1xx_xx.s, where you'd do it the the CooCox GUI I don't know. For GNU/GCC it is often defined in the linker script, points to the top of memory and moves down to the heap. You appear to be defining a stack in the 512 byte range, and it's placed very low in RAM.

If CooCox doesn't have documentation, or you can't find it in your GUI, try their forum.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on March 14, 2014 at 16:41

Look (search/grep) your project files for something like this..

#define STACK_SIZE 0x00000200 
__attribute__ ((section(''.co_stack'')))
unsigned long pulStack[STACK_SIZE];

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
bernhard
Associate II
Posted on March 14, 2014 at 17:05

Found it!

.\cmsis_boot\startup\startup_stm32f10x_md.c I entered

/*----------Stack Configuration-----------------------------------------------*/ 
#define STACK_SIZE 0x00001000 /*!< The Stack size suggest using even number */
__attribute__ ((section(''.co_stack'')))
unsigned long pulStack[STACK_SIZE];

What I dont get: why does

#define STACK_SIZE 0x00000100

increase

bss to 1024

? (0x400) Do I need the heap (when programming in (static) C, so no

new

or

malloc

) at all?
Posted on March 14, 2014 at 17:42

I don't know, what else is in your project?

Can you review the .MAP output by the linker to determine the memory use/foot-print?

If none of you code, or libraries, uses malloc()/new, then the heap can be small. You might be able to eliminate it, depends on what other code expects to support it, etc.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
bernhard
Associate II
Posted on March 14, 2014 at 18:39

What else is in my project? Nothing:

int main(void)
{
while(1)
{
}
}

I'm only fooling around with the stack size... Mapfile for stacksize0x00000200 is attached.

excerpt from map-file (0x200, bss=2048):

.heap 0x20000000 0x0
0x20000000 __end__ = .
0x20000000 _end = __end__
0x20000000 end = __end__
*(.heap*)
0x20000000 __HeapLimit = .
.co_stack 0x20000000 0x800
0x20000000 . = ALIGN (0x8)
*(.co_stack .co_stack.*)
.co_stack 0x20000000 0x800 ..\obj\startup_stm32f10x_md.o
0x20000000 pulStack
0x20005000 __StackTop = (ORIGIN (ram) + 0x5000)
0x20004800 __StackLimit = (__StackTop - SIZEOF (.co_stack))
0x20005000 PROVIDE (__stack, __StackTop)
0x00000001 ASSERT ((__StackLimit >= __HeapLimit), region ram overflowed with stack)

excerpt from map-file (0x100, bss=1024):

.heap 0x20000000 0x0
0x20000000 __end__ = .
0x20000000 _end = __end__
0x20000000 end = __end__
*(.heap*)
0x20000000 __HeapLimit = .
.co_stack 0x20000000 0x400
0x20000000 . = ALIGN (0x8)
*(.co_stack .co_stack.*)
.co_stack 0x20000000 0x400 ..\obj\startup_stm32f10x_md.o
0x20000000 pulStack
0x20005000 __StackTop = (ORIGIN (ram) + 0x5000)
0x20004c00 __StackLimit = (__StackTop - SIZEOF (.co_stack))
0x20005000 PROVIDE (__stack, __StackTop)
0x00000001 ASSERT ((__StackLimit >= __HeapLimit), region ram overflowed with stack)

.co_stack seems to be always 4 times larger than STACK_SIZE...

________________

Attachments :

StructTest.map : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0r3&d=%2Fa%2F0X0000000beV%2F_2Ecr7EN_hZWO8b9pmQeOxf9RzGAJlYetwKBGZB6wtc&asPdf=false
Posted on March 14, 2014 at 18:52

.co_stack seems to be always 4 times larger than STACK_SIZE...

No doubt because it's defined as an array of ''unsigned long''s which are 32-bit wide.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
philpem
Associate II
Posted on March 15, 2014 at 09:59

To be honest, you really shouldn't be allocating variables as large as that on the stack. The total size of those is going to be several kilobytes!

Prefixing them with the ''static'' keyword will move them to the heap, but bear in mind they'll keep their value through successive runs of the function. That is to say, if function ''foo'' has a static int which it sets to 123, when it's run again, that value will be pre-set to ''123'' again.

As a bonus, the linker will complain if you try to allocate more variables than you have available heap memory.