Hi there,
It was trivial to access the stack pointer from C for AVRs. The following code worked:
void __attribute__ ((__section__ (".init3"), __naked__)) move_sp(void) {
SP -= sizeof(wormhole_t);
message_ptr = (wormhole_t*)(SP + 1);
}
How can I access the stack pointer for the MK22FN512VLH12?
Thanks in advance!
- Laci
解決済! 解決策の投稿を見る。
Hi
Compiler independent C-only version for Cortex:
void *fnGetSP(void)
{
volatile unsigned long var = 0;
return (void *)((unsigned long)&var + 4);
}
If the variable is not set to 0 the code will generally be in-lined and result in the compiler directly generating a single instruction similar to
ADD R0, SP, #0x04
which is the SP value but I don't trust that because it may be slightly off when it optimises out the temporary variable (and the +4 may not be needed - making it compiler/optimisation dependent - although still accurate to one stack pointer location).
This code does generate a warning though because it uses the address of a temporary variable...
Regards
Mark
Hi Laci,
I'm using this:
void* KIN1_GetPC(void)
{
#ifdef __GNUC__
void *pc;
__asm__ __volatile__ ("mov %0, pc" : "=r"(pc));
return pc;
#else
#warning "only for GCC"
return NULL;
#endif
}
I hope this helps,
Erich
Thanks Erich,
Am I right that your function returns the PC, not the SP? Should I simply replace pc with sp in the assembly statement to adapt your function?
- Laci
Your original suggestion contained pc, not sp. Can you confirm that the following is correct?
void* getSP(void)
{
void *sp;
__asm__ __volatile__ ("mov %0, sp" : "=r"(sp));
return sp;
}
Alternatively, the following has also been suggested to me. I'm wondering whether it's also correct:
void* getSP(void)
{
void *sp;
__asm__ __volatile__ ("mrs %0, msp" : "=r"(sp));
return sp;
}
Thank you!
- Laci
Hi Laci,
yes, this is what I'm using for getting the PC too.
Erich
But which one? :smileyhappy: The 1st or the 2nd code code snippet that I pasted?
Thanks!
- Laci
Hi Laci,
simply try them out? :-).
I'm using the following:
void* KIN1_GetPC(void)
{
void *pc;
__asm__ __volatile__ ("mov %0, pc" : "=r"(pc));
return pc;
}
Erich
Thank you, Erich!
Usually, I can try suggested solutions, but in this case I wasn't even sure what should be the value of SP. I will make sure to use your version.
Thanks again!
- Laci
Hi
Compiler independent C-only version for Cortex:
void *fnGetSP(void)
{
volatile unsigned long var = 0;
return (void *)((unsigned long)&var + 4);
}
If the variable is not set to 0 the code will generally be in-lined and result in the compiler directly generating a single instruction similar to
ADD R0, SP, #0x04
which is the SP value but I don't trust that because it may be slightly off when it optimises out the temporary variable (and the +4 may not be needed - making it compiler/optimisation dependent - although still accurate to one stack pointer location).
This code does generate a warning though because it uses the address of a temporary variable...
Regards
Mark
Thanks Mark,
I love the simplicity of your solution, but I'm not in peace with the warning. Is there any way to disable this warning for this function?
Hi
Warning need to be disabled according to the compiler use - maybe a pragma can be added to quieten it.
Regards
Mark
Here is GCC example of how to selectively disable a warning per function.
The word 'diagnostic' may need to be replaced with 'error'.
Note that there are some warnings and errors that simply refuse to be turned off by pragma.
Using the GNU Compiler Collection (GCC): Diagnostic Pragmas
void power_off( void )
{
USART_Shutdown();
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Winline"
POWER_OFF();
#pragma GCC diagnostic pop
}