1
votes

First time poster here, let me know if this should be posted elsewhere. Please be kind :p.

This question came to me on a hike, and I couldn't find exactly what I was looking for afterwards.

Suppose I have an ISR for an event. Normally, the event will fire the interrupt, the ISR will run, and then we'll continue on our merry way.

Suppose now I have some shared variables, and as a super simple fix, I globally disable interrupts during the critical section. If the event occurs during this critical section, does the ISR execute after I re-enable interrupts or is that event never handled?

Furthermore, what would happen if an event was to occur inside the ISR, after the interrupt flag has been cleared but before the ISR finishes? If it happens multiple times, does only the first one that occurred within the ISR get handled?

Appreciate all answers. Typically I keep my ISRs short enough that this hasn't happened yet.

Thanks!

1

1 Answers

3
votes

Since you are not specific about a particular processor or interrupt controller the following is generally true. For specific implementations you would have to consult the reference material for the specific hardware.

When an interrupt occurs whilst interrupts are disabled, an "interrupt pending" flag will be set, and if that flag is not explicitly cleared beforehand the interrupt will be invoked as soon a interrupts are reenabled.

Furthermore, what would happen if an event was to occur inside the ISR, after the interrupt flag has been cleared but before the ISR finishes?

Assuming the interrupt controller automatically disables the active interrupt, the interrupt will again become pending, and the ISR will be-invoked as soon as it completes. The pending flag is not a counting object, so if multiple events occur after the pending flag is set, that cannot cause the ISR to run for each event.

If your ISR does not complete before the likelihood of a another event, then either you have one or more of the following:

  1. an inappropriately long ISR execution time,
  2. too slow a processor for the application,
  3. too high an expectation of the processor performance,
  4. a poor design.

An ISR should be both short and deterministic (i.e. it should have constant, or at least bounded execution time). Generally it should be used to signal some less constrained process to do the slower and less deterministic processing, using buffering or event counting (message queues or counting semaphores for example in an RTOS) to cope with the mismatch in determinism.

An example of where you might get an interrupt rate that the processor cannot cope with is in signal processing where an ADC may be capable of very high sample rates and of generating one interrupt per sample. In such circumstances using the ADC interrupt might not be practical - any sample rate higher then a 1KHz say, but depending on the processor performance and what other work must be done in the available CPU cycles. In that case one solution is to use DMA transfer where the DMA controller is signalled on sample completion and transfers the sample directly to memory. It can be configured to do this for multiple samples before generating an single interrupt for an entire block of samples. Processing a block of samples in one go generally has significantly lower overhead than processing one sample at a time in an interrupt.