1
\$\begingroup\$

I'm using the PIC18F46k22 mcu and I'm using two function in my high priority interrupt routine:

#pragma code
#pragma code My_HiPrio_Int=0x0008 
#pragma code
#pragma interrupt chk_isr
#pragma code
void My_HiPrio_Int(void)
{
 _asm
 GOTO chk_isr
 _endasm
}
void chk_isr(void) /*Serial Interrupt*/
{ 
 INTCONbits.GIE = 0;
 if(INTCONbits.TMR0IF==1) //Timer routine
 Timer0_ISR();
 if(PIR1bits.RC1IF) //RS485 receiver 
 RC_ISR();
 INTCONbits.GIE = 1;
}
void Timer0_ISR(void)
{
 nTick0++;
 if(pSet == 0) nTickSetPress++;
 else nTickSetPress = 0;
 if(pPlus == 0) nTickPlusPress++;
 else nTickPlusPress = 0;
 if(pMinus == 0) nTickMinusPress++;
 else nTickMinusPress = 0;
 if(pShift == 0) nTickShfPress++;
 else nTickShfPress = 0;
 if(pCountPlus == 0) nTickCount++;
 else nTickCount = 0;
 if(pReset == 0) nTickResetPress++;
 else nTickResetPress = 0;
 if(bCdlyStart == 1) nCdlyCount++;
 if(nCdlyCount >= nTickCdly) bCdlyStart = 0;
 if(bDisplayTime == 1) nDisplayTimeCount++;
 if(bBlinkDigitFast == 1) nTickBlinkFast++;
 TMR0H = TMR0HValue;
 TMR0L = TMR0LValue;
 INTCONbits.TMR0IF = 0;
}
void RC_ISR(void) 
{
 rxbuf485 = RCREG1;
 if (rxbuf485 == 0)
 {
 return;
 }
 if (rxbuf485 == TOKEN)
 {
 b485RxToken = 1;
 return;
 }
 if (b485RxComplete) return;
 if (!b485SOH)
 {
 if (rxbuf485 != SOH) return;
 b485SOH = 1;
 n485RxDataPos = 0;
 b485RxComplete = 0;
 memset (RS485RXDATA, 0, sizeof(RS485RXDATA));
 return;
 } 
 else if (rxbuf485 == EOT)
 {
 b485SOH = 0;
 b485RxComplete = 1;
 return;
 }
 if (n485RxDataPos == 50) 
 n485RxDataPos = 50;
 if (n485RxDataPos>=RS485RXSIZE) 
 n485RxDataPos--;
 RS485RXDATA[n485RxDataPos++] = rxbuf485;
 return;
}
void Timer0Init(void)
{
 T0CON = 0x07;
 TMR0H = TMR0HValue;
 TMR0L = TMR0LValue;
 T0CONbits.TMR0ON = 1;
 INTCONbits.TMR0IE = 1;
 nTick0 = 0; 
 nTickSetPress = 0;
 nTickResetPress = 0;
 nTickCdly = 0; 
 nTickBlinkFast = 0;
}
void RS485Init(void)
{
 TRISCbits.TRISC7=1; // RX
 TRISCbits.TRISC6=0; // TX
 TXSTA1 = 0x00; 
 RCSTA1 = 0x90; 
 SPBRG1 = 30; 
 BAUDCON1 = 0x00; 
 PIE1bits.RC1IE = 1; 
 TRISCbits.TRISC3 = 0;
 p485 = 0; 
 memset (RS485RXDATA, 0, sizeof(RS485RXDATA)); 
}

Can two routine be done in a high priority interrupt? Will there be any problem in long term? This is because I'm trying to find out why my device always hang after running a few days...

asked Oct 13, 2014 at 2:59
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Have you considered declaring your 2 functions as inline? This would avoid having these as real function calls in the compiled code. Also, the idea of using a function like memset inside an ISR doesn't seem like agood idea to me ... I couldn't really give you a good reason though - seems like there might be lots of unnecessary stack usage by all of the function parameter values. \$\endgroup\$ Commented Oct 14, 2014 at 1:47
  • \$\begingroup\$ Adding more to @brhans comment, I can see there is some unncessary code in those "ISR" functions. Also, you don't need a return at the end of function, you can save an instruction there. I don't think calling two functions in ISR making it unresponsive but there could be some another reason for that! \$\endgroup\$ Commented Oct 20, 2014 at 9:22
  • \$\begingroup\$ Note also that with the C18, calling another function from the interrupt routine may add such an overhead that it fails badly. Check e.g. xargs.com/pic/c-faq.html#isrfunc In had the issue even with a short subroutine call (in C) on mplabx with xc8. So this is yet another reason to inline the calls, here again for the interruption to return as fast as possible. \$\endgroup\$ Commented Feb 22, 2015 at 16:09

2 Answers 2

1
\$\begingroup\$

There is much silliness here:

  1. Your interrupt routine is just jumping into another routine instead of executing directly. You may need to do something like that if you are also using low priority interrupts, but this doesn't seem to be the case.

  2. What's with setting GIE to 0 in the interrupt routine? You need to actually read the datasheet.

  3. Even worse, you are setting GIE to 1 near the end of the second interrupt routine. I could try to explain why you shouldn't do that, but you need to read the datasheet anyway, so you can discover for yourself why this is a dumb idea.

  4. By being too clever by a half, as the British like to say, you have defeated the compiler's means of properly turning on interrupts again at the end of the interrupt service routine. Put another way, you are no longer running a RETFIE instruction.

  5. This whole thing could have been done much more easily in assembler, and then maybe you'd see how the interrupt code is messed up the way it is now. Unlike on large systems with many levels of abstraction, on small resource limited systems using a compiler doesn't alleviate the need to actually understand what is happening at the machine instruction level.

  6. Messing with machine details like interrupts absolutely requires reading the datasheet.

answered Nov 30, 2014 at 13:10
\$\endgroup\$
0
\$\begingroup\$

There's no trouble in calling functions within ISRs, neither assigning high priority to multiple peripherals as long as it doesn't create a conflict while servicing them. There are a couple of things to have in mind though, such as latency and the order in which you service them. Calling functions within ISRs add extra cycles when the context switch is performed (in and out), but its something that might not affect your application at all if weighed in. As for the order, consider writing up top the if(flag){} chain the higher priority or critical services, they will be checked first. There's something odd in your code and that might the the reason why your MCU hangs, after you call RC_ISR(); you are not clearing the PIR1bits.RC1IF flag. You are exiting the high priority ISR with a flag that will force a reentry.

answered Oct 31, 2014 at 11:35
\$\endgroup\$
1
  • \$\begingroup\$ There's no trouble in calling functions within ISRs There might be problems if the function in question is also called outside the interrupt and if the compiler doesn't support reentrant functions \$\endgroup\$ Commented Oct 31, 2014 at 14:24

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.