I’m trying to create some code that will check the stack utilization.
But, to do this I need a variable or symbol that I can reference in my code to tell me the stack size which is defined in the PRM file. I had a trick that worked in the LCF file with the Kinetis family, but that trick isn’t working here in the PRM file of the HCS08 chip.
Does anyone know how to accomplish this?
Solved! Go to Solution.
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.
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.
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 |
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 |
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. |
Have a great day,
Zhang Jun
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
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.
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.
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 |
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 |
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. |
Have a great day,
Zhang Jun
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------