3.5.7 How Can I Make My Interrupt Routine Faster?

Consider suggestions made in Section 3.5.2 “How Can I Make My Code Smaller?” (code size) for any interrupt code. Smaller code is often faster code.

In addition to the code you write in the ISR, there is the code the compiler produces to switch context. This is executed immediately after an interrupt occurs and immediately before the interrupt returns, meaning it must be included in the time taken to process an interrupt (see 5.9.4 Context Switching). This code is typically optimal, in that only registers used in the ISR will be saved by this code. Thus, the fewer registers that are used in your ISR means that potentially less context switch code will be executed. Register use increases with the complexity of code, so avoid complex statements and calls to functions that might also contain complex code. Use the assembly list file to see which registers are being used by the compiler in the interrupt code (see 6.3 Assembly List Files).

Mid-range devices have only a few registers that are used by the compiler and there is little context switch code. Some devices save context automatically into shadow registers, which further reduces (or eliminates entirely) the compiler-generated switch code (see 5.6 Register Usage).

Consider having the ISR simply set a flag and return. The flag can then be checked in main-line code to handle the interrupt. This has the advantage of moving the complicated interrupt-processing code out of the ISR so that it no longer contributes to its register usage. Always use the volatile qualifier (see 5.3.8.2 Volatile Type Qualifier for variables shared by the interrupt and main-line code; see Section 3.4.6 “How Do I Share Data Between Interrupt and Main-line Code?”).