Tuesday, February 7, 2012

Stack size of bootloader versus application

I got myself in a bind when I changed the stack size of my application, but didn't change the size of the stack in the bootloader.

I learned something new today: the CPU sets the stack pointer to the first word of the vector table on reset. If you have a bootloader that does something like jump to the reset vector (__vector_table + 4 bytes), it will NOT reload the stack pointer. If your stack pointer is not changed, you are likely to start writing all over the stack with your static variables. yuck.

In my case, the bootloader had a stack of 0xC00. My main app was running out of memory, so I changed the stack to 0xB80 (which was more than enough). However, I noticed that my app was still using a stack of size 0xC00, when it had only allocated 0xB80 to it. uhoh.


To fix this, I added these 2 lines to the ResetHandler in startup_stm32f10x_md_vl.s (or the equivalent for other STM32s)


Reset_Handler
;; MTL
;;force reload of the stack pointer!
;; it is stored on the start of the vector table
LDR R0,=__vector_table
LDR SP,[R0]
;;
LDR R0, =SystemInit
BLX R0
LDR R0, =__iar_program_start
BX R0


Btw, IAR 6.3 has a feature to analyze the stack size. It kinda works, but it is a pain in the butt if you have C++ virtual functions or any function pointers.

No comments: