Forums

TMS320F2812, RPC value in Stack overwrite before Division Operatioin

Started by sino...@nestgroup.net June 19, 2009
Hi,

Below is a portion of the code having bug.

**************************************************************************
//main()

main()
{
Initialize();

0x003F2463: //Starting address of SuperLoop()
SuperLoop();

}//end of main()

************
//Functions
************
Initialize()
{
InitSystem1();

0x003F24F1: //Starting address of InitSystem2()
InitSystem2();

InitSystem3();

}//end of Initialize()
SuperLoop()
{

while(1)
{
Process1();
Process2();
Process3();
}

}//end of SuperLoop()

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

Case1:
------

InitSystem1()
{
//No local varibales
- - -
- - -

s_RxMaxPower ULONG_MAX / (((859 * (Uint32)s_RxPowMonSlope) >> 11) + 1); -- (Eq1)

- - -
- - -
}

Case2:
(Numerator of Eq1 replaced with a local variable)
-------------

InitSystem1()
{
Uint32 Temp = ULONG_MAX;
- - -
- - -

s_RxMaxPower Temp / (((859 * (Uint32)s_RxPowMonSlope) >> 11) + 1); ------ (Eq2)

- - -
- - -
}

Given Conditions:
--
#define ULONG_MAX 4294967295 /* MAX VALUE FOR UNSIGNED LONG */
static int32 s_RxMaxPower;
static Uint16 s_RxPowMonSlope = 0x0800;
Uint32 Temp = ULONG_MAX;

IDE: CCS 3.1.0
Stack Size: 0x0400
Opt Level: Register ( -o0)
--

For the given values of variables, the Denominator of Eq1 will become 0x000035C.
Problem facing:

In Case1, after each reset we were never getting into SuperLoop() properly. We were thrown into Illeagal Interrupt ISR Vector causing a watchdog reset. But in Case2, everything was all right.

While debugging we observed:

-1-
After the execution of Eq1, the next-old RPC value in the stack was getting over-written with the denominator value of Eq1, i.e., 0x000035c in our case rather than 0x003F2463(Starting Address of SuperLoop()). This caused the program to behave ubnormally and whenever it met with an invalid/trap instruction, it fired an Illegal Interrupt. However it comeback to InitSystem2()(0x003F24F1) because this value retained in RPC.

-2-
This doesnot happen in Case2. Because two seperate locations gets initialized in the Stack to store the denominator of Eq2. This may be because(I think) of the declaration of the local variable 'Temp'. But whenever we declare a varibale or a 'const' or a 'static const' outside the SystemInit1() but in the same .c file the same problem persists.

The Debug-Disassembly of the code follows:

Case1 Disassembly:
---------- ---------- ---------- ---------- ----------
l1 : s_RxMaxPower = ULONG_MAX / (((859 * (Uint32)s_RxPowMonSlope) >> 11) + l2 : MOVW DP,#0x0242 1);
l3 : MOV @T,#0x035B
l4 : CLRC SXM
l5 : MPYXU ACC,T,@3
l6 : SFR ACC,11
l7 : ADDB ACC,#1
l8 : MOVL *-SP[2],ACC -> here the stack over-writes next RPC Value l9 : MOVB ACC,#0
l10: SUBB ACC,#1
l11: FFC XAR7,#UL$$DIV
l12: MOVL @8,ACC

At line l2:
SP = 0x0408
RPC = 0x3F24F1 //Address of InitSystem2()

Stack Values:
0x0406 2463 //Address of SuperLoop()
0x0407 003F
0x0408 24F1 //Address of InitSystem2()
0x0409 003F

After line l8:
SP = 0x0408
RPC = 0x3F24F1

Stack Values:
0x0406 03C5 //Address of SuperLoop() gets over-written by the dinominator 0x0407 0000 //value
0x0408 24F1 //Address of InitSystem2()
0x0409 003F
Case2 Disassembly:
---------- ---------- ---------- ---------- ----------
l1 : s_RxMaxPower = Temp / (((859 * (Uint32)s_RxPowMonSlope) >> 11) + 1);
l2 : MOVW DP,#0x0242
l3 : MOV @T,#0x035B
l4 : CLRC SXM
l5 : MPYXU ACC,T,@3
l6 : SFR ACC,11
l7 : ADDB ACC,#1
l8 : MOVL *-SP[2],ACC
l9 : MOVB @ACC,XAR1
l10: SUBB ACC,#1
l11: FFC XAR7,#UL$$DIV
l12: MOVL @8,ACC

At line l2:
SP = 0x040A
RPC = 0x3F24F1

stack Values:
0x0406 2463 //Address of SuperLoop() moved down and get preserved
0x0407 003F
0x0408 FFFF //A new pair of Stack locations gets initialized
0x0409 0000
0x040A 24F1 //Address of InitSystem2()
0x040B 003F

After line l8:
SP = 0x040A
RPC = 0x3F24F1

stack Values:
0x0406 2463 //Address of SuperLoop() retains
0x0407 003F
0x0408 035C //Denominator of Eq1
0x0409 0000
0x040A 24F1 //Address of InitSystem2()
0x040B 003F

---------- ---------- ---------- ---------- ----------

Q1. What is the problem with Case1? Is it a bug in coding?

Q2. If it is not a coding-bug, what is the root-cause?

Q3. Why new memory space in Stack is not initialized/assigned before entering SystemInit1() even known to the Compiler that a UL$$DIV function has to be executed in SystemInit1()?

Q4. How the problem could be well-defined and solved?

Any help is sincerly appreciated.

--------
-Regards
-Sinoj

_____________________________________