HCS08 PRM Symbols

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

HCS08 PRM Symbols

Jump to solution
1,294 Views
ignisuti_
Contributor IV

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?

Labels (1)
Tags (1)
0 Kudos
1 Solution
734 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

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!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

0 Kudos
1 Reply
735 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

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!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos