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

RB0 / EXT interrupt blocked by various functions

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



Joined: 25 Jul 2006
Posts: 6

View user's profile Send private message

RB0 / EXT interrupt blocked by various functions
PostPosted: Wed Jun 20, 2007 6:53 pm     Reply with quote

My system is: 18F4620, 20 MHz, CCS PCWH 3.249.

Code:
ROM used: 27832 bytes (42%)
          Largest free fragment is 37704
RAM used: 397 (10%) at main() level
          483 (12%) worst case
Stack:    21 worst case (13 in main + 8 for interrupts)

I use a 60 Hz power line zero cross interrupt on RB0 for 120 events / second. I have less frequent interrupts on EXT1 and EXT2. I also use TIMER1 and TIMER2 interrupts.

Timing measurements on a scope show that the interrupt routines are fairly short.

When the system is otherwise "idle" the interrupt timing works as expected. As more activity is performed, the jitter on the interrupt response increases, up to perhaps 30% of the 1/120 s interrupt period. This much occurs 1 or 2 times per second. The system being run can handle perhaps 5% jitter.

After searching on this forum I found hints to similar situations here:
http://www.ccsinfo.com/forum/viewtopic.php?t=29105
http://www.ccsinfo.com/forum/viewtopic.php?t=25535

which clued me in to look for "BCF FF2.7" which clears the GIE bit in the INTCON register.

A search through my listing reveals around 170 instances of GIE being cleared before some operations. The operations that result in this process seem to include "putc()", "read_eeprom()", "spi_read()", "delay_X()", '*', '/', and perhaps others.

There may be things I can do to alleviate some situations, but I would rather remove the clearing of GIE. The other operations don't need fast response. I have a lot of RAM left over, so stack issues should not be a problem.

Questions:
1) Can I disable the compiler from clearing GIE?
2) If I rewrite the suspect functions so they don't clear GIE, what problems can I expect?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 20, 2007 7:02 pm     Reply with quote

Quote:

A search through my listing reveals around 170 instances of GIE being
cleared before some operations. The operations that result in this
process seem to include "putc()", "read_eeprom()", "spi_read
()", "delay_X()", '*', '/', and perhaps others.

How many of these functions are you calling from inside interrupt
service routines ?
peter_dufault



Joined: 25 Jul 2006
Posts: 6

View user's profile Send private message

PostPosted: Wed Jun 20, 2007 9:43 pm     Reply with quote

Quote:
How many of these functions are you calling from inside interrupt
service routines ?

#INT_RDA: None
#INT_EXT1: None
#INT_EXT2: None
#INT_TIMER1: None
#INT_TIMER2: None

and then...
#INT_EXT: "putc()", "read_eeprom()", "spi_read()", "delay_X()", '*', '/', ...

I think I see what might be going on. Note that the jitter delay happens before the interrupt. Even though the execution time of the interrupt is fairly short, because those routines are not inline and because it's possible to be called from within the interrupt routine, it seems that the compiler will insert the "BCF INTCON, GIE" for all conditions, whether inside or outside the interrupt routine.

I did take into account the interrupt execution time. The individual cycles are split into a number of time slices that execute only a bit at a time; it never goes through everything in one pass. Some parts of the ISR are executed in only some conditions as well. I should be able to push some out of the interrupt handler. I will try it out tomorrow. I foresee many flags a flappin'.

Does my explanation seem reasonable?
Ttelmah
Guest







PostPosted: Thu Jun 21, 2007 2:49 am     Reply with quote

What is happening, has been explained many times in the past.
The PIC, does not have a 'value' stack. As such, storage used inside routines, is the same in all copies of the routine. Hence to prevent 'reentrancy', if a routine is used inside an interrupt, and also used outside an interrupt,then interrupts _must_ be disabled whenever the routine is called. The same also applies to anything using 'hardware' flags for operations.
There are ways round parts of this. You can force the compiler to develop two copies of the 'delay' routines (basically you have one #use delay statement, declare the interrupt routines, and then have another #use delay statement). This has been documented here in the past.
For SPI_READ, you might just want to leave interrupts being disabled. You could code this yourself (it is only a matter of reading the SPI data register), but what happens if in the main code, the SPI_READ routine, checks the flag to see if data is waiting, sees that it is, and goes to read the data, then at that moment the interrupt occurs?. The code will arrive to read the data with the data already having been read.
The same applies to putc, and read_eeprom. In the former, the 'main' code, sees the flag to say that there is space in the transmit buffer, goes to write the data, and in between whiles, there has been an interrupt, and the buffer has been filled. Similarly, for read_eeprom, all the registers are setup to read the required byte, and then the code interrupts, and changes the byte addressed...
Most of the routines involved are fast. The main one that is probably causing problems, is the use of delays, which can be easily fixed as outlined above. The other that might (depending on how long the strings involved are), is the 'putc'. Consider not using putc. Instead use the code in the examples directory, for an interrupt driven RS232 transmit routine. Then sending characters, is just a matter of adding them to the much larger software transmit buffer. Though interrupts will be disabled during the write to this, this takes only a few uSec, against the time needed to actually 'send' the data.

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