Delay in Interrupt Service Routing.

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I have a hardware/external interrupt which calls an ISR with a delay inside.

My question is what will happen if the condition/flag of the interrupt is set whilst the previous delay is still running in the ISR.

Will the uC ignore that interrupt and continue to complete current?
will the current ISR be left immediately to start the new ISR?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It depends how do you want it to work.

Normally the CPU clears the global interrupt flag when entering an interrupt so the current interrupt runs and the next interrupt is run after it.

But if you enable global interrupts inside your ISR, it will start new ISR during execution of current ISR.

Your C compiler (if you even use C) might want to do things differently by default.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

My question is what will happen if the condition/flag of the interrupt is set whilst the previous delay is still running in the ISR.

Adding to Jepael's comments:

If this happens you might have to be extra careful with how the ISR accesses global (statically allocated) variables.

If this happens at an overall rate that makes the ISR "incarnations" never catch up you have an "interrupt overrun situation", i.e. you are missing events.

I am slightly curious as to why you need a delay in an ISR. I would suspect that there would be a safer/more elegant solution for most problems at hand.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Quote:

My question is what will happen if the condition/flag of the interrupt is set whilst the previous delay is still running in the ISR.

Adding to Jepael's comments:

If this happens you might have to be extra careful with how the ISR accesses global (statically allocated) variables.

If this happens at an overall rate that makes the ISR "incarnations" never catch up you have an "interrupt overrun situation", i.e. you are missing events.

I am slightly curious as to why you need a delay in an ISR. I would suspect that there would be a safer/more elegant solution for most problems at hand.

There certainly is.

I am having some strange results and I think it has something to do with the interrupts.

If i don't set global interrupts, the interrupts will wait for previous ISR to complete before starting I assume, Is this correct?

When global interrupts have been set interrupts can interrupt each other?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well what is it that you are doing?

But yes, you are correct how the global interrupt flag works. If they are enabled then they are executed, and if disabled then they wait until enabled so they are executed later.

When returning from an interrupt, the global interrupt flag is restored so they are globally enabled after the interrupt.

If you keep then disabled, then no other interrupt is able to execute. You could disable only the interrupt that is executing and then enable other interrupts globally if you wanted, so other interrupts can happen during your long delay.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

which calls an ISR with a delay inside.

This is not great design. Put any delays you need in the main() code then just have the ISR()s set flags that the main() code later acts upon. An ISR should complete in 50-100 cycles or even less if possible for the very reason that it blocks main() and other ISR()s (including itself) while it executes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
just have the ISR()s set flags that the main() code later acts upon

This sounds like a good idea, but:
The hardware usually already sets a flag to signal there is an IRQ awaiting service, so usually there is no need for an ISR to get a flag set.

Having a delay inside an ISR is generally not a good idea, if it is longer than a few cycles. If the delay is longer it can be worth starting a timer to do the rest in a timer ISR. Two short ISRs are usually less trouble than one long one.

At least GCC is not very efficient with the ISR header code. ASM can save on this, by reserving some registers for ISR only usage and not saving Zero-reg unless really needed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kleinstein wrote:
Quote:
just have the ISR()s set flags that the main() code later acts upon

This sounds like a good idea, but:
The hardware usually already sets a flag to signal there is an IRQ awaiting service, so usually there is no need for an ISR to get a flag set.

I have to disagree here (and I think most others would also disagree).

In the first place, main code will never see that hardware flag since it will be cleared by or via the ISR.

In any case, most interrupt-driven activity naturally breaks down into a smaller gotta-do-it-right-now part, and a larger handle-this-later part (which may not need to happen every interrupt). That's where the flag set in the ISR comes into play. You take care of the immediate need, then free up the processor to respond to other interrupts while handling the rest of the processing as soon as time allows.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
In the first place, main code will never see that hardware flag since it will be cleared by or via the ISR.
Not if you don't enable the ISR.

Regards,
Steve A.

The Board helps those that help themselves.