SOLVED: Interrupt queuing

I've searched for this, but cannot find a definative answer.

Say for example, a rising interrupt is used to increment a counter, if in the loop of a code the interrupt is detached to prevent another interrupt disrupting a calculation, then reattached - what happens if that interrupt pin goes high during the period it is detached?

When it becomes reattached, is there a 'pending' or 'queued' interrupt that is then serviced? If not, is there any way to do this?

Yes, the interrupts are queued. But, only one of each kind. If there is more than one of a given kind, the extra(s) are ignored.

Say for example, a rising interrupt is used to increment a counter, if in the loop of a code the interrupt is detached to prevent another interrupt disrupting a calculation, then reattached - what happens if that interrupt pin goes high during the period it is detached?

The event is lost. There's no per-event queueing.

If not, is there any way to do this?

Write your interrupt handler(s) to be as small & fast as possible so these conditions won't occur. Set flags, push entries on a private stack or make entries in an array, etc. inside the interrupt handler to log the event, then have the main loop process the events as it can.

Good luck!

A number of libraries make a point of clearing pending interrupt flags before they start, attachInterrupt probably does this which is what might be causing your confusion.

You do not need to attach/detach the interrupt, you can simply disable interrupts temporarily. Any interrupts which happen while disabled will be held in a pending state and processed when interrupts are re enabled, this is standard practice for accessing shared variables etc.

loop()
{
..
..
..
nointerrupts(); // disable interrupts while we do something sensitive like access a shared variable which is also accessed in the interrupt
..
..
..
interrupts(); // reenable interrupts, any that occured between nointerrupts and now, will be serviced now.
..
..
}

Duane B

rcarduino.blogspot.com

Thanks very much, I will use the interrupts(); method. However, will there indeed only be 1 queued interrupt allowed, or more? There seems to be conflicting replies.

PaulS: Yes, the interrupts are queued. But, only one of each kind. If there is more than one of a given kind, the extra(s) are ignored.

DuaneB: You do not need to attach/detach the interrupt, you can simply disable interrupts temporarily. Any interrupts which happen while disabled will be held in a pending state and processed when interrupts are re enabled, this is standard practice for accessing shared variables etc.

When it becomes reattached, is there a 'pending' or 'queued' interrupt that is then serviced?

Normally, no. attachInterrupt has (had?) a bug that works the way you've described.

jtw11: Thanks very much, I will use the interrupts(); method. However, will there indeed only be 1 queued interrupt allowed, or more?

[u]Each interrupt source[/u] has a queue depth of one. (Except in one reasonable case where the depth is zero.)

[quote author=Coding Badly link=topic=129917.msg977265#msg977265 date=1351620759] [u]Each interrupt source[/u] has a queue depth of one. (Except in one reasonable case where the depth is zero.)

[/quote]

Interrupt source being that specific interrupt pin?

Not exactly. For a given pin, there could be several interrupt sources. All pins support "pin change" interrupts; that is one source. A few pins support "external interrupts"; that is another source. (attachInterrupt uses "external interrupts")

I see, so if there were two external interrupts, only one queue event would be logged even though there are 2 requesting a log (if for example, they were)?

Also, what is a pin change interrupt? Is that adding another interrupt pin using the PinChangeInt library?

jtw11:
I see, so if there were two external interrupts, only one queue event would be logged even though there are 2 requesting a log (if for example, they were)?

No. Each is a separate source.

Also, what is a pin change interrupt?

It’s similar to CHANGE available for external interrupts (attachInterrupt( pin, CHANGE );).

Is that adding another interrupt pin using the PinChangeInt library?

Yes. But only for CHANGE. LOW, RISING, and FALLING are not available (but can be simulated and are simulated in one of the pin-change interrupt libraries).

I see - once again, many thanks for all the quick replies.