Take the 2-minute tour ×
Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It's 100% free, no registration required.

From what I read on the internet we should respond to interrupts as quickly as possible, when programming microcontrollers; and that flags should be avoided because they tend to compound over time.
But the quickest way to respond to an interrupt is by using a flag (just need to change the boolean value of the variable and continue the code inside the main function). How to solve this problem? Should a state machine be used in any interrupt to avoid flags or that doesn't matter?

share|improve this question
1  
You have no choice but to "respond to interrupts" very quickly. That's what interrupts are. You want, in general, not to dwell for a long time in ISR's, and "long time" needs to be defined for your specific application. I haven't bumped into many situations where avoiding flags was super important-- but that would be pretty application specific. –  Scott Seidman May 5 at 16:46
    
@Scott: There are factors that influence how fast interrupts are delivered, it just isn't true that they will be handled quickly no matter how the code is written. Interrupts are delayed when masked, which may be done explicitly by code, or automatically while processing another interrupt. –  Ben Voigt May 5 at 18:56
    
@Ben, yes, but I think the OP is talking about what needs to go in the ISR with somewhat imprecise language. Once you're in the ISR, the interrupt has been "responded to" already. Masked interrupts are a different matter, and I think a bit beyond what the OP is getting at. –  Scott Seidman May 5 at 19:12

2 Answers 2

up vote 23 down vote accepted

Designing by rules of thumb you found on the internet someplace is a bad idea. The right way is to understand the issues, them make intelligent tradeoffs.

There is nothing wrong with a system that takes a interrupt, clears the hardware condition, then sets a flag for foreground code to do the remainder of the processing when it gets around to it. The danger in that is that the foreground code might not get around to it in a while, and if the same condition occurs again before that, information might get lost. Or, if something needs to be handled with low latency or jitter, then you probably want to handle it in the interrupt routine.

Again, understand the tradeoffs. Interrupt code runs immediately after the condition occurred, at the expense of everything else the processor might have to do at the time. Is that worth it? That depends. How much delay can you tolerate in handling the condition? How important is it that the foreground code not be delayed? It should be obvious that there is no universal single answer to this. It is highly dependent on the particular application.

For example, if part of the processors's job is to respond to a serial command stream that is sent to it at 115.2 kbaud, then bytes can be received as fast as every 87 µs. The interrupt routine could simply set a flag to let the foreground routine know it should read a byte from the UART, but that would require the foreground code to check the flag at least every 87 µs. In many cases, that would be difficult. A good tradeoff for many cases (again, this might not fit any one particular case) would be for the interrupt routine to grab the byte from the UART, clear the hardware condition, and stuff the byte into a software FIFO. The foreground code then empties the FIFO as it can, probably in bursts between performing other tasks that can take longer than the 87 µs byte time.

On the other hand, the interrupt routine for a user button might only perform debouncing and set a flag when the button is in a new state. The system only needs to respond to the button in human time, which can be many milliseconds. If the foreground code checks all events at least every few milliseconds, then there is no need for the interrupt routine to do any more of the processessing than described.

In general, the interrupt routine should do whatever immediately latency or jitter-sensitive processing needs to be performed due to the event, then set state so that processing that can respond slower can be performed later from foreground code. Again though, don't just run off using that as a rule of thumb. Understand why. Then you won't need any rules of thumb.

share|improve this answer
3  
Excellent answer, if I may add one more point: If the ISR only sets a flag for mainloop, then it's completely pointless: Just check the interrupt flag in mainloop. –  markrages May 5 at 22:52

No, it is not necessary to respond to interrupts as soon as possible. Suppose you have an interrupt to tell you when a UART transmit buffer is empty. If you don't have anything you need so send then you can wait as long as you want to service that interrupt.

I think what you have read is that interrupt service routines should be as short as possible. This is generally true, because having long interrupt service routines can delay the response to other interrupts or cause jitter in the response time.

I don't know what you mean by "flags". If you mean a static variable then there should be no problem in writing to such a variable inside an ISR and using its value outside the ISR. However, if you have a shared variable, one that can be modified inside an ISR as well as outside an ISR then you can have problems. The simplest way to handle this is to disable all interrupts whenever any piece of code modifies the shared variable, and do this as quickly as possible.

I've given you very simple answers, even though the field of multitasking in embedded systems includes many possible solutions to these problems. Unless you can ask a more specific question it will be hard to give you better answers.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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