I am writing the firmware for an embedded device in C using the Silicon Labs IDE and the SDCC compiler. The device architecture is based on the 8051 family. The function in question is shown below. The function is used to set the ports on my MCU to drive a stepper motor. It gets called in by an interrupt handler. The big switch statement just sets the ports to the proper value for the next motor step. The bottom part of the function looks at an input from a hall effect sensor and a number of steps moved in order to detect if the motor has stalled. The problem is, for some reason the second IF statement that looks like this if (StallDetector > (GapSize + 20))
{
HandleStallEvent();
}
always seems to get optimized out. If I try to put a breakpoint at the HandleStallEvent()
call the IDE gives me a message saying "No Address Correlation to this line number". I am not really good enough at reading assembly to tell what it is doing but I have pasted a snippet from the asm output below. Any help would be much appreciated.
void OperateStepper(void)
{
//static bit LastHomeMagState = HomeSensor;
static bit LastPosMagState = PosSensor;
if(PulseMotor)
{
if(MoveDirection == 1) // Go clockwise
{
switch(STEPPER_POSITION)
{
case 'A':
STEPPER_POSITION = 'B';
P1 = 0xFD;
break;
case 'B':
STEPPER_POSITION = 'C';
P1 = 0xFF;
break;
case 'C':
STEPPER_POSITION = 'D';
P1 = 0xFE;
break;
case 'D':
STEPPER_POSITION = 'A';
P1 = 0xFC;
break;
default:
STEPPER_POSITION = 'A';
P1 = 0xFC;
} //end switch
}
else // Go CounterClockwise
{
switch(STEPPER_POSITION)
{
case 'A':
STEPPER_POSITION = 'D';
P1 = 0xFE;
break;
case 'B':
STEPPER_POSITION = 'A';
P1 = 0xFC;
break;
case 'C':
STEPPER_POSITION = 'B';
P1 = 0xFD;
break;
case 'D':
STEPPER_POSITION = 'C';
P1 = 0xFF;
break;
default:
STEPPER_POSITION = 'A';
P1 = 0xFE;
} //end switch
} //end else
MotorSteps++;
StallDetector++;
if(PosSensor != LastPosMagState)
{
StallDetector = 0;
LastPosMagState = PosSensor;
}
else
{
if (PosSensor == ON)
{
if (StallDetector > (MagnetSize + 20))
{
HandleStallEvent();
}
}
else if (PosSensor == OFF)
{
if (StallDetector > (GapSize + 20))
{
HandleStallEvent();
}
}
}
} //end if PulseMotor
}
... and the asm output for the the bottom part of this function...
; C:\SiLabs\Optec Programs\HSFW_HID_SDCC_2\MotionControl.c:653: if(PosSensor != LastPosMagState)
mov c,_P1_4
jb _OperateStepper_LastPosMagState_1_1,00158$
cpl c
00158$:
jc 00126$
C$MotionControl.c$655$3$7 ==.
; C:\SiLabs\Optec Programs\HSFW_HID_SDCC_2\MotionControl.c:655: StallDetector = 0;
clr a
mov _StallDetector,a
mov (_StallDetector + 1),a
C$MotionControl.c$657$3$7 ==.
; C:\SiLabs\Optec Programs\HSFW_HID_SDCC_2\MotionControl.c:657: LastPosMagState = PosSensor;
mov c,_P1_4
mov _OperateStepper_LastPosMagState_1_1,c
ret
00126$:
C$MotionControl.c$661$2$8 ==.
; C:\SiLabs\Optec Programs\HSFW_HID_SDCC_2\MotionControl.c:661: if (PosSensor == ON)
jb _P1_4,00123$
C$MotionControl.c$663$4$9 ==.
; C:\SiLabs\Optec Programs\HSFW_HID_SDCC_2\MotionControl.c:663: if (StallDetector > (MagnetSize + 20))
mov a,_MagnetSize
mov r2,a
rlc a
subb a,acc
mov r3,a
mov a,#0x14
add a,r2
mov r2,a
clr a
addc a,r3
mov r3,a
clr c
mov a,r2
subb a,_StallDetector
mov a,r3
subb a,(_StallDetector + 1)
jnc 00130$
C$MotionControl.c$665$5$10 ==.
; C:\SiLabs\Optec Programs\HSFW_HID_SDCC_2\MotionControl.c:665: HandleStallEvent();
ljmp _HandleStallEvent
00123$:
C$MotionControl.c$668$2$8 ==.
; C:\SiLabs\Optec Programs\HSFW_HID_SDCC_2\MotionControl.c:668: else if (PosSensor == OFF)
jnb _P1_4,00130$
C$MotionControl.c$670$4$11 ==.
; C:\SiLabs\Optec Programs\HSFW_HID_SDCC_2\MotionControl.c:670: if (StallDetector > (GapSize + 20))
mov a,#0x14
add a,_GapSize
mov r2,a
clr a
addc a,(_GapSize + 1)
mov r3,a
clr c
mov a,r2
subb a,_StallDetector
mov a,r3
subb a,(_StallDetector + 1)
jnc 00130$
C$MotionControl.c$672$5$12 ==.
; C:\SiLabs\Optec Programs\HSFW_HID_SDCC_2\MotionControl.c:672: HandleStallEvent();
C$MotionControl.c$678$2$1 ==.
XG$OperateStepper$0$0 ==.
ljmp _HandleStallEvent
00130$:
ret
It looks to me like the compiler is NOT optimizing out this second if statement from the looks of the asm but if that is the case why does the IDE not allow me so set a breakpoint there? Maybe it's just a dumb IDE!
The IF statement is not being optimized out. This is the code for it.
C$MotionControl.c$670$4$11 ==.
; C:\SiLabs\Optec Programs\HSFW_HID_SDCC_2\MotionControl.c:670: if (StallDetector > (GapSize + 20))
mov a,#0x14 ; r2,r3 = 20 + GapSize
add a,_GapSize ; (adding a 16-bit number in two 8-bit steps)
mov r2,a
clr a
addc a,(_GapSize + 1)
mov r3,a
clr c
mov a,r2 ; subtracting in two 8-bit steps
subb a,_StallDetector
mov a,r3
subb a,(_StallDetector + 1)
jnc 00130$ ; jump if carry not set (fall through if carry set)
C$MotionControl.c$672$5$12 ==.
; C:\SiLabs\Optec Programs\HSFW_HID_SDCC_2\MotionControl.c:672: HandleStallEvent();
C$MotionControl.c$678$2$1 ==.
XG$OperateStepper$0$0 ==.
ljmp _HandleStallEvent ; it knows HandleStallEvent does not return!
00130$: ; or rather, it knows this handler cannot return, so there's no need to call.
ret
I notice that in the 3rd-to-last line, something funny is happening. It is not doing a function call to HandleStallEvent
. It is doing a long-jump, so it evidently knows that HandleStallEvent
cannot return. I also see that in the two lines above that, it is defining assembler symbols that relate the line number to the jump instruction. So, it has a symbol for line 678. If the IDE won't let you set a breakpoint at line 678, perhaps you can get the hex address of line 678, and set it at the hex address. Another thing you might try could be to insert a local variable definition like int breakhere = 1
before that line, and see if that gives you some instructions you can break at.
BTW, you can see that the CPU thinks in terms of 8-bit numbers, so if you can use char instead of short, it will save instructions. Whether the time saved is worth it depends on what percent of time the machine is in this code.
BTW2, if you want to squeeze performance out of this puppy, what I relied on when I was doing embedded work was randomly halting the IDE (or the Intel "Blue Box" ICE). Here's something about that.