What happens when  ISR execution time is longer than interrupt occurs  - Page 1
Forum section: electronics / general

author: Mtech1
author_rank: Contributor
timestamp: October 07, 2023, 11:20:46 am
content: Could anyone please explain when the execution time of the ISR (Interrupt Service Routine) exceeds the timer interval (e.g., the ISR taking 1.5 ms while the timer is set for 1 ms intervals), what are the consequences? Does the ISR continue uninterrupted while the subsequent interrupt gets delayed, or does the ISR not complete, and does the subsequent interrupt occur before it's finished?I think ISR won't finish and will be interrupted by the next interrupt. I am asking for confirmation and more clarity

author: jpanhalt
author_rank: Super Contributor
timestamp: October 07, 2023, 11:33:09 am
content: Depends on the MCU. If there is only one level of interrupts, then you miss the interrupt, because interrupts are disabled. However, because the flag still gets set, you will get an interrupt immediately as you enable them, unless your clear the flag(s) before re-enabling them.

author: Kleinstein
author_rank: Super Contributor
timestamp: October 07, 2023, 11:36:29 am
content: It depends on the µC and type of interrupt. Often further interrupts are blocked until the ISR is finished - at least this is the default, but one may change this (e.g. enable interrupts early).If there are different interrupt priorities this usually still block interrupts of the same priority, but may allow higher priority interrupts to interrupt the ISR.In many case a lost interrupt request in buffered and the interrupt will than happen as soon as the CPU has time for it. Of cause this only works OK if this is more like a onece / rare problem (e.g. with different interrupt source colliding) and not the CPU just too slow to keep up.

author: Jeroen3
author_rank: Super Contributor
timestamp: October 07, 2023, 11:51:03 am
content: On ARMv6 the pending flag is set again and the interrupt will fire again immediately after it returned. If it fires a third time it will be lost. Sometimes there is an overrun bit for this, eg with UART and DMA.If this is a risk in your application because this is a real-time constraint you may want to check for this overrun state at the end of your ISR.Your application design decides if it's a problem or not. Using different priority levels of interrupts and using timers to trigger them is a cheap way of doing some multitasking without rtos.Some task overrun may not be a big problem if other higher priority interrupts preempt it.

author: Mtech1
author_rank: Contributor
timestamp: October 07, 2023, 12:02:34 pm
content: Take PIC16F877A and timer interrupt, for example

author: jpanhalt
author_rank: Super Contributor
timestamp: October 07, 2023, 12:09:43 pm
content: The interrupt timer and ISR can be viewed as two independent clocks running simultaneously; although, that is not necessarily the case. You can plot them out to see what might happen. Rather than just guessing at the variables, it would be more productive for you to describe what you want to accomplish and the MCU you are using.EDIT: Just saw your post. The 16F877A only has one level/priority of interrupt. What timer are you using for the interrupt?

author: woofy
author_rank: Frequent Contributor
timestamp: October 07, 2023, 12:16:03 pm
content: Quote from: Mtech1 on October 07, 2023, 12:02:34 pmDepends on your interrupt routine. TMR1IF, for example, has to be cleared in software,If you clear it immediately then it will be set again before your interrupt code has finished, you will execute 1 instruction from the base code before firing the interrupt again. Your base routine will run silly slow.If you clear it at the end, then you will have a bit more time in the base code before the interrupt fires again.In both cases you will miss interrupts.If this is actually happening then you need a redesign of the application. slow down the interrupts or better, don't do all that processing in the interrupt.If you really must do all that processing every mS, then you need a better processor.

author: ejeffrey
author_rank: Super Contributor
timestamp: October 07, 2023, 06:10:31 pm
content: There are a lot of variations on interrupt handling: edge vs level, vectored vs not, priority or not. But they all basically have to have a way to solve an important race condition: the isr finishes handling the peripheral, but then a new event happens before the ISR completes. You don't want to loose the interrupt as that could cause a situation where the peripheral is waiting for OS service but the interrupt is lost. So pretty much every platform has a way to track that an interrupt is pending while the ISR is executing and interrupts are blocked and trigger a new interrupt as soon as possible.So if you ISR takes longer than the interrupt interval it's going to lead to starvation of lower priority tasks.Also, the vast majority of interrupt handlers, at least those related to hardware peripherals are not reentrant. Even if an ISR re-enables interrupts globally, usually it will first block the particular interrupt it is handling.

author: jpanhalt
author_rank: Super Contributor
timestamp: October 07, 2023, 06:28:29 pm
content: Quote from: ejeffrey on October 07, 2023, 06:10:31 pmI don't believe the 16F877A does that. If the interrupt flag is set, it will immediately re-enter the iSR on exit. There is only one interrupt vector, and upon re-entry, if multiple events can trigger an interrupt, that source needs to be determined. If it is the same as before, then that routine gets repeated.

author: uer166
author_rank: Super Contributor
timestamp: October 07, 2023, 06:38:10 pm
content: Quote from: jpanhalt on October 07, 2023, 06:28:29 pmI think you're both saying the same thing: the ISR is not re-entrant which means that it can't be called while the ISR is executing, and will instead be called after it completes and exits. I.e. "it will immediately re-enter the ISR on exit", which is absolutely not re-entrant in the usual definition.

author: MikeK
author_rank: Super Contributor
timestamp: October 07, 2023, 07:40:58 pm
content: Quote from: uer166 on October 07, 2023, 06:38:10 pmThat PIC will disable interrupts as soon as it enters the interrupt routine. So, yes, the ISR won't be called again while inside the ISR.From the datasheet:Quote

author: jpanhalt
author_rank: Super Contributor
timestamp: October 07, 2023, 08:03:25 pm
content: @uer166It was this that probably confused me and maybe still does,QuoteI have never tried to enable GIE (global interrupt) while still executing routines in an interrupt. I suspect if one did that and an interrupt flag was set, it would execute the interrupt without reading/clearing the stack and get a stack overflow condition. Which is not unlike calling a subroutine within a subroutine. Obviously, you can do it, but you need to keep track of the returns.I might be wrong, and unfortunately, I cannot test it right now. With newer PIC's (e.g, 16F1xxx), one can read and write the stack, and with those, you can avoid the stack overflow problem. I have a routine named after the SciFi movie, "MIB." I have rarely used it (i.e., once) to execute a call without a return. When I get time, which won't be soon, I will test my opinion during an ISR with a 16F1829.In the meantime, it is probably irrelevant to the TS's problem.

author: MikeK
author_rank: Super Contributor
timestamp: October 07, 2023, 09:44:00 pm
content: Quote from: jpanhalt on October 07, 2023, 08:03:25 pmMicrochip just says "Don't do it!":https://onlinedocs.microchip.com/oxy/GUID-BB433107-FD4E-4D28-BB58-9D4A58955B1A-en-US-5/GUID-006D23D9-D5F3-4A18-97F9-98CB2C849CEC.htmlQuote

author: jpanhalt
author_rank: Super Contributor
timestamp: October 07, 2023, 11:35:51 pm
content: Of course, I wouldn't do that. That is, enable GIE within an interrupt. But the point I was addressing is the statement that even if you foolishly do that, there is a BLOCK from re-entering the interrupt. I agree, don't do it. But, I don't think there is a BLOCK from doing it, so long as you take care of the stack. Do it once, and there will probably be no problem, but the stack will still contain the original return address. That will/can eventually lead to stackoverflow, other strange behavior, and a reset.I write in Assembly, and can easily manipulate the stack. On occasion, that can be useful. To reiterate, I do not think re-entering an interrupt is actually BLOCKED on midlevel and enhanced midlevel PIC's once one has entered the ISR. RETFIE acts much like a macro for a specific type of return without adding inline code. So far as I know, nothing else.Why take this thread by an apparent new person off on a tangent? When I get time, I will try to demonstrate it in another thread and put a link here.

author: langwadt
author_rank: Super Contributor
timestamp: October 08, 2023, 12:12:46 am
content: Quote from: MikeK on October 07, 2023, 09:44:00 pmcan does not mean it will, classic ARM only had one interrupt line, so to get priorities/nesting/preemption the interrupt had to be reenabled (after adjusting the mask)

author: tggzzz
author_rank: Super Contributor
timestamp: October 08, 2023, 08:28:57 am
content: Quote from: Mtech1 on October 07, 2023, 11:20:46 amYour design fails, whatever happens.ISRs should be limited to grabbing the information from the interrupting peripheral (a few instructions), then placing that information in a queue.The background task repeatedly waits for something to arrive in the queue and processes it (as many instructions as necessary).

author: jpanhalt
author_rank: Super Contributor
timestamp: October 08, 2023, 10:46:08 am
content: Quote from: langwadt on October 08, 2023, 12:12:46 amI agree. In fact, after signing off yesterday and watching college football, I gave interrupts a little more thought.I began with PIC12F5xx chips that don't have interrupts. Then went to midrange 12F6xx and 16Fxxx, but didn't use interrupts for quite awhile. Finally, I took a bite of the forbidden fruit. Until Microchip added automatic context saving and restoration, one had to do that in code, which was almost always as part of the interrupt. RETFIE was simply return from interrupt and enable GIE. One could do the same with,Code:bsf INTCON,GIE ;enable global interruptsreturn ;clears the stackAs for interrupting an interrupt, those who used the very early mid-level chips can recall that disabling GIE was a problem with 3 and only 3 chips (16C71, 16C73, and 16C74).* One could get into an interrupt without GIE disabled, and it gave problems. Those problems were fixed.As you say, it appears that one could use masking of the appropriate iE bits to allow multiple interrupt priorities in those chips without that hardware possibility.*See attachment from PIC16FC71 datasheet.

author: woofy
author_rank: Frequent Contributor
timestamp: October 08, 2023, 04:11:18 pm
content: Quote from: jpanhalt on October 08, 2023, 10:46:08 amWould that really work reliably?If there was a pending interrupt, say from an impending timer interrupt as the OP is querying, then setting GIE will immediately jump to the to the interrupt vector before the return has taken place. From page 129 of the data sheet:"When bit GIE is enabled, and an interrupt’s flag bit and mask bit are set, the interrupt will vector immediately."What Microchip means by "immediately" is not so clear. I believe there is a two stage pipeline in these chips, and the instruction in the pipeline (the return) might get completed first. So it might work, but I don't think I would do it.

author: jpanhalt
author_rank: Super Contributor
timestamp: October 08, 2023, 06:08:06 pm
content: Probably not given there is a finite time between enabling GIE and the return. (Analogous to the problem with clearing GIE on those 3 early chips.) However, Microchip warns about the necessity of checking other pending flags before returning. It was just an example of how to clear the stack from the preceding interrupt call. My point is to emphasize there is nothing "magic" about interrupts. They are great, when used properly, as they are hardware based. Automatic context saving on PIC16F1xxx and later is even greater, but it is nothing that wasn't done before in firmware. Of course, it had to be restored a finite time before exit, which could give the same problem with an intervening interrupt flag that was not cleared or dealt with before exiting.

author: ejeffrey
author_rank: Super Contributor
timestamp: October 08, 2023, 07:58:22 pm
content: Quote from: jpanhalt on October 07, 2023, 08:03:25 pmI'm not sure about the PIC but many processors, even ones without vectored interrupt handlers have per-interrupt enable masks. In that case, what you can do upon entering the ISR is to mask the interrupt for your device then reenable global interrupts. The go about handling the IO. The interrupt controller will still register pending interrupts but not deliver them Then unmask your interrupt when returning from the ISR, and if an interrupt is pending it will be delivered and cause the ISR to restart.The reason to do this is just to minimize the time with global interrupt disabled to reduce latency for your more latency sensitive interrupts.Of course if you do this you have to be aware that you can be preempted by other interrupts and your access to global memory still has to be done safely. But at least no other