5
\$\begingroup\$

Im working on a uC that has interrupts configured for various FIFO's present in the uC. Each FIFO is connected to a common bus and can receive data independently(at any point of time). Now, everytime a FIFO receives 8 bytes of data a single ISR is called and in the ISR I have to identify which FIFO caused the interrupt.

What I would like to know is whether the Interrupt must be reset at the beginning of the ISR function or the end.

Problem1 that may occur: Suppose I reset the interrupt at the beginning of the ISR,if another FIFO gets filled while I'm in the ISR, since I have reset the interrupt, what will happen? Will it automatically re-enter the ISR after I execute the last line of the ISR or will some other problem occur?

Problem2 that may occur: Suppose I reset the interrupt at the end of the ISR,if another FIFO gets filled while I'm in the ISR, since I have not yet reset the interrupt, will I re-enter the ISR I have executed the last line of the ISR?

Where is the best place to reset the interrupt? Please do excuse if my understanding of interrupts is wrong

\$\endgroup\$
  • \$\begingroup\$ Clear at the beginning. Usually the ISR will be called again immediately after the current one exits. \$\endgroup\$ – Szidor Apr 5 '16 at 10:19
  • \$\begingroup\$ No, because you may lose interrupts. In simple terms: if flag is set AND not in ISR -> ISR is called. \$\endgroup\$ – Szidor Apr 5 '16 at 10:31
  • \$\begingroup\$ By "flag is set" I mean "is not zero" and not "is changing from zero to nonzero". \$\endgroup\$ – Szidor Apr 5 '16 at 10:32
  • \$\begingroup\$ I got it. A)Interrupt->ISR->Clear Int Flag,Proccess ISR,New interrupt in the background,Int Flag Set->End of ISR->Reenter ISR A) \$\endgroup\$ – AlphaGoku Apr 5 '16 at 10:39
  • \$\begingroup\$ yes that is correct \$\endgroup\$ – Szidor Apr 5 '16 at 11:23
5
\$\begingroup\$

Your question isn't limited to FIFOs or any particular interrupt-causing hardware.

Clear interrupt conditions as soon as you know you will handle that condition.

In the case of vectored interrupts, this is very early in the interrupt routine because you know the interrupt cause just from being there. You might do the normal saving of state before anything else, but clearing the interrupt condition should be the next thing you do.

In the case of a shared interrupt routine, you first have to check which device is causing the interrupt. Once you have found a device with its interrupt condition set, you go to the code to handle that device. Clearing the interrupt condition should usually be the first thing this code does.

The main reason for clearing the interrupt condition before servicing the interrupt is to not lose a interrupt. Suppose you did the reverse. The device interrupts, you handle it, then another event occurs right before you clear the interrupt condition. Now the condition for the new event has been cleared, but your code doesn't know that. The state for that device is now hung because it needs service and probably can't generate new events, but the one event that caused the current condition has already been cleared. Oops.

Note that the device you end up servicing in a shared interrupt routine may not be the one that originally caused the interrupt. Multiple devices could have their interrupt conditions set by the time you check them. I generally check them in a fixed order, handle the first one I find that needs service, then get out of the interrupt. If another device also has its interrupt condition set, then the processor will cause another interrupt. Some people go back and loop until no device has its condition set, but this makes the interrupt longer in most cases.

Also be careful checking devices that may have their interrupt masked off at run time. A common example is the UART transmit interrupt. You usually shut that off when the output FIFO is drained, then enable it right after stuffing something into the FIFO. On many processors, masking off the interrupt only prevents the interrupt itself from being generated, not the interrupt condition from being indicated. If some other device causes a shared interrupt and you check the UART transmitter first, you will mistakenly think it needs service since its interrupt condition is set even though its interrupting capability is masked. For any devices that may have its interrupting capability masked off, you have to also check that mask and ignore the device if it is masked off. This may sound obvious, but it is a common rooky mistake.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ In your last para,ur saying about a condition where multiple processes use a single uart peripheral and so,an interrupt not masked by one process may be misinterpreted by another?Also, i didnt quite understand ur vectored interrupt part. \$\endgroup\$ – AlphaGoku Apr 5 '16 at 11:20
  • \$\begingroup\$ @Aks: I'm talking about a shared interrupt routine that needs to check which device needs service. Vectored interrupts are the opposite architecture. The hardware goes to a unique execution address for each possible interrupt cause. The Microchip dsPIC line is a good example of that, which their PIC 16 line is a good example of a shared interrupt architecture. \$\endgroup\$ – Olin Lathrop Apr 5 '16 at 11:26
0
\$\begingroup\$

It is better to clear the interrupt flag ("reset the interrupt") at the beginning of the ISR because you will not loose another interrupt if it happens while the first invocation is still running.

Quick example: you receive data using some peripheral, the ISR takes some time to process it, if you receive a second byte while the ISR is still running and you clear the flag at the very beginning you will just get a second interrupt. If you have cleared that at the end then you would loose data.

| improve this answer | |
\$\endgroup\$

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.