8
\$\begingroup\$

Wherever I have searched about the practical implementation of the level-based interrupt, I have found only one suggestion that people have given i.e disable the interrupt as soon as it enters the ISR so it doesn't keep triggering back.

Another thing I have read is that it is used to create a loop i.e as long as interrupt is there, serve the ISR, but that could be achieved with a while or do while loop.

And the advantages a level edge interrupt would provide might be the luxury to run one instruction of the main programme in between serving the ISRs and the latency. I guess.

So is there something I am missing when it comes to understanding the level edge interrupt?

A great answer would be to show me some sort of practical usage of level-based interrupts.

\$\endgroup\$
  • \$\begingroup\$ ...Other thing I have read is that it is used to create a loop i.e as long as interrupt is there, serve the ISR but that could be achieved with a while or do while loop.... The fact some thing can be achieved one way, doesn't mean we should eliminate all of the other ways of doing the same. \$\endgroup\$ – Eugene Sh. May 16 '17 at 16:08
  • \$\begingroup\$ @EugeneSh. No doubt about it, but there must be some solid advantage to do the same thing in the other way. Isn't it? I am more interested in knowing that "advantage". I just want to know what sort of difference it makes in looping using loop statements and level based interrupt? If looping is the only purpose achieved using it. \$\endgroup\$ – MaNyYaCk May 16 '17 at 16:15
  • 2
    \$\begingroup\$ what if you have multiple interrupt pending on one line? e.g. each trigger of ISR handles one packet of data but the device have multiple in the queue? With edge triggered interrupt, the interrupt controller needs to know when the previous interrupt is handled and when is time to submit the next interrupt. Also for use cases where multiple interrupt is asserted when the host is still handling a previous one, without level triggering it's hard to queue and prioritize them. \$\endgroup\$ – user3528438 May 16 '17 at 16:21
10
\$\begingroup\$

Level-based interrupts can safely be shared and cascaded easily and reliably; by contrast, reliably sharing edge-triggered interrupts is often difficult and sometimes impossible.

When using level-based interrupts, an interrupt handler can simply ask each possible interrupt source in turn "Do you need attention", and service it if so. Once it's done, the handler can return. If an interrupt source which was polled early in the sequence decides it needs attention while a later source is being serviced, the processor will notice that the IRQ pin is still active and re-trigger the interrupt handler, thus allowing the late-arriving interrupt to be serviced.

When using non-cascaded edge-triggered interrupts, things get more complicated. After an interrupt handler has gone through and serviced everyone, it must then go through and re-poll everyone to find out if a previously-polled device has decided that it needs service. Only after every device has consecutively reported that it does not need service would it be safe for the interrupt to return. Note that if devices that want service keep their "need service" indication active, returning from an interrupt handler at a time when a device needs service may render that interrupt permanently useless.

It may be useful for an I/O pin to have some edge-capture logic which, when an edge arrives, sets a latch and outputs a "need-service" indication until software clears it. Such a thing might appear on the very front end as an edge-sensitive interrupt. At any downstream point, however, it's better to have interrupt logic demand that an interrupt be serviced at all times when any upstream point is not satisfied.

\$\endgroup\$
  • \$\begingroup\$ I would like to apologize to take so much time. But the question that I asked was very specific to the External Interrupts of the controller, and it took me certain time to understand all the answers that poured in came considering the processor with an interrupt controller. Thanks for providing this valuable answer. \$\endgroup\$ – MaNyYaCk Jul 15 '17 at 16:22
6
\$\begingroup\$

One obvious situation where level based interrupts are useful is for the situation where the signal is already in that state when the code begins to monitor the signal.

Let's consider a typical example ...

Signal: "Case_Over_Temperature" Goes low when the ambient in the box is too high for normal operation..

Obviously, this signal could go low at any time, either because we are making too much heat, or because the box is installed in a hot location.

Obviously, on power up that line could be in either condition. Let's assume for the moment that the power-on code doesn't just go look but relies on the interrupt instead. If the interrupt is edge triggered and the signal is already low, when the interrupt gets enabled the appropriate code will not be executed. Level sensitive interrupts would be prudent here.

Similarly, if the processor is put to sleep and is not set to wake on that interrupt, that line can go low at any time. When whatever else wakes it up happens, you want the interrupt to fire at that time.

Indeed, arguably, with the prevalence of sleep mode processors, level based interrupts have become more useful.

However, as with all things code related, there is always more than one way to "skin a cat". If you don't use level based, the wakeup code needs to go poll the interrupt pins if they are not automatically queued by the processor.

Obviously, level triggered also comes with it's own set of issues in that the code has to handle knowing that it has already handled the condition etc.

\$\endgroup\$
2
\$\begingroup\$

It's somewhat the other way around: why have awkward edge-triggered interrupts when you can have the easier level-triggered?

Edge triggered interrupts are more susceptible to noise spikes and harder to filter. They're then riskier to run off-board or up cables. The interrupt can't be withdrawn by the source.

Level-triggered interrupts stay on until the CPU acknowledges the source. So there's the solid base of full handshaking. The CPU can filter noise out of the interrupt signal in almost any way it wants, it's just increasing the interrupt response time. If the application requires and allows for well-filtered signals, level triggering is adaptable.

I first saw edge-triggered interrupts used for NMIs on CPUs like the Z80 and 6502, while maskable interrupts used level triggered. The NMIs used edge-triggered simply to stop a stuck pin or stuck driving circuit from keeping the CPU re-entering the NMI ISR forever. The NMI must show activity to get another one.

The answer, of course, is that they both have their applications. But level-triggered is the starting point and edge-triggered gone to because there's a special case.

\$\endgroup\$
  • 1
    \$\begingroup\$ I wouldn't say the Z80 and 6502 used edge-triggered interrupts to avoid issues of "stuck" pins. Instead, I'd say that they need to be able to mask any kind of interrupt once servicing has begun, and for NMI that is accomplished via special "mask NMI" latch which gets set when an NMI is serviced, and is cleared when the NMI pin is released. \$\endgroup\$ – supercat May 16 '17 at 21:54
  • \$\begingroup\$ @supercat, you've described how you see it but not how Z80/6502 work. The NMI could have been level, same as INT/IRQ with interrupt source removed by hw or sw interrupt acknowledge. Works perfectly well. What d'you think made them design NMI as edge-triggered and INT/IRQ as level, what do you see as the benefit? \$\endgroup\$ – TonyM May 17 '17 at 6:36
  • \$\begingroup\$ The term "edge triggered" is used to describe inputs which place an edge-detect circuit before a synchronizer, so that a signal that comes and goes all within a single cycle will get processed, but I've also seen it used to describe inputs which latch a signal on each clock signal and look for a signal to be absent on one or more cycles and then present for one or more cycles. If the NMI had to be acknowledged by software, failure to acknowledge the first interrupt would effectively mask all subsequent ones. \$\endgroup\$ – supercat May 17 '17 at 14:34
  • \$\begingroup\$ @supercat, that's not how Z80/6502 work and they alone were the subject of my example you questioned. If you're after a discussion on edge-triggered NMIs, please go to chat to avoid an extended comment exchange. Not sure what I can add, though. Thanks. \$\endgroup\$ – TonyM May 17 '17 at 14:38
  • \$\begingroup\$ I haven't looked at the details of how the Z80 works, but according to the 6502 data sheet NMI is sampled once on each phi2 clock. The data sheet is silent about sample/hold times, but from what I've read elsewhere an NMI pulses which isn't present during at least three consecutive samples will not always be processed. \$\endgroup\$ – supercat May 17 '17 at 16:25
1
\$\begingroup\$

Level based ISR's support Ack/Nak which is useful when you have many sources.

If you have many ISR's and many priority ranks in both SW & external HW with ranked priorities.

If all sources were edge OR'd you would still have to poll each to find which source set and then clear the interrupt.

So both edge and level have advantages in different architectures.

To avoid missing an Edge IRQ, it has to be enabled then tested immediately after at the end of the ISR.

Some level IRQ's can last long than the ISR and detected if expected.

\$\endgroup\$
1
\$\begingroup\$

It is when a "party line" is being used, together with open-drain or open-collector, when the level mode of operation makes more sense.

In this case, each "party" on the line activates their output when they need "service." As the interrupt handling software goes out and polls (and then handles) each device on the party line in turn, these devices release their hold and go inactive. Eventually, there are no more (level) interrupts remaining, the interrupt line itself goes inactive, and the software handling interrupts goes "quiescent" again.

\$\endgroup\$
  • 1
    \$\begingroup\$ it does matter. what if the host receives another edge on another line when it is already handling a interrupt? a few choices: 1) ignore the incoming interrupt; 2) queue it in the hardware; 3) interrupt the current interrupt handler and handle the new one, either handle it completely or queue it for later. With level trigger you just leave it there and it will still be there for you to handle after you are done with the current ISR. \$\endgroup\$ – user3528438 May 16 '17 at 16:29
  • \$\begingroup\$ @user3528438 I'm addressing the question about "why level." So I'll just remove that part and avoid debate. \$\endgroup\$ – jonk May 16 '17 at 16:30
  • 1
    \$\begingroup\$ Even when using dedicated interrupts, I'd suggest that edge-triggered interrupts are only better if one may be interested in responding to an event that may have come and gone by the time one can service it, and even there using an event-latching device to drive a level-sensitive interrupt may be just as useful as using a edge-sensitive interrupt. An edge-triggered interrupt might save an instruction that would otherwise be needed to clear the latch, but that's generally not a meaningful cost or savings. \$\endgroup\$ – supercat May 16 '17 at 16:32
  • \$\begingroup\$ @supercat I've re-focused my answer to directly answer the titled question, so as to avoid engaging in some long, sordid chapter and verse. Much simpler. (Yes, I've been using all manner of interrupt methods since... 1974... so I've seen all the reasons, I think. I just don't want to discuss them today.) \$\endgroup\$ – jonk May 16 '17 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.