Hi Joe,
we can use tree prefixes __SEG_SIZE_ to define the size of the stack segment. in order to use it for stack segment. the stack section SSTACK must be defined in a fixed address section.
Linker-Defined Objects
The linker supports defining special objects to get the address and size of sections at link time. Objects to be defined by the linker must have as a special prefix one of the strings below and must not be defined by the application at all.
| NOTE | Because the linker defines C variables automatically when their size is known, the usual variables declaration fails for this feature. For an extern int __SEG_START_SSTACK;, the linker allocates the size of an int, and does not define the object as address of the stack. Use the following syntax so that the compiler/linker has no size for the object: extern int __SEG_START_SSTACK[]; |
Usual applications of this feature are the initialization of the stack pointer and retrieving the last address of an application to compute a code checksum at runtime.
The object name is built by using a special prefix and then the name of the symbol.
The following tree prefixes are supported:
__SEG_START_ : start address of the segment
__SEG_END_ : end address of the segment
__SEG_SIZE_ : size of the segment
| NOTE | The __SEG_END_ end address is the address of the first byte behind the named segment. |
The linker assumes the remaining text after the prefix to be the segment name. If the linker does not find such a segment, it issues a warning and takes 0 as the address of this object.
| NOTE | There is no warning issued for predefined segments like SSTACK or OVERLAP, even if these segments are empty and not explicitly allocated. The warning is only issued for user-defined segments. |
Because identifiers in C must not contain a period in their name, the Freescale format aliases can be used for the special ELF names. Few of them are SSTACK instead of .stack, DEFAULT_RAM instead of .data, DEFAULT_ROM instead of .text, COPY instead of .copy, ROM_VAR instead of .rodata, STRINGS instead of .rodata1, STARTUP instead of.startData, PRESTART instead of .init , _OVERLAP instead of .overlap, _OVERLAP2 instead of .overlap2. Also, __DOT__ can be prefixed for objects whose names start with period character.
For example, __SEG_START___DOT__common can be used to get start address of .common section.
Listing 3.46 C Source Code
#define __SEG_START_REF(a) __SEG_START_ ## a
#define __SEG_END_REF(a) __SEG_END_ ## a
#define __SEG_SIZE_REF(a) __SEG_SIZE_ ## a
#define __SEG_START_DEF(a) extern char __SEG_START_REF(a) []
#define __SEG_END_DEF(a) extern char __SEG_END_REF( a) []
#define __SEG_SIZE_DEF(a) extern char __SEG_SIZE_REF( a) []
/* To use this feature, first define the symbols to be used: */
__SEG_START_DEF(SSTACK); // start of stack
__SEG_END_DEF(SSTACK); // end of stack
__SEG_SIZE_DEF(SSTACK); // size of stack
/* Then use the new symbols with the _REF macros: */
int error;
void main(void) {
char* stackBottom= (char*)__SEG_START_REF(SSTACK);
char* stackTop = (char*)__SEG_END_REF(SSTACK);
int stackSize= (int)__SEG_SIZE_REF(SSTACK);
error=0;
if (stackBottom+stackSize != stackTop) { // top is bottom + size
error=1;
}
for (;;); /* wait here */
}
Listing 3.47 .prm File
LINK example.abs
NAMES example.o END
SECTIONS
MY_RAM = READ_WRITE 0x0800 TO 0x0FFF;
MY_ROM = READ_ONLY 0x8000 TO 0xEFFF;
MY_STACK = NO_INIT 0x400 TO 0x4ff;
END
PLACEMENT
DEFAULT_ROM INTO MY_ROM;
DEFAULT_RAM INTO MY_RAM;
SSTACK INTO MY_STACK;
END
INIT main
Listing 3.48 Linker-Defined Symbols
__SEG_START_SSTACK 0x400
__SEG_END_SSTACK 0x500
__SEG_SIZE_SSTACK 0x100
| NOTE | To use the same source code with other linkers or old linkers, define the symbols in a separate module for them. |
| NOTE | In C, you must use the address as value, and not any value stored in the variable. So in the previous example, (int)__SEG_SIZE_REF(SSTACK) was used to get the size of the stack segment and not a C expression like __SEG_SIZE_REF(SSTACK)[0]. |
Have a great day,
Zhang Jun
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------