2011-08-03 06:06 AM
I'd like to add stack usage monitoring to my application. I can't afford the overhead of stack checking on every function call, so I was considering adding a routine that runs periodically to monitor the stack high-water mark. I'm not using an RTOS.
I know my stack size, but how do I find the beginning of the stack? will it always start at the same place? I'm using the Keil tools, if that makes a difference. Thanks!2011-08-03 08:41 AM
The stack is set by the first vector on the STM32, and descends from there. The C startup code may also place it too, before calling main().
A 4K stack, on a 20K part, can nominally get placed at 0x20005000 and descend to 0x20004000. Fill that space with a distinctive pattern, and enumerate upward to measure the depth used. In Keil the bottom of the stack is defined by Stack_Mem, and the top/start as __initial_sp My stack checker loads a pointer to Stack_Mem, and the climbs 32-bits at a time until if find the bottom of the used stack, and then computes the amount used based on the known size.2011-08-03 12:04 PM
Thank you; conceptually I understand what to do, but I'm getting stuck on the implementation, perhaps because I'm new to the Keil/ARM tools. Now that you've steered me towards the appropriate linker symbols, I can't seem to reference them (__initial_sp and Stack_Mem) from my C code; the linker complains the symbols are undefined. I tried declaring them as extern but it didn't help.
2011-08-03 04:05 PM
In stm32F10x.s (startup.s, whatever)
EXPORT Stack_Size EXPORT Stack_Mem Stack_Size EQU 0x00001000 AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size __initial_sp in C application extern void * Stack_Mem; unsigned long *p = (unsigned long *)&Stack_Mem;2011-08-04 08:18 AM
I was missing the EXPORT statements; it works now.
Thanks!