Is there anything wrong with this code?
/*. .. */extern unsigned char Fo_A[]; //Defined in ASM file/* ... */const signed short S[3] = {-10, 0, 10}; //Singleton table/* ... */signed short dT_ThrotA; //Output variables/* ... */void DeFuzz(void){ signed int tempNum; //Temporary Numerator var signed int tempDen; unsigned int i; //iteration counter //***Motor A*** tempNum = 0; tempDen = 0; for(i = 3; i>0;i--){ tempNum = tempNum + (Fo_A[i] * S[i]); tempDen = tempDen + Fo_A[i]; } dT_ThrotA = (tempNum / tempDen); /* ... */}
It's run through about 50 times per second thanks to a timer based ISR.
When I run it through the debugger, every now and then the tempNum and tempDen get a random number in them instead of being initialized to 0... I can't figure out why it's doing this.
已解决! 转到解答。
Hello AirDragon,
This issue might be related to the known compiler defect #MTWX35998 (Incorrect code generated by compiler when compiler creates sub-functions for common code and the sub function access an array defined as local variable).
Could you perhaps try to disable -onf as suggested by Daniel or try to declate the variables (tempNum, tempDen) as static.
This issue was fixed in CodeWarrior for HCS12(x) v5.0.
I'd recommend you to download and install the latest CW available here:
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=CW-HCS12X&fpsp=1&tab=Design_Tools_Tab
Stanish
You are most likely debugging optimized code, which makes it look like the variables aren't initiazlied. Look at the disassembly and see what the code actually does.
Historically, CW has always been very dumb when it comes to optimizations coming with them enabled by default. If you have a somewhat new CW version there should be a compiler option -O0 Disable Optimizations to disable them during debugging. If that doesn't help, you can always make the variables volatile.
I'm going to try that out as soon as I can, but I did look at the compiler options and didn't see a -O0 option.
However, I did see the -One option, would that work?
I am using the 5.9.0 SE version, build 5294
I can't seem to make heads or tails out of this dissassembly. I also don't see anywhere when the tempNum and tempDen get initialized, so...?
Function: DeFuzzSource : /*...*/Options : -CPUHCS12 -D__ONLY_INIT_SP -D_HCS12_SERIALMON -Env"GENPATH= /*...*/" -Env"LIBPATH= /*...*/" -Env"OBJPATH= /*...*/" -Env"TEXTPATH= /*...*/" -Lasm="/*...*/FuzzyLevel.c.o.lst" -Mb -ObjN="FuzzyLevel.c.o" 0000 1b9c [2] LEAS -4,SP 130: signed int tempNum; //Temporary Numerator var 131: signed int tempDen; 132: unsigned int i; //iteration counter 133: 134: 135: //***Motor A*** 136: tempNum = 0; 0002 073e [4] BSR *+64 ;abs = 0042 137: tempDen = 0; 138: 139: for(i = 3; i>0;i--){ 140: tempNum = tempNum + (Fo_A[i] * Se[i]); 0004 e6e20000 [4] LDAB Fo_A,X 0008 071f [4] BSR *+33 ;abs = 0029 000a 26f8 [3/1] BNE *-6 ;abs = 0004 141: tempDen = tempDen + Fo_A[i]; 142: } 143: 144: dT_ThrotA = (tempNum / tempDen); 000c ec82 [3] LDD 2,SP 000e ee80 [3] LDX 0,SP 0010 1815 [12] IDIVS 0012 7e0000 [3] STX dT_ThrotA 145: 146: //***Motor C*** 147: tempNum = 0; 0015 072b [4] BSR *+45 ;abs = 0042 148: tempDen = 0; 149: 150: for(i = 3; i>0;i--){ 151: tempNum = tempNum + (Fo_C[i] * Se[i]); 0017 e6e20000 [4] LDAB Fo_C,X 001b 070c [4] BSR *+14 ;abs = 0029 001d 26f8 [3/1] BNE *-6 ;abs = 0017 152: tempDen = tempDen + Fo_C[i]; 153: } 154: 155: dT_ThrotC = (tempNum / tempDen); 001f ec82 [3] LDD 2,SP 0021 eeb3 [3] LDX 4,SP+ 0023 1815 [12] IDIVS 0025 7e0000 [3] STX dT_ThrotC 156: } 0028 0a [7] RTC 0029 87 [1] CLRA 002a 3b [2] PSHD 002b b754 [1] TFR X,D 002d 59 [1] LSLD 002e b746 [1] TFR D,Y 0030 ecea0000 [4] LDD Se,Y 0034 ed80 [3] LDY 0,SP 0036 13 [3] EMUL 0037 e386 [3] ADDD 6,SP 0039 6c86 [2] STD 6,SP 003b 3a [3] PULD 003c e382 [3] ADDD 2,SP 003e 6c82 [2] STD 2,SP 0040 09 [1] DEX 0041 3d [5] RTS 0042 c7 [1] CLRB 0043 87 [1] CLRA 0044 6c84 [2] STD 4,SP 0046 6c82 [2] STD 2,SP 0048 ce0003 [2] LDX #3 004b 3d [5] RTS 157: //-----------------------DeFuzz---------------------------- 158:
Hello AirDragon,
This issue might be related to the known compiler defect #MTWX35998 (Incorrect code generated by compiler when compiler creates sub-functions for common code and the sub function access an array defined as local variable).
Could you perhaps try to disable -onf as suggested by Daniel or try to declate the variables (tempNum, tempDen) as static.
This issue was fixed in CodeWarrior for HCS12(x) v5.0.
I'd recommend you to download and install the latest CW available here:
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=CW-HCS12X&fpsp=1&tab=Design_Tools_Tab
Stanish
Well, it appears that it just might be the #MTWX35998 defect...
I applied the -Onf option as Daniel suggested, and the Defuzz variables initialized as they where supposed to.
Stanish, I have the 5.1 Special Edition, when I look at the version in the "Help > About CodeWarrior" it gives me version 5.9.0 build 5294.
[Edit] I also tried declaring them as static (without the -Onf option), but they still didn't initialize.
There are no local arrays in this sample, so I wonder how it could be this particular bug. Well I did not lookup the details of MTWX35998 but the description sounds not like this issue at all.
Also when looking at the assembly listing, I'm sure the variables get zeroed out. So I don't see how matches with the initial description of "tempNum and tempDen get a random number in them instead of being initialized to 0".
So is anyone seeing where the generated code is incorrect?
Or is this "just" about that the -onf optimization makes it apear as if the variables do not get set? Is this a code generation issue or a debug info issue?
Daniel
I can't rightly tell, I'm going through each ASM operator in the DeFuzz subroutine, and don't see anything wrong with it.
Every now and then the debugger shows the correct values for tempNum and tempDen when I'm running through the C steps... but mostly it shows a seemingly random number.
I've figured out that the DeFuzz assembly runs through the for() loop once before the debugger halts it, which may explain in part the random number seen before.
The good news is that it is behaving itself... for now.
AirDragon,
Indeed we can deny that this issue is related to #MTWX35998. Sorry, I thought you are perhaps using an older version of the compiler.
I assume that this is either an debug issue or stack overflow. If the function works as expected then it's probably a debug info related issue.
Stanish
Wow is that bug still around? I remember reporting it back in the Metrowerks days at CW 1.2 or something like that. Since then I have had "create subfunctions for common code" disabled merely out of suspicion.
10 years to fix a bug...
The common code optimization, -onf to disable, makes the code a bit harder to follow, so I would recommend to temparly disable it in order to follow the code more directly.
Basically the created subfunction called with "BSR *+64 ;abs = 0042" does store 0 to the 2 locals. The same code at offset 0x0044 is used to zero out the variables for source code lines at 136 and at 147.
Daniel