Keil Logo

Interrupt related crashes.

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Author
sebastiaan knippels
Posted
11-Feb-2019 09:43 GMT
Toolset
C51
New! Interrupt related crashes.

Dear all,

We are programming a 8051 core in C and we are experiencing crashes which are related to interrupts.

The machine in question uses 2 DACs to control servo motors. These motors rotate 2 C-shaped hands which needs to be homed. This homing (moving to default position) is done by 4 interrupts, 2 for each hand. Each hand has a sensor to detect the opening.

First we let the hands turn and we use a software counter to let them speed up, once at speed I enable 2 external interrupts which are triggered on the opening sensors.

The external interrupts make sure that the hands are steered in the opposite direction at full force to let them stop quicker.

Both external interrupts also start 2 hardware timers at a 1ms interval. These timer interrupts are used to track the time of the counter pulse and to turn the motors off.

Occasionally this action results in complete system reboot. It can go well a 100 times or it may reset after the 5th homing action. The crashs always occurs after the homing, this is why we are convinced it must be related to the interrupts.

The code which starts the motors and enables the external interrupts:

case lowerNippleHands:          // lower nipple arms and store the spokes if mininum torque isn't reached
                        nippleKeysOnNipples=0;  // control a pneumatic cylinder
                        rimMotorEnabled = 0;    // controls a relais
                        leftServoSCREW = 0;     // these are the 4 dacs used to controll the servo motors
                        rightServoSCREW = 0;
                        leftServoUNSCREW=zeroLoadTorqueLeft+10;
                        rightServoUNSCREW=zeroLoadTorqueRight+10;  // start both motors in unscrew direction at low torque
                        gotoCase(lowerNippleHands+1,150);                                        // 300ms delay to the next case
                break;

                case lowerNippleHands+1:
                        updateTorque_bool = false;
                        leftServoUNSCREW=255;                                                                                   // turn the motors at full power
                        rightServoUNSCREW=255;
                        leftServoSCREW=0;
                        rightServoSCREW=0;
                        gotoCase(lowerNippleHands+2,100);                               // 200ms delay to next case
                break;

                case lowerNippleHands+2:
                        iex2=0; // ensures the ISR does not gets executed when ex2 is set,
                        iex3=0; //  " " same for #3
                        ex2=1;  // start listening to upgoing flank of nipple home sensor (enables the ISR)
                        ex3=1;  // these interrupts set two timer interrupts which give a pulse to stop the nipple keys.
                        if(menu == TESTMACHINESEQUENCE) updateTorque_bool = true;
                        readySignal = true;
                break;

The interrupt code is as follows:

void ISR_ex2(void) interrupt ex2_vector                                         // left nipple hand home sensor
{
        ex2=0;
        leftServoSCREW=255;                                                                                                                     // initialize counter pulse
        leftServoUNSCREW=0;

        counterL = 0;                                                                                                                                           // clear this counter
        TR1 = 0;                                         // start timer 1
        TH1 = ((-500 >> 8) & 0xff);
        TL1 = (-500 & 0xff);
        TR1 = 1;
        ET1 = 1;
}

void ISR_ex3(void) interrupt ex3_vector                                         // right nipple hand home sensor
{
        ex3=0;
        rightServoSCREW=255;                                                                                                            // initialize counter pulse
        rightServoUNSCREW=0;

        counterR = 0;                                                                                                                                           // clear this counter
        TR2 = 0;                                         // start timer 2
        TH2 = ((-100 >> 8) & 0xff);
        TL2 = (-100 & 0xff);
        TR2 = 1;
        ET2 = 1;
}

void ISR_timer1(void) interrupt timer1_vector // timer 1 to stop left nipple key 1 ms interval
{
        counterL++;
        if(counterL==counterPulseL) {
                ET1 = 0;
                TR1 = 0;
                leftServoSCREW=0;
                leftServoUNSCREW=0;}
        else {
                TR1 = 0;                                         // restart timer 1
                TH1 = ((-500 >> 8) & 0xff);
                TL1 = (-500 & 0xff);
                TR1 = 1;}
}

void ISR_timer2(void) interrupt timer2_vector                   // timer 2 to stop right nipple key 1 ms interval
{
        counterR++;
        if(counterR==counterPulseR) {
                ET2 = 0;
                TR2 = 0;
                rightServoSCREW=0;
                rightServoUNSCREW=0;}
        else {
                TR2 = 0;                                         // restart timer 2
                TH2 = ((-100 >> 8) & 0xff);
                TL2 = (-100 & 0xff);
                TR2 = 1; }
}

Our leading theory is the crash/system reboot is perhaps a memory overlap between an ISR call and a function call with arguements.

I was wondering if any of you could shed some light on this matter. Could the 'using' keyword resolve our issue? Than we would let the interrupts using an alternative register bank.

I am open for ideas and suggestions.

Bas

Author
erik malund
Posted
11-Feb-2019 14:17 GMT
Toolset
C51
New! RE: Interrupt related crashes.

Methinks you have stack overflow.
try adding to all

void ISR...(void) interrupt vector using 1

If you use interrupt priorities the 'using' must be different for high and low

also moving some rarely used veriables to xdata may be needed

stack overflow is easily checked bu filling stack pointer to end of idata with 0xff running with a breakpoint in reset and checking the memory when it breaks

Next Thread | Thread List | Previous Thread Start a Thread | Settings

  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.