Code for STACK usage calculation:

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

Code for STACK usage calculation:

Jump to solution
943 Views
hareeshakoratik
Contributor II

Hi All,

 

                First we were doing the stack usage calculation by manual as follows: (Controller is S9S12G128F0MLF LQFO48)

 

  • Using a typical bench setup, flash the software to be examined.
  • Attach a JTAG debugger to the JTAG connector on the PCB
  • Use CodeWarrior to attach to the PCB and download debugging information.
  • Set a breakpoint at the beginning of the function main ().
  • Start program execution. The breakpoint should be reached in a second or two.
  • Using the registers window, verify that the SP is set to 20FD. (The startup code calls the main function so that is the reason that it is not 20FF.)
  • In the memory window, right click and select fill. Set the fill range to 2000 thru 20FC and the fill value to some recognizable value that is not a valid program address, such as A1. Press OK and verify that the stack area has been filled with the chosen value.
  • Resume program execution and try to invoke as much of the possible software execution paths as you can. At least run the software for 5 minutes.
  • At the end of the software exercise, stop the debugger and examine the memory window for the lowest address in the range 2000 thru 20FC that is not a fill value. Subtract that address from 0x2100, convert to decimal and divide the result by 256. The resulting number is the fraction of the stack space used.

 

But now I want to do this stuff through code. So I have written following functions to do the same:

All functions looks fine individually, but if I call one after other, STACK is overflowing at the end of *Read_From_Stack() and Stack_Usage_Calc. even I am setting SP to top of the STACK.

 

Please anyone can identify what is going wrong with my code.

 

If anyone know / having the example/working code to calculate STACK usage, please share with me.

 

 

/*

  Function to get size of stack

*/

extern uint16_t __SEG_SIZE_SSTACK[];

 

uint16_t Stack_Size_Allocated()

{

 

  {

      return (uint16_t)__SEG_SIZE_SSTACK;

  }

   

}

 

/*

    Function to write known data into stack location

*/

void Write_To_Stack()

{

  static uint16_t SP_Value = 0x20FD;

                asm INS

                asm INS

                asm INS

                //asm LDS #$20FD

  while (SP_Value > 0x2000)

                                {

      asm LDAA #0xA1

                                                asm PSHA //Push index register data into stack;

      asm STS SP_Value

    }

    asm LDS #$20FD

}

 

/*

    Function to write known data into stack location

*/

 

static uint8_t *Read_From_Stack()

{

  static uint8_t Temp_Stack = 0;

  static uint16_t SP_Value_Top = 0xFFFF;

  static uint8_t i = 0;

  static uint8_t Stack_Data[255];

  static uint8_t x;

  for (x = 0; x < 255; ++x)

    {

      Stack_Data[x] = 0xFF;

    }

                  asm INS

                  asm INS

                  asm INS

                  asm INS

                  asm INS

                                while (SP_Value_Top > 0x2000)

                                {

                                                asm PULA // Pull data frop top of the stack into X register

                                                asm DES

                                                asm STAA Temp_Stack //Temp_Stack //Data read from Stack Last Address

                                                Stack_Data[i] = Temp_Stack;

                                                i++;

      asm DES

      asm STS SP_Value_Top

    } 

    return Stack_Data;

}

 

/*

    Function to calculate stack usage:

*/

 

void Stack_Usage_Calc()

{

  //uint8_t *Stack_Used =0; /* a pointer to an int */

                static uint8_t Stack_Used_Count = 0;

                static uint8_t Stack_Not_Used_Count = 0;

                static uint8_t i = 0;

                static uint8_t Stack_Size = 255;

                static uint16_t Stack_Usage = 0;

                static uint8_t *Stack_Used; /* a pointer to an int */

                               

  //Stack_Size = Stack_Size_Allocated();

                Stack_Used = Read_From_Stack();

 

 

                for (i=0; i<Stack_Size ; ++i)

                                {

                                                if (*(Stack_Used + i) == 0xA1)

                                                                {

                                                                                Stack_Used_Count++;

                                                                }

                                                else

                                                                {

Stack_Not_Used_Count++; //Stack is not used, No Count, do nothing

                                                                }

                                 }

  Stack_Usage = ((Stack_Used_Count/Stack_Size)*100); //It gives Stack usage in % by our BMS 

}

 

Thanks in advance

 

Regards,

Hareesha.

Labels (1)
0 Kudos
Reply
1 Solution
536 Views
hareeshakoratik
Contributor II

Hi All,

Here is the correct working code.

Mistake in previous code is, I was incrementing SP to 0x20FF from 0x20F9. Actually first 3 bytes were used by start up code and another 3 bytes were used by main function. But I was over writing that stack data with my known value so that code was not returning to calling functions. Solution is, we need to read and store the SP into a variable at the entry of function and same SP should be re -loaded at the end of the function. And main is, we are not supposed to touch the content of stack memory which is used by start-up code and main function.

Following is correct working code for STACK usage calculation. Let me know if anyone need any information regarding the same. Correct me if I am wrong anywhere.

/*

**********************************************************************

* DEFINES AND CONSTANTS

**********************************************************************

*/

uint8_t Stack_Usage_Min = 100; /* Minimum STACK usage in precentage */

uint8_t Stack_Usage_Max = 0;  /* Maximum STACK usage in precentage */

extern uint16_t __SEG_SIZE_SSTACK[];

  /*

  Function to get the size of stack

*/

uint16_t Get_Stack_Size_Allocated()

{

  {

      return (uint16_t)__SEG_SIZE_SSTACK;

  }

}

/*

  Function to get lower start address of the stack

*/

uint16_t Get_Stack_Start_Address()

{

  {

      return (uint16_t)__SEG_START_SSTACK;

  }

/*

**********************************************************************

* GLOBAL FUNCTIONS

**********************************************************************

*/

/*

    Function to write known data into stack location

*/

void Write_To_Stack()

{

  /* Declare static variables.*/

  /* Follwoing variables are made as static, because test case variables are not supposed to save

     on STACK along with main draiver variables*/

  static uint16_t SP_Value;

  static uint16_t SP_Value_Initial;

  DisableInterrupts

  asm STS SP_Value_Initial /* Store initial SP into a variable, restore at the end of function */

     asm STS SP_Value /* Store SP value into a variable */

  while (SP_Value > 0x2000)

    {

    asm LDAA #0xA1  /* Load 0xA1 into A register*/

      asm PSHA /* Push index register data into stack.*/

    asm STS SP_Value  /* Store SP into a variable */

  }

    asm LDS SP_Value_Initial  /* Load SP from a variable. It will give control back to main function*/

    EnableInterrupts

}

/*

    Function to evaluate stack usage.

*/

void Eval_Stack_Usage()

{

  /* Declare static variables.*/

  /* Follwoing variables are made as static, because test case variables are not supposed to save

     on STACK along with main draiver variables*/

  static uint16_t SP_Value_Lower;

  static uint16_t SP_Value_Initial;

    static uint8_t Stack_Not_Used_Count;

    static uint16_t Stack_Size;

    static uint8_t SP_Data;

    static uint8_t Stack_Usage;

       

  /*Initilize static variables.*/

  SP_Value_Lower = Get_Stack_Start_Address();

    Stack_Not_Used_Count = 0;

    Stack_Size = Get_Stack_Size_Allocated();

    SP_Data = 0x00;

    Stack_Usage = 0;

   

    DisableInterrupts

 

  asm STS SP_Value_Initial   /* Store initial SP into a variable, restore at the end of function.*/

    asm LDS SP_Value_Lower /* Load SP with lower address of STACK.*/

    asm PULA /* Pull data frop SP location into A register.*/

    asm STAA SP_Data  /* Store data read from register A into a variable.*/

   

  while (SP_Data == 0xA1) /* If content of stack memory is equal to A1.*/

  {    

    ++Stack_Not_Used_Count;    /*increment count by 1;*/

    asm PULA /* Pull data frop SP location into A register, whih increases SP by 1*/

      asm STAA SP_Data /*Store data read from register A into a variable.*/

  }

  asm LDS SP_Value_Initial   /* Load SP from a variable. It will give control back to calling function*/

  EnableInterrupts

 

  Stack_Usage = (((Stack_Size - Stack_Not_Used_Count)*100)/Stack_Size); /* It gives Stack usage in % by our BMS.*/

     

  if (Stack_Usage_Min > Stack_Usage)

  {

     Stack_Usage_Min = Stack_Usage;

  }

 

  if (Stack_Usage_Max < Stack_Usage)

  {

     Stack_Usage_Max = Stack_Usage;

  }

}

View solution in original post

0 Kudos
Reply
1 Reply
537 Views
hareeshakoratik
Contributor II

Hi All,

Here is the correct working code.

Mistake in previous code is, I was incrementing SP to 0x20FF from 0x20F9. Actually first 3 bytes were used by start up code and another 3 bytes were used by main function. But I was over writing that stack data with my known value so that code was not returning to calling functions. Solution is, we need to read and store the SP into a variable at the entry of function and same SP should be re -loaded at the end of the function. And main is, we are not supposed to touch the content of stack memory which is used by start-up code and main function.

Following is correct working code for STACK usage calculation. Let me know if anyone need any information regarding the same. Correct me if I am wrong anywhere.

/*

**********************************************************************

* DEFINES AND CONSTANTS

**********************************************************************

*/

uint8_t Stack_Usage_Min = 100; /* Minimum STACK usage in precentage */

uint8_t Stack_Usage_Max = 0;  /* Maximum STACK usage in precentage */

extern uint16_t __SEG_SIZE_SSTACK[];

  /*

  Function to get the size of stack

*/

uint16_t Get_Stack_Size_Allocated()

{

  {

      return (uint16_t)__SEG_SIZE_SSTACK;

  }

}

/*

  Function to get lower start address of the stack

*/

uint16_t Get_Stack_Start_Address()

{

  {

      return (uint16_t)__SEG_START_SSTACK;

  }

/*

**********************************************************************

* GLOBAL FUNCTIONS

**********************************************************************

*/

/*

    Function to write known data into stack location

*/

void Write_To_Stack()

{

  /* Declare static variables.*/

  /* Follwoing variables are made as static, because test case variables are not supposed to save

     on STACK along with main draiver variables*/

  static uint16_t SP_Value;

  static uint16_t SP_Value_Initial;

  DisableInterrupts

  asm STS SP_Value_Initial /* Store initial SP into a variable, restore at the end of function */

     asm STS SP_Value /* Store SP value into a variable */

  while (SP_Value > 0x2000)

    {

    asm LDAA #0xA1  /* Load 0xA1 into A register*/

      asm PSHA /* Push index register data into stack.*/

    asm STS SP_Value  /* Store SP into a variable */

  }

    asm LDS SP_Value_Initial  /* Load SP from a variable. It will give control back to main function*/

    EnableInterrupts

}

/*

    Function to evaluate stack usage.

*/

void Eval_Stack_Usage()

{

  /* Declare static variables.*/

  /* Follwoing variables are made as static, because test case variables are not supposed to save

     on STACK along with main draiver variables*/

  static uint16_t SP_Value_Lower;

  static uint16_t SP_Value_Initial;

    static uint8_t Stack_Not_Used_Count;

    static uint16_t Stack_Size;

    static uint8_t SP_Data;

    static uint8_t Stack_Usage;

       

  /*Initilize static variables.*/

  SP_Value_Lower = Get_Stack_Start_Address();

    Stack_Not_Used_Count = 0;

    Stack_Size = Get_Stack_Size_Allocated();

    SP_Data = 0x00;

    Stack_Usage = 0;

   

    DisableInterrupts

 

  asm STS SP_Value_Initial   /* Store initial SP into a variable, restore at the end of function.*/

    asm LDS SP_Value_Lower /* Load SP with lower address of STACK.*/

    asm PULA /* Pull data frop SP location into A register.*/

    asm STAA SP_Data  /* Store data read from register A into a variable.*/

   

  while (SP_Data == 0xA1) /* If content of stack memory is equal to A1.*/

  {    

    ++Stack_Not_Used_Count;    /*increment count by 1;*/

    asm PULA /* Pull data frop SP location into A register, whih increases SP by 1*/

      asm STAA SP_Data /*Store data read from register A into a variable.*/

  }

  asm LDS SP_Value_Initial   /* Load SP from a variable. It will give control back to calling function*/

  EnableInterrupts

 

  Stack_Usage = (((Stack_Size - Stack_Not_Used_Count)*100)/Stack_Size); /* It gives Stack usage in % by our BMS.*/

     

  if (Stack_Usage_Min > Stack_Usage)

  {

     Stack_Usage_Min = Stack_Usage;

  }

 

  if (Stack_Usage_Max < Stack_Usage)

  {

     Stack_Usage_Max = Stack_Usage;

  }

}

0 Kudos
Reply