4
votes

I am trying to monitor the stack pointer in C on an embedded ARM MCU. As the project grows, I'd like to know how much space is left and map more if necessary.

I already know the start and top address of the stack from the map file generated when compiled.

I would like to get the address the sp is pointing to so I can do some basic math and monitor the stack on a percentage used basis, but I am new to ARM and don't understand why my assembly is not working.

This is what I am doing:

int stackptr;
asm
{                
    LDR r0, =stackptr  // put address of C variable stackptr in r0
    MOV r1, sp         // move value of sp to r1
    STR r1, [r0]       // put value of r1 in address contained in r0 (stackptr)
}

// math using stackptr...

If I look at the address stored in stackptr, its right at the start of the stack and its not changing (I am calling this every 100ms). I expected this to be bouncing around somewhere in the middle of my stack.

Also, if I try to get the address of the stack base and limit (using the same method but with sb and sl), I just get 0's. I am not as concerned about this since from my research it seems they are not always used.

Thanks for the help

1
Is this code running via an interrupt? If so, it may have its own stack (and stack pointer). - EOF
I can't speak to your specific platform, but there is more than one way to accomplish this task. You may want to take a look at this great write up by IAR. - embedded_guy
Is this a Cortex-M (with 'only' 2 SP registers), or a Cortex-A/older architecture (with up to 8 banked copies)? Also, is there any kind of OS or other context-switching involved? - Notlikethat
@EOF is correct; Running the proposed code in an ISR would only give the SP of the ISR, which may have its own stack. If this is the case, you must find where the context of the interrupted task was pushed when it was switched for the interrupt context, and read the SP from that saved context. - Iwillnotexist Idonotexist
if this function is called only in one execution path then it will always result in the same stack value, if this function is called in many different places (various layers of nested functions) then it should be showing a difference and the volatile keyword is likely the problem. - old_timer

1 Answers

3
votes

Try making stackptr volatile, since compiler can think it is not getting updated and use stale copy in a register or completely optimize away access to it.

Another approach to your problem might be to ask compiler to calculate possible stack usage and create a report. For example with GCC you can use -fstack-usage and -Wstack-usage flags. -fstack-usage creates a .su file with the same name, reporting stack usage of each function. -Wstack-usage=X warns if a function requires more stack than what's passed in. Of course this is static analysis so compiler can't handle all the cases (but generate warnings if so). I would also expect any commercial compiler to have such functionality if you are not using GCC.