2

In general, what's the maximum length of instructions that can be included in an Interrupt Service Routine?

The docs say an ISR should be "as short and fast as possible", but that's bit vague.

For example, I have an ISR that gets called for each pulse on an motor's encoder.

void on_encoder_pulse(){
    encoder_change = true;
    count1 += 1;
    count2 += last_call;
    last_call = millis();
}

Will this run without interruption?

2

What is the maximum length an Interrupt Service Routine?

This depends on the max latency before servicing any other waiting Interrupt Service Routine (ISR).

An AVR ISR will execute with further interrupts disabled until the running ISR is completed. Any other interrupt(s) during the execution will be delayed. Data may be lost if the delay is too long. This depends on the interrupt source and frequency of interrupts.

In general an ISR (for incoming data) should only capture the data that could be lost and delay processing to the main loop function. A good example is the ISR for the Arduino Hardware Serial (USART) handling. Data sent and received are queued.

A traditional method (design pattern) is to have very short ISRs that capture data and push to an event queue. All processing is done in the main loop. This gives short latency and faster response, and reduces the risk of ISRs depending on each other, etc.

Cheers!

2

As already explained by jwpat7, interrupts are, by default, not interruptible. Thus, if another interrupt fires while your ISR is running, it will no be serviced until your ISR completes. This delay you impose on other interrupts is called latency. So your question boils down to “how much latency can the other interrupts tolerate”.

There is no simple answer: it all depends on the timing requirements of whatever those interrupts are servicing. For example:

  • The millis() counter is updated by interrupts. Any latency longer than 1024 µs (on the Uno) can make it loose tics.
  • If you are using the serial port to receive data, a latency longer than one byte time (1040 µs at 9600 pbs, less at higher baud rates) will make you loose data.
  • If you are using the Servo library, any interrupt latency will create jitter in the drive signal, and at some point this may become visible as mechanical jitter.

Then, if you really need a precise answer, you will have to check the timing requirements of every piece of hardware and every library you are using. And then check the latency already imposed by the ISRs in those libraries, as your latency can come in top of that.

If your program relies on loop() looping fast enough, you should also keep in mind that interrupts also slow that.

1

In general, on AVR devices, interrupts have been turned off (by hardware) when an ISR (interrupt service routine) begins execution.

Thus, if on_encoder_pulse() is an ISR and is invoked due to an interrupt, it will run uninterrupted.

An ISR that within itself turns the interrupt system back on before it's done runs the risk of other interrupts being serviced before it completes.

The suggestion that ISR's be “as short and fast as possible” is intended to avoid other interrupts being missed, as will happen if an interrupt source activates multiple times while the interrupt system is off. Most interrupt sources latch a bit and will be handled when the interrupt system is re-enabled; some don't latch a bit, and won't be seen if some ISR is long-winded.

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.