Hi All,
First we were doing the stack usage calculation by manual as follows: (Controller is S9S12G128F0MLF LQFO48)
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.
Solved! Go to Solution.
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;
}
}
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;
}
}