a problem in my code with k*e*i*l optimization levels!

Status
Not open for further replies.

7rots51

Advanced Member level 4
Joined
May 17, 2002
Messages
1,183
Helped
25
Reputation
50
Reaction score
12
Trophy points
1,318
Visit site
Activity points
9,636
hdlc_transmit

Hello

I have a problem with keil in this project ,please read this code and find the problem,my guess is that code optimization levels may produce the bug.


Open this project in keil 7.06:


State 1:

compile it with this options: AT89C52(use extended linker and assembler LX51 AX51),code optimization in level 8,remove tick of linker code packing.

go to debug mode and open disassembly window and c:0x0142 you can see that MT9092_Rd returns byte in R7 and the main program use it as status varible.

there is no problem and everything goes well.

exit debug mode.

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

State 2:

compile it with this options: AT89C52(use extended linker and assembler LX51 AX51),add tick of linker code packing,code optimization in level 11.

go to debug mode and open disassembly window and c:0x006A you can see that MT9092_Rd returns byte in R7 and the main program doe not use it as status varible.the return value of MT9092_Rd function in R7 (status variable in main
function) does not used and missed!

This is my problem,please help me to solve it.


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

Only this part of code is under verify:

at main fuction,return value of HDLC_Status_R() as status variable.

while(1)
{
status = HDLC_Status_R();
status = status >> 2;
status = status & 0x03;
if(status == TxEMPTY)
{
TXX = 0;
HDLC_Transmit();

---------------------------------------------------------------------------
State 1 disaasembly:

34: while(1)
35: {
36: status = HDLC_Status_R();
C:0x0136 7F04 MOV R7,#0x04
C:0x0138 120159 LCALL MT9092_Rd(C:0159)
37: status = status >> 2;
C:0x013B EF MOV A,R7
C:0x013C 13 RRC A
C:0x013D 13 RRC A
C:0x013E 543F ANL A,#0x3F
C:0x0140 FF MOV R7,A
38: status = status & 0x03;
C:0x0141 530703 ANL 0x07,#0x03
39: if(status == TxEMPTY)
C:0x0144 BF020E CJNE R7,#0x02,C:0155
40: {
41: TXX = 0;
C:0x0147 C2B4 CLR T0(0xB0.4)
42: HDLC_Transmit();
C:0x0149 1201D9 LCALL HDLC_Transmit(C:01D9)


---------------------------------------------------------------------------
State 2 disaasembly:

34: while(1)
35: {
36: status = HDLC_Status_R();
37: status = status >> 2;
C:0x006A 3188 ACALL C:0188
C:0x006C 13 RRC A
C:0x006D 13 RRC A
C:0x006E 543F ANL A,#0x3F
C:0x0070 FF MOV R7,A
38: status = status & 0x03;
C:0x0071 530703 ANL 0x07,#0x03
39: if(status == TxEMPTY)
C:0x0074 BF020D CJNE R7,#0x02,C:0084
40: {
41: TXX = 0;
C:0x0077 C2B4 CLR T0(0xB0.4)
42: HDLC_Transmit();
C:0x0079 31AC ACALL HDLC_Transmit(C:01AC)


Bye
 

Look here:
hxxp://www.elektroda.pl/eboard/viewtopic.php?t=56285&highlight=optimization+level

hope this is useful for you
 

Hi,

(I'm late but hope this can help you anyway.....)

I'm sorry, but I don't Agee with you (hope I understand correctly your problem).

I think You have undervalutate the following row

C:0x006A 3188 ACALL C:0188

ACALL is a absolute call to 0x0188.

From disassembly:

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

C:0x006A 3188 ACALL C:0188

......Jump to C:0188

>> C:0x0188 7F04 MOV R7,#0x04
>> C:0x018A 11B9 ACALL MT9092_Rd(C:00B9)
>> C:0x018C EF MOV A,R7
>> C:0x018D 22 RET

......return to calling code


C:0x006C 13 RRC A
C:0x006D 13 RRC A
C:0x006E 543F ANL A,#0x3F
C:0x0070 FF MOV R7,A
38: status = status & 0x03;
C:0x0071 530703 ANL 0x07,#0x03
39: if(status == TxEMPTY)
C:0x0074 BF020D CJNE R7,#0x02,C:0084
40: {

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


that is the same flow of the example of case 1.

Compliler at level 11 is executing level 9 too (reuse common entry code)
please see other call to 0x188 subroutine.....

28: do{
29: if(HDLC_RxState == RxEMPTY) getout = 1;
C:0x00F4 3188 ACALL C:0188


30: if( (HDLC_RxState == RxOVER) && ~getout)
C:0x00FC 3188 ACALL C:0188
C:0x00FE 5403 ANL A,#0x03



if You turn on the "Assembly Code" option in "listing" of the project
You could have the assembly in your .lst file

; SOURCE LINE # 34
; SOURCE LINE # 35
; SOURCE LINE # 36
MOV R7,#04H
E CALL _MT9092_Rd
;---- Variable 'status' assigned to Register 'R7' ----
; SOURCE LINE # 37
MOV A,R7
RRC A
RRC A
ANL A,#03FH
MOV R7,A
; SOURCE LINE # 38
ANL AR7,#03H
; SOURCE LINE # 39
R xJNE R7,#02H,?C0003
; SOURCE LINE # 40


Sorry, but i think you have to search your problem in other part of software (or hw).

(This not means that K** c51 do not have bugs...... IT HAVE BUGS !!! )

Hope this help.
 

crono:

thanks for your notice on the problem.I solved it by reducing the optimization level tolevel 8 and avoid some optimization.
As many users know k//l is a good compiler for 8o51 .I think when we use high level of optimization ,some fault may occur in logic of our software and it may operate incorrectly.
It is better to use lower level of optimization and write more simple c codes and avoid complex and heavy methods for programming.
 

hi,

This is a tipical K***l bug.

Is a simple bit swap routine for a remote keyboard wit some led.
The routine must swap bit 4 and 5.

This is not dependent by optimizing level. I tryed also with volatile declaration without solution.

If someone Know how to solve in a better way is welcome !!!



// ------------------------------------
// Shared flags
// ------------------------------------
volatile unsigned char bdata bTmp4Swap;
sbit fTmp4SwapBit0 = bTmp4Swap^0;
sbit fTmp4SwapBit1 = bTmp4Swap^1;
sbit fTmp4SwapBit2 = bTmp4Swap^2;
sbit fTmp4SwapBit3 = bTmp4Swap^3;
sbit fTmp4SwapBit4 = bTmp4Swap^4;
sbit fTmp4SwapBit5 = bTmp4Swap^5;
sbit fTmp4SwapBit6 = bTmp4Swap^6;
sbit fTmp4SwapBit7 = bTmp4Swap^7;
// -------------------------------


/*-------------------------------------------------------------------------*/
CASE 1 Bugged routine
/*-------------------------------------------------------------------------*/
void RxLedStatus(void) // Msg from R5P to R5L
{
bit fTmp;

bTmp4Swap = I2cPack.bDati[0]; // Received data (unsigned char)
fTmp = fTmp4SwapBit4; // Save LedWash
fTmp4SwapBit4 = fTmp4SwapBit5; // Move LedZero in pos. 4
fTmp4SwapBit5 = fTmp; // Restore LedWash in pos. 5
bLocalLeds = bTmp4Swap; // Update Local Leds
UpdateTBLeds(); // Refresh TB Leds
}

/* ASM LISTING

; FUNCTION RxLedStatus (BEGIN)
; SOURCE LINE # 167
0000 7800 E MOV R0,#LOW I2cPack+04H
0002 E6 MOV A,@R0
0003 F500 E MOV bTmp4Swap,A
; SOURCE LINE # 168
0005 A200 E MOV C,fTmp4SwapBit4
0007 9200 R MOV fTmp,C
; SOURCE LINE # 169
0009 A200 E MOV C,fTmp4SwapBit5
000B 9200 E MOV fTmp4SwapBit4,C
; SOURCE LINE # 170
000D A200 R MOV C,fTmp
000F 9200 E MOV fTmp4SwapBit5,C
; SOURCE LINE # 172
0011 F500 E MOV bLocalLeds,A
; SOURCE LINE # 174
0013 020000 E LJMP UpdateBodyTBLeds
; FUNCTION RxLedStatus (END)
*/


/*-------------------------------------------------------------------------*/
CASE 2 Patched routine
/*-------------------------------------------------------------------------*/
void RxLedStatus(void) // Msg from R5P to R5L
{
bit fTmp;

bTmp4Swap = I2cPack.bDati[0]; // Received data (unsigned char)
fTmp = fTmp4SwapBit4; // Save LedWash
fTmp4SwapBit4 = fTmp4SwapBit5; // Move LedZero in pos. 4
fTmp4SwapBit5 = fTmp; // Restore LedWash in pos. 5

ACC = 0; // REQUIRED BY COMPILER BUG !!!!!!!

bLocalLeds = bTmp4Swap; // Update Local Leds
UpdateTBLeds(); // Refresh TB Leds
}

/*
; FUNCTION RxLedStatus (BEGIN)
; SOURCE LINE # 167
0000 7800 E MOV R0,#LOW I2cPack+04H
0002 E6 MOV A,@R0
0003 F500 E MOV bTmp4Swap,A
; SOURCE LINE # 168
0005 A200 E MOV C,fTmp4SwapBit4
0007 9200 R MOV fTmp,C
; SOURCE LINE # 169
0009 A200 E MOV C,fTmp4SwapBit5
000B 9200 E MOV fTmp4SwapBit4,C
; SOURCE LINE # 170
000D A200 R MOV C,fTmp
000F 9200 E MOV fTmp4SwapBit5,C
; SOURCE LINE # 172
0011 E4 CLR A
; SOURCE LINE # 174
0012 850000 E MOV bLocalLeds,bTmp4Swap
; SOURCE LINE # 175
0015 120000 E LCALL UpdateTBLeds
; SOURCE LINE # 176
0018 22 RET
; FUNCTION RxLedStatus (END)
*/
 

NOT TESTED!

void RxLedStatus(void) // Msg from R5P to R5L
{
unsigned char x, bit4, bit5;

x = I2cPack.bDati[0]; // Received data (unsigned char)

bit4 = x & 0x10;
bit5 = x & 0x20;

x &= 0xEF; // bit 4 clear
x |= (bit5>>1); // bit 5

x &= 0xDF; // bit 5 clear
x |= (bit4<<1); //bit 4

bLocalLeds = x; // Update Local Leds
UpdateTBLeds(); // Refresh TB Leds
}

Tom
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…