CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Priority of Interrupts, and setting priority?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
arrow



Joined: 17 May 2005
Posts: 213

View user's profile Send private message

Priority of Interrupts, and setting priority?
PostPosted: Fri Jul 08, 2005 9:13 am     Reply with quote

Hi

Is there a priority of interrupts?
If yes, then is there a way to set the priority?

If I have an INT_RB, and the subroutine is executing, and
an INT_TIMER2 is set, will INT_RB first finish or will it go straight to
INT_TIMER2?

I am trying to flash an LED using INT_TIMER2, but my main concern is that the INT_RB routine gets done.

Thank you in advance
arrow
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Fri Jul 08, 2005 9:53 am     Reply with quote

This information is readily available on the forum. Do a search.

http://www.ccsinfo.com/forum/viewtopic.php?t=22282&highlight=priority+interrupts
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
valemike
Guest







Re: Priority of Interrupts, and setting priority?
PostPosted: Fri Jul 08, 2005 1:12 pm     Reply with quote

arrow wrote:
Hi
Is there a priority of interrupts?
If yes, then is there a way to set the priority?

If I have an INT_RB, and the subroutine is executing, and
an INT_TIMER2 is set, will INT_RB first finish or will it go straight to
INT_TIMER2?

I am trying to flash an LED using INT_TIMER2, but my main concern is that the INT_RB routine gets done.


I took a shortcut in my isrs. I have TIMER1, TIMER3 and RB0 interrupt. I'm not sure how much an rb0 int is different from an rb int in the way they are cleared.

Anyways, from within my other two ISRs, just before i exit those isrs, i have the following code:

#int_ext
void rb0_isr(void)
{
....
}

#int_timer1
void tmr1_isr(void)
{
...
if (rb0 interrupt flag is set)
{
rb0_isr();
}
}

You can do this shortcut with rb0 interrupts because simply doing a dummy read on rb0 will clear that flag, and that is all you need to clear that interrupt. after you call rb0_isr(), the tmr1_isr() will exit and context restoration is implemented by the CCS compiler.

And to get priorities, you can use #priority, but this only specifies which interrupt to test first. Once you're in the isr, all the other isrs will have to wait. (unless you implement a fast isr)

What ive shown you though is how to avoid the time-consuming isr overhead of a pending rb0 int.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 08, 2005 3:14 pm     Reply with quote

Quote:
#int_ext
void rb0_isr(void)
{
....
}

#int_timer1
void tmr1_isr(void)
{
...
if (rb0 interrupt flag is set)
{
rb0_isr();
}
}

You can do this shortcut with rb0 interrupts because simply doing a dummy read on rb0 will clear that flag, and that is all you need to clear that interrupt. after you call rb0_isr(), the tmr1_isr() will exit and context restoration is implemented by the CCS compiler.


Your code doesn't do what you think it's doing. In fact, it just sets
the INTF interrupt flag (which in fact is already set if the test is true),
and exits the Timer1 isr. The PIC still has to do a complete trip through
the interrupt dispatcher routine for each interrupt.

Here is a test program to show this. This was compiled with
PCM vs. 3.227.
Code:
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)

#byte INTCON = 0x0B
#bit  INTF_BIT = INTCON.1

#int_ext
void rb0_isr(void)
{
char c;
c = 0x55;
}

//---------------------
#int_timer1
void tmr1_isr(void)
{
char k;
k = 0xAA;

if(INTF_BIT)
  {   
   rb0_isr();
  }
}

//======================
void main()
{

while(1);
}


Here is part of the .LST file, with comments:
Quote:
.................... #int_ext
.................... void rb0_isr(void)
.................... {
.................... char c;
.................... c = 0x55;
003C: MOVLW 55
003D: MOVWF 2A
.................... }
....................
.................... //---------------------
003E: BCF 0B.1
003F: BCF 0A.3
0040: BCF 0A.4
0041: GOTO 023
.................... #int_timer1
.................... void tmr1_isr(void)
.................... {
.................... char k;
.................... k = 0xAA;
0042: MOVLW AA
0043: MOVWF 29
....................
.................... if(INTF_BIT)
0044: BTFSS 0B.1
0045: GOTO 047
.................... {
.................... rb0_isr();
0046: BSF 0B.1 <-- It just sets the INTF bit
.................... }
.................... }
....................
.................... //======================
0047: BCF 0C.0
0048: BCF 0A.3
0049: BCF 0A.4
004A: GOTO 023
valemike
Guest







PostPosted: Fri Jul 08, 2005 4:09 pm     Reply with quote

PCM Prog, i made a mistake.

You're right, that sure looks like it's going thru the interrupt dispatcher twice. What i meant to write was:

Code:

#int_ext
void int_rb0(void)
{
    my_rb0_fxn();
}


Then from the timer1_isr, i do:
Code:

#int_timer1
void tmr1_isr(void)
{
    [timer 1 isr code goes here]
    ...
    Before exiting the timer isr, do a check on the rb0 int flag
    if (rb0 interrupt flag is TRUE)
    {
        my_rb0_fxn();
    }
}
...

// notice that no #int_xxx preprocessor directive precedes this function
void my_rb0_fxn(void)
{
    // There is at least one dummy read of rb0 here, which automatically clears the flag
}



I hope this is right, i've been doing this for a while now. If it doesn't do what I expect, then that means i'm just lucky enough not to be having multiple pending isrs at once.
valemike
Guest







PostPosted: Fri Jul 08, 2005 4:16 pm     Reply with quote

maybe i should have read your comment more closely, especially the assembly listing.

However, if you call the non_isr function called my_rb0_fxn(), i don't think that the intf bit will get set or cleared.

I looked at my disassembly listing, and it's strange that the intf does not get set immediately (this is PCH for the 18F458 by the way):

Code:

.................... #int_ext 
.................... void rb0_interrupt(void) 
.................... { 
....................     if (GLOBAL_door_type_value == DOOR_TYPE_BESAM_AMD) 
*
03AE:  MOVF   54,W
03B0:  SUBLW  04
03B2:  BNZ   03B8
....................     { 
....................         besam_amd_isr(); 
03B4:  BRA    0362
....................     } 
.....etc. etc. etc.
valemike
Guest







PostPosted: Fri Jul 08, 2005 4:22 pm     Reply with quote

Wait, forget my most recent post.

I think what i'm trying to say is that if i am in a timer1 isr, then check the rb0 interrupt flag, then i should call a function not defined as the #ext_isr itself, but rather a function that the rb0 isr calls.

Thus to accomplish this, i have to declare the #int_ext isr function, and then the actual meat of the isr is in another function.

I sure hope that works, and if it isn't, well i'm lucky to not be getting any negative side effects from doing it that way Shocked
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 08, 2005 4:48 pm     Reply with quote

I think it works OK, but it costs another stack level to call the function.
So with a PIC that has only 8 stack levels, I'd just make a duplicate copy
of the int_ext code and put it in the int_timer1 isr.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Jul 08, 2005 4:51 pm     Reply with quote

Here is an example of something I did like what Mike was trying to do
Code:

#INT_EXT
void Zero_Cross_ISR(void)
{
  if (bit_test(Current_Stat.Byte, ZEROX_FAIL_BIT))
  {
    Need_To_Send_Stat = TRUE;
    Current_Stat.Bits.Zerox_Fail = FALSE;
  }
  bit_clear(FLAGS, SAVE_EEPROM_DATA_BIT);
  Power_Fail = FALSE;     /* if we get here it means power is good  */
  setup_timer_1(T1_DISABLED);
  /* first time through, we need to determine if using 50Hz or 60Hz */
  switch (Zero_Cross_State)
  {
    /* Start the frequency test */
    case START_TEST:
      set_timer1(0);     
      setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
      Zero_Cross_State = END_TEST;
      break;
     
    /* End the test and set Test_Time to the time between zero crosses */
    case END_TEST:
      if (TIMER_1_HIGH > NINE_MILISEC)
        Hz60 = FALSE;
      Zero_Cross_State = IDLE;
      break;
       
    /* Handle zero crosses */
    default:
      if (Hz60)
      {
        set_timer1(PHAZA_ZEROX_60HZ);      /* setup for Phaz A zero cross  */
        Phaz_Keeper = 0; 
      }
      else
      {
        set_timer1(PHAZA_ZEROX_50HZ);      /* setup for Phaz A zero cross  */
        Phaz_Keeper = 2; 
      }
      setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
      Zero_Cross_Count = 10;
      bit_set(PIE1, TMR1IE);
      bit_clear(PIR1, TMR1IF);
      break;
  }
  /* Clear the flag bit since we are about to bypass the compilers clear */
  bit_clear(INTCON, INTF);
/* Check the int's again */
  #asm
    BCF    0x0A,3  /* clear 2 MSB's of the PC */
    BCF    0x0A,4
    GOTO   0x18    /* go back to the start of then isr handler  */
  #endasm
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group