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 support@ccsinfo.com

Interrupts?

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



Joined: 23 Aug 2005
Posts: 93

View user's profile Send private message Visit poster's website

Interrupts?
PostPosted: Mon Feb 06, 2006 7:51 am     Reply with quote

Hi,
Im wondering about the priority of interrupts, can I make one interrupt "prio1", that is, that this one is allways done even if I am in an other interrupt?
I want this beacuse I got an interrupt CCP1 that drives a sort of internal clock and some math code that MUST be executed at programmed times, every 10mS.
My interrupts are as follow:
Code:

// Interrupts
#int_CCP1 //compare interrupt, this MUST be done every time!!!!!!
void CCP1_isr()
{
//code...do something every 10mS
}
#int_RB  //portB interrupt no problem, only executed by switch pressing
void RB_isr()
{
code..
}
#int_rda //this can be a problem, it MUST NOT interfere with the CCP1_issr!
void serial_isr()
{
#use rs232(baud=300, xmit=PIN_C6, rcv=PIN_C7, bits=7, parity=E)
//code...
}


Can I make a priority of isr's?
Have a nice day
/Tagge
Tagge



Joined: 23 Aug 2005
Posts: 93

View user's profile Send private message Visit poster's website

PostPosted: Mon Feb 06, 2006 8:46 am     Reply with quote

I know that there is the #priority in CCS, but I think I have to be able to even jump in to the CCR1 isr when the rs232-isr is in progress..
Can I do this without loosing chars in the buffer?
And can I jump out from the rs-232 in progress at all? or should it be done..
I didnt found any good answers at the forum, anyway..
Ttelmah
Guest







PostPosted: Mon Feb 06, 2006 9:15 am     Reply with quote

It depends on the PIC involved.
Older PIC's (12/14/16 chips), do not support interrupts inside interrupts. The hardware disables the global interrupt flag, when an interrupt handler is being called. All '#priority' does, is set the order in which the interrupts are 'parsed' in the global handler. If #priority is not used, the parsing order is dependant on the order in which the interrupt handlers are defined.
On the 18 PICs, there is seperate support for hardware priority. Look in the 'readme.txt', for details of how this is used (the #int_xxx HIGH) command. Beware, that on many chips, there are 'caveats', about which particular interrupts can be high priority, and in some cases caveats about how they work. On the chips with this ability, a 'HIGH' priority interrupt can interrupt another interrupt handler.

Best Wishes
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Mon Feb 06, 2006 9:52 am     Reply with quote

If you are talking of interrupt priority I assume you are talking of PIC18Fxxxx wich can handle priorities.
The highest priority is reserved for the #int_CCP1 (compare interrupt) every 10ms.
The lowest priority is reserved for the #int_rda at @300 bauds, that is: it will long 33ms just to get a single char.
IMO this will be very difficult to get a char because a low priority interrupt cannot interrupt a high priority ISR, that is the #int_rda will be served only after high priority interrupts have been served


Humberto
Ttelmah
Guest







PostPosted: Mon Feb 06, 2006 10:10 am     Reply with quote

The priorities are not 'reserved' for any particular interrupts, they are setable by the priority flags. There are only two priorities in the hardware. So, on the 18F4525, the flag 'CCP1IP' (bit2 of IPR1), determines whether the CCP1 interrupt is high or low priority. Provided the high priority interrupt source, can be handled in significantly less than the gap between successive interrupts, there will still be time to handle the low priority devices, and a latency of up to 3mSec, will be acceptable at 300bps, for the interrupt handling of the RS232 code.
The thing that worries me, is the mention of 'math code', since this could easily involve significant time....

Best Wishes
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Mon Feb 06, 2006 10:33 am     Reply with quote

Telmah, I know that the priorities are not reserved.
I wrote this:
Quote:

The highest priority is reserved for the #int_CCP1 (compare interrupt) every 10ms.
The lowest priority is reserved for the #int_rda at @300 bauds, that is: it will long 33ms just to get a single char.

following the initial poster headline criteria:

#int_CCP1 // compare interrupt, this MUST be done every time!!!!!!
#int_rda // it MUST NOT interfere with the CCP1_issr!

Humberto
Tagge



Joined: 23 Aug 2005
Posts: 93

View user's profile Send private message Visit poster's website

PostPosted: Mon Feb 06, 2006 11:39 am     Reply with quote

Yes, Im using a PIC18f2525, and no, dont worry, the "math" is done under "normal" operation in main() and some subroutines.
But it seems that the CCP1 isr is affected by the rs232 isr anyway? I get some missed "times" during a longer time of operation (a day or so).
The rs232 isr gets a burst of chars at least every ~10sec..
Everything in the code works as planned, but the missing "times"....
and they are really important Wink
So I would love to have an CCP1 interrupt done during a rs232 interrupt.
I will try the tips that I greatfully have recived here, thanks.
DragonPIC



Joined: 11 Nov 2003
Posts: 118

View user's profile Send private message

Customize
PostPosted: Mon Feb 06, 2006 2:29 pm     Reply with quote

Sounds like you are going to have to do a customized ISR for the RS232 that checks the CCP1 interrupt flag and then calls a math function from inside that ISR.

You might be able to check the CCP1 interrupt in between each routine too (Example: in between #int_RB and #int_rda).

Quote:
The rs232 isr gets a burst of chars at least every ~10sec..
Everything in the code works as planned, but the missing "times"....


Is there anyway you can cut and spread out the burst of characters sent to the RS232? That way you can catch the CCP1 interrupt in between and not spenf too much time in the the RS232 interrupt.
_________________
-Matt
Ttelmah
Guest







PostPosted: Mon Feb 06, 2006 3:28 pm     Reply with quote

So, have you tried using the HIGH keyword with the INT_CCP?. How old is your compiler (this is critical - on some versions, you will need #device HIGH_INTS=true, and on older versions, the high priority interrupts do not save the registers)?.

Best Wishes
Tagge



Joined: 23 Aug 2005
Posts: 93

View user's profile Send private message Visit poster's website

PostPosted: Tue Feb 07, 2006 3:24 am     Reply with quote

Hi again,
i got the 3.242 compiler I think its the newest one.
I now tryed to insert the #int_xxx HIGH, and it did ask for the
#device HIGH_INTS=true, wich I then also implemented.
Don't I have to save any registers manually, really?
It seems to work alright, but I cant be sure until the box is tested by a third part. That is one of my problems, I cant test the functionallity by myself. Depending on that we dont have equipmemt for it. And this error of missing "times" did also appear after third part testing.
I tougt everything worked fine, but life is not only living its mostly learning...
Thanks to you all, I will be back with the results from testing.
Tagge



Joined: 23 Aug 2005
Posts: 93

View user's profile Send private message Visit poster's website

PostPosted: Wed Feb 08, 2006 5:32 am     Reply with quote

Hi again,
I think I have found at least one problem that makes the error of missing "times".
I have a printf() in my code, this will disable interrupts during it?
can I make it some other way? by "clean" putc(), and still remaine my bcc calkulation?
But on the other hand, thus it matter, printf is only activ during one char at the time? or is it disabling interrupts during the whole string?
Or should I rewrite the code to make an interruptdriven TX,
void serialtx_isr (void)?
Code:
 
void putcsum(int8 val)
{
   bcc^=val;   //xor on every byte
   putc(val);   //write string
}
//------------------------------------------------------------
putc(0x02);                 //stx, startbit text
   printf(putcsum, "F.F(00)\r\nC.1.0(%s)\r\n0.0(%lu)\r\n1.8.1(%09.1f*kWh)\r\n1.8.2(%09.1f*kWh)\r\n32.7(%lu*V)\r\C.5.0(00)%C%C%C%C",
   METER_NO,CUST_NO,energy_A,energy_A2,voltage,0x21,0x0d,0x0a,0x03);

   putc(bcc);                  //as last, print checksum of above printf()

Ttelmah
Guest







PostPosted: Wed Feb 08, 2006 8:21 am     Reply with quote

Printf, should not disable interrupts, _unless_ you are using any of the functions it calls_, inside an interrupt. So if 'putcsum' is used in an interrupt, then interrupts will be disabled.
This is a general problem. Basically, any function used inside an interrupt, _will_ cause interrupts to be disabled, if it is also used outside the interrupt. There are a couple of other things that will also disable interrupts. Certain types of memory movement (table based memcpy routines), and writes to the program memory. Now printf, can be made to disable interrupts with certain operations, but your example does not look like it would trigger these, unless putcsum is the culprit.
There was a longish thread a few weeks ago, about which operations would disable interrupts. This may help.

Best Wishes
Tagge



Joined: 23 Aug 2005
Posts: 93

View user's profile Send private message Visit poster's website

PostPosted: Wed Feb 08, 2006 8:37 am     Reply with quote

I think I read it, and there was someone who claimed that a printf does disable interrupts, thats why I asked.
None of the functions it calls are inside any isr. But it seems that I get a better stability by using an isr driven TX. Altough I havent implemented all the way yet.
For some reason I only get about half (1'st) of the string out of this, maybe due to that I have an CCP1 isr set as #int_ccp1 HIGH.
It seems that what one gains at one side, makes you loose at the other...

Code:

#int_tbe
void serial_tx_isr()
{
      //if there are characters to be transmitted....
      if(TX_Counter != 0)
      {
         putc(TX_Buffer[TX_Rd_Index]);
         // send char out port

         // test and wrap the pointer
         if(++TX_Rd_Index > TX_BUFFER_SIZE)
            TX_Rd_Index = 0;

        TX_Counter--;   // keep track of the counter
        if (TX_Counter == 0)
             disable_interrupts(int_tbe);
      }
}
// write a character to the serial transmit buffer
void bputc(INT8 c)
{
    INT8 restart = 0;

    while(TX_Counter > (TX_BUFFER_SIZE-1))
         ;       // WAIT!! Buffer is getting full!!

    if(TX_Counter == 0) // if buffer empty, setup for interrupt
       restart = 1;

    TX_Buffer[TX_Wr_Index++]=c; // jam the char in the buffer..

    if(TX_Wr_Index > TX_BUFFER_SIZE)     // wrap the pointer
        TX_Wr_Index = 0;
                            // keep track of buffered chars
    TX_Counter++;

    // do we have to "Prime the pump"?
    if(restart == 1)
        enable_interrupts(int_tbe);
}

//and in subroutines
void putcsum(int8 val)
{   
   bcc^=val;   //xor på varje byte
   bputc(val);  //skriv ut sträng   
}
void putmsg(int8 chr)

   bputc(chr); 
}
//------------------------------------------------
...
bputc(0x02);                 //stx, startbit text
   printf(putcsum, "F.F(00)\r\nC.1.0(%s)\r\n0.0(%lu)\r\n1.8.1(%09.1f*kWh)\r\n1.8.2(%09.1f*kWh)\r\n32.7(%lu*V)\r\C.5.0(00)%C%C%C%C",
   METER_NO,CUST_NO,energy_A,energy_A2,voltage,0x21,0x0d,0x0a,0x03);

   bputc(bcc);                  //as last, print checksum of above string

Do I gaine anything from this?
Ttelmah
Guest







PostPosted: Wed Feb 08, 2006 10:34 am     Reply with quote

Do you have 'ERRORS' enabled in the RS232 setup?.
If not, and the receive routine is not called often enough, so there is a hardware buffer overrun, the UART will effectively lockup.
Printf, will disable interrupts for the accesses to the constant string. The thread about this (and other similar problems), is entitled:
"How to prevent inbuilt functions to disable interrupts".
There was a workaround in this for the printf behaviour.
Generally the advantage of interrupt drive transmit, is that if (as you mention), you are doing things like maths in the main code loop, the processor can get on with this while the data is sending. Otherwise there will be long gaps in the time available for such things...

Best Wishes
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