This will return the current stack pointer value:
static __inline__ void *sp_get(void)
{
void *sp;
__asm__ __volatile__ ("mrs %0, msp" : "=r"(sp));
return( sp );
}
However you probably actually want a constant from the linker script. Probably not what you really want either.
I move the .noinit section to the start of RAM so it is in a known place so that I can communicate between bootloader and the app at startup.
Simpy moving .noinit to before everything else gets rid of all of the 'growth' and messing with stack discussed at AVRFreaks.
The GPIOx section also simulates some of the XMega address space so I can share code between the Kenitis M0+ and an XMega.
Make sure that the NOINIT space is more than you need but not by much. Allocating to much wastes RAM and using more than allocated makes hair pulling bugs. 0x200/512 bytes is what I use in my project:
MEMORY
{
VECTORS (rx) : ORIGIN = 0x0, LENGTH = 0x000000C0
BOOTCFG (r) : ORIGIN = 0x000003C0, LENGTH = 64
FLASHCFG (r) : ORIGIN = 0x00000400, LENGTH = 16
FLASH (rx) : ORIGIN = 0x00000410, LENGTH = (256K - 1K - 0x410) /* Flash size - EEPROM Sim size - vectors and Flash Config bytes */
EEPROMSIM (rx) : ORIGIN = (256K - 1K), LENGTH = 1K
BOOTLOADER (rx) : ORIGIN = 0x1C000000, LENGTH = 16K
NOINIT (rwx) : ORIGIN = 0x1FFFE000, LENGTH = 0x200 /* Space for variables that do not get zeroed at C startup */
GPIOx (rwx) : ORIGIN = 0x1FFFE200, LENGTH = 0x10 /* Space to simulate AVR GPIOx */
RAM (rwx) : ORIGIN = 0x1FFFE210, LENGTH = (32K - 0x200 - 0x10) /* Internal SRAM. flash_kinetis_cmd executes out of RAM */
}