Stack Overflow and UnderFlow monitoring

Showing results for 
Search instead for 
Did you mean: 

Stack Overflow and UnderFlow monitoring

Contributor V

Hello All,

I am working with S12 ZVML MCU. I want to implement the stack counter undeflow/overflow check.

The S12Z safety manual recommends to implement a periodic stack over/underflow check.


My query is whether a simple check of comparing the stack counter against a user defined threshold counter value will suffice or any further additions are required.

Labels (1)
Tags (1)
4 Replies

NXP TechSupport
NXP TechSupport


There are two things to talk about.


1) Usually the stack should be correctly precalculated to be sure how the application is working and how much space it requires for the stack. Then you can use two approaches.

  1. a) fill the part of stack by means of FILL command in the prm file which you expect will be newer used by the application. (The least addresses space of the stack). Then you can check two things in a regular periods, the SP value for current status and the “FILLed” part of stack to check whether we have not overflow calculated stack size between two stack address checking events.

This is the part I am able to say from my position. The second part provides next possibility to get more info from special team.


2) You can post any safety related questions to the special community space. The community is monitored by experts in safety area.

You need to have an NDA to get there first. If you do not have it you have to ask for it by inserting a new case where you ask for it.

Please read this document.


Best regards,


Contributor V

Hi lama‌,

Thank you for your reply.

I understood.

Is there any document relevant to the suggestion 1a.

0 Kudos

NXP TechSupport
NXP TechSupport


an example of prm file. See modifications in bold.

/* This is a linker parameter file for the MC9S12ZVLA128 */
NAMES END /* CodeWarrior will pass all the needed files to the linker by command line. But here you may add your own files too. */

SEGMENTS  /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */

/* Register space  */
/*    IO_SEG        = PAGED         0x000000 TO   0x000FFF; intentionally not defined */

/* RAM */
      //RAM           = READ_WRITE  0x001000 TO 0x002FFF; intentionally removed
      RAM           = READ_WRITE  0x001000 TO 0x002DFF;
      MY_STACK_RAM  = NO_INIT     0x002F00 TO 0x002FFF;    // expected stack size
      MY_CHECK_STACK_RAM  = READ_WRITE  0x002E00 TO 0x002EFF FILL 0xFF;  // intentionally used for stack underflow check (select proper size)

/* EEPROM */
      EEPROM        = READ_ONLY   0x100000 TO 0x1007FF;

/* non-paged FLASHs */
      ROM           = READ_ONLY   0xFE0000 TO 0xFFFDFF;
 /*   VECTORS       = READ_ONLY     0xFFFE00 TO   0xFFFFFF; intentionally not defined: used for VECTOR commands below */
   //OSVECTORS      = READ_ONLY     0xFFFE10 TO   0xFFFFFF;   /* OSEK interrupt vectors (use your vector.o) */

PLACEMENT /* here all predefined and user segments are placed into the SEGMENTS defined above. */
      _PRESTART,              /* Used in HIWARE format: jump to _Startup at the code start */
      STARTUP,                /* startup data structures */
      ROM_VAR,                /* constant variables */
      STRINGS,                /* string literals */
      VIRTUAL_TABLE_SEGMENT,  /* C++ virtual table segment */
    //.ostext,                /* OSEK */
      NON_BANKED,             /* runtime routines which must not be banked */
      COPY              INTO  ROM;

    //.stackstart,            /* eventually used for OSEK kernel awareness: Main-Stack Start */
 //  intentionally removed     SSTACK,  /* allocate stack first to avoid overwriting variables on overflow */  // !!!!!!!!!!!!
    //.stackend,              /* eventually used for OSEK kernel awareness: Main-Stack End */
    DEFAULT_RAM         INTO  RAM;

    SSTACK              INTO  MY_STACK_RAM;

  //.vectors            INTO  OSVECTORS; /* OSEK */

ENTRIES /* keep the following unreferenced variables */
    /* OSEK: always allocate the vector table and all dependent objects */
  //_vectab OsBuildNumber _OsOrtiStackStart _OsOrtiStart

STACKTOP  0x2fff     // redefined for required stack size defined in the SEGMENTS section

VECTOR 0 _Startup /* reset vector: this is the default entry point for a C/C++ application. */
//VECTOR 0 Entry  /* reset vector: this is the default entry point for an Assembly application. */
//INIT Entry      /* for assembly applications: that this is as well the initialization entry point */

Result of the modifications is.....RAM 0x2e00~0x2eff is not used by application for variables and it is filled by patter 0xff at the start of the code automatically. RAM 0x2f00~0x2fff is used for STACK.


Best regards,


0 Kudos

NXP Employee
NXP Employee

Hi Pratibha,

The filing the stack by known pattern and check how much from it was rewritten by application code is common approach for debug testing whether your stack size is adequal. Typically, we reset MCU by debugger into Startup() code (prior stack initialization), fill stack by debugger and let code run. After some time, we stop CPU and watch size of used stack.

However, if I remmember correctly, the stack is only part of RAM where linker will ignore the FILL command. So, Lama's advice may help only partialy.

Anyway, the stack is used from top and by default located at begining of RAM. So, you may simply write some pattern directly at address 0x1000 (RAM start) during MCU init and periodically check it.

For example: 

volatile unsigned int stack_overflow @0x1000  =0x5AA5;

Note: Be aware! The default CW project has disabled memory overlapping warnings.

See  for more details regarding variable allocation in CW. 

I hope it helps you.

Best regards


0 Kudos