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

Enable interrupt during call - 216

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



Joined: 18 Jun 2014
Posts: 13

View user's profile Send private message

Enable interrupt during call - 216
PostPosted: Wed Jun 18, 2014 1:23 pm     Reply with quote

So I have been attempting to find a simple answer to my problem to no avail. I am using Timer2 as a timer to measure a specified time with relative accuracy. My problem is that I am also running a graphical LCD and I have some other operations which all disable interrupts. I get a Warning 216 - Interrupts disabled during call to prevent re-entrancy. The problem is that these different operations increase the time that it takes to run through the main loop, thus changing my interrupt timing. My interrupt is the following:

Code:
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
setup_timer_2(T2_DIV_BY_16,250,10);          // 2.5 ms interrupt

#INT_TIMER2
void TIMER2_interrupt(void)  // 2.5 ms @ 64 MHz
   {
   if (sleep_timer>0)
      sleep_timer--;
   }

I would really like to enable the Timer 2 interrupt all of the time regardless of what is trying to prevent its call. I am okay with all of my other interrupts being disabled. I would actually prefer them to be disabled during the calls. Is there a simple way to always enable the Timer 2 interrupt? Or rather never allow it to be disabled?

I can see that the LST file shows 17 lines of assembly code because the variable 'sleep_timer' is an int32.

I am running V5.014 CCS compiler. I am using a PIC18F65K22. Clock speed is internally running at 64 MHz.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 18, 2014 2:42 pm     Reply with quote

Look at the #int_xxxx section of the CCS compiler manual. Look at the
keyword 'HIGH', and the directive: #device HIGH_INTS=TRUE
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf

Also, be aware that if you access (r/w) 'sleep_timer' in your main code,
you will need to disable interrupts while doing this. That's because
sleep_timer consists of 4 bytes, and this means several lines of ASM
code are needed to read or write to it. Your #int_timer2 routine could
interrupt the main code while the main code is reading 'sleep_timer' and
change some of the bytes in mid-read. This could result in erratic
program behavior. Example of what is needed:

Code:

void main(void)
{
int32 temp;

disable_interrupts(INT_TIMER2);
temp = sleep_timer;
enable_interrupts(INT_TIMER2);

AdamWebber



Joined: 18 Jun 2014
Posts: 13

View user's profile Send private message

PostPosted: Wed Jun 18, 2014 3:12 pm     Reply with quote

I tried the #INT_TIMER2 HIGH with the #device HIGH_INTS=TRUE definition and it did not help the timing. From reading the structure, it will interrupt other interrupts in progress but it will not interrupt if it has been disabled due to 216 warning.

Thanks for the prompt reply though.

Just to let you know, those two commands that I installed took 8% of the chip's resources.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Jun 18, 2014 4:00 pm     Reply with quote

Radical rethink called for.
At this stage you are not revealing enough to work on.

Mike
AdamWebber



Joined: 18 Jun 2014
Posts: 13

View user's profile Send private message

PostPosted: Wed Jun 18, 2014 6:22 pm     Reply with quote

I am developing a product that utilizes the PIC18F65K22. I have three buttons connected to external interrupts that are active low. I have a graphical LCD which writes through I2C using software, not hardware ports. I use a 32 bit integer that decrements every 2.5ms on Timer 2 interrupt. When the integer reaches 0, I put the device to sleep. The only thing in Timer 2 is the above routine. That is pretty much the whole structure. So when I write to the graphical LCD, it disables all interrupts, including the Timer 2 interrupt. Since the LCD is written to using software I2C, I'm not concerned about interrupting the transfer of data because the interrupted I2C clock signal will still be stable for the 1.06 us that it takes to interrupt Timer 2 and decrement the number. So I would like to know how I can prevent Timer 2 from being disabled while data is being transferred to my LCD. I hope that this is clear enough. This is general enough that you shouldn't need much more information but if there is something specific that is required, I will be happy to inform you of whatever you need.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 18, 2014 7:28 pm     Reply with quote

There is nothing in the #int_timer2 routine that will cause a Warning 216
message. It doesn't use any CCS library functions to test or decrement
the int32 sleep_timer variable.

So the code that causes that warning must be in your other interrupt
routines. You are calling a CCS library function (or one of your own
functions) in the interrupt and you are also calling it in main() or some
other place that is outside the interrupt routine. That's what causes the
216 warning. What shared functions are you calling ?


Also, it doesn't take 1.06 usec to process the interrupt at 64 MHz.
Based on a quick instruction count, by looking at the .LST file, it's more
like about 4 usec. There is substantial overhead to save and restore
the state of the machine.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Thu Jun 19, 2014 2:12 am     Reply with quote

To amplify what PCM wrote: you get a "Warning 216 - Interrupts disabled during call to prevent re-entrancy" when any routine - even "hidden" ones embedded in compiler related code such as for floating point math and longer delays - is used both in main code and any interrupt handler. The compiler is warning that its interrupt locked the relevant calls in mainline code.

The compiler is not clever enough to be able to decide which interrupt sources are affected by this, and so it disables interrupts globally.

The right way to solve this is to change the code so that disabling is not needed rather than to force interrupts back on - the disabling is there for a reason.

The general way to avoid this is to find where such routines are called in ISRs and change them to avoid using the relevant routines.

In some cases, especially where its your own routines that are called, you can make separate versions for interrupt and mainline use. With implicit calls made by compiler generated code, code reorganisation, such as moving offending code to the mainline, can help.

As your timer2 routine doesn't seem to use any routines (assuming the 32 bit comparison and decrement are not implemented by calls) it must be that some other ISR, which you haven't shown us, does. A common candidate is delay_ms() which for more than a couple/few ms will repeatedly call a routine that delays for 1ms. Also floating point maths calls routines, err..., routinely. Serial IO is another candidate, printfs in ISRs will almost certainly cause it if there is any serial IO in mainline code, even if its not printf (because printf and the like are implemented by calls to other lower level routines).

Of course, all three, long delays, serial IO - and other IO, but serial is generally the worst and most commonly seen - and floating point are bad news in ISRs due to how long they take.

The only code that I've got that has to do this disabling is Modbus RTU stuff, as the CRC code is used in both sending (mainline) and receiving (ISR). For everything else, I regard it as a problem I should solve.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Thu Jun 19, 2014 2:28 am     Reply with quote

You appear to have two problems here.

1) The 216 warning.
2) Timer2 interrupt being disabled by other interrupts.

The 216 warning has been discussed at length.

Your PIC has interrupts at two levels.
You should be able to make Timer2 the only high level interrupt.
End of.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Thu Jun 19, 2014 12:53 pm     Reply with quote

Remember that the standard 'INT 0' interrupt (INT_EXT), doesn't have a 'priority' bit. So if he is using this, it'll be set as a high priority interrupt automatically. Might be one problem.

Other thing that would cause problems, is functions called inside the interrupts and also in the 'main' code, which would give the 'interrupts disabled' warning, which would then interfere with the timings.
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