2015-09-10 01:15 PM
Hai, im developming an application using the ST standard peripherie library. Im trying to get the information, how big is my stack. I tried to use the __get_PSP(void) function to get the value of the stack program counter. This function is implemented into the file: core_cmFunc.h
When im executing my code, i will not get the right values. When im debuging, i can see the value in SP Register and thus the stack pointer. Could somebody help me how to get the information, how big is my stack during my application.2015-09-10 01:57 PM
Define a local/auto variable which is volatile, and get the address of it.
{ volatile int i; printf(''%p\n'',&i); } or return it as a (void *) pointer void * getsp(void) { volatile int i; return(&i); } The more classic way of measuring stack depth and utilization, is to clear or mark the entire stack space, and then periodically go the the base address for the stack section (not the SP at the top), and move upward until you no longer see you initialization pattern.2015-09-10 02:01 PM
Stack pointer is R13; how to get its value is compiler-dependent.
The value of information obtained in this way is dubious; the 0xDEADBEEF watermark method (google for it if you don't know it already) might be more adequate. JW2015-09-11 05:00 AM
If you are using interrupts you can periodically check stack pointers (process and system) to look for highwater marks (i.e. lowest address). Not all that reliable but easy and sometimes it gives you an early warning when a stack exceeds it's bounds.
FreeRTOS uses a variation on this. When task context changes there's an option to check task stack pointer to ensure it's in range. Saved me some debugging on several occasions. You still need to do your own checks for system SP, especially if nesting interrupts. Jack Peacock2015-09-11 10:34 AM
Interesting.
How do you get R13 value? Or how do you easily mix assembly and C? For example in Keil 5?2015-09-11 05:07 PM
Surely something like this is significantly more portable, although implementation dependent.
int main(void)
{
volatile void *x = &x;
...
volatile should prevent it optimizing to a register, as should getting it's address. ie forces it to be memory, as registers don't have and address.
If you want to learn how to inline assembler with
__asm I'm sure there's documentation, but ARM/Keil does make it difficult to access R.R15