17.2 Writing an Interrupt Service Routine

An interrupt handler function is different than an ordinary function in that it handles the context save and restore to ensure that upon return from interrupt, the program context is maintained. A different code sequence is used to return from these functions as well.

Several attributes can be used to ensure that the compiler generates the correct code for an ISR. Macros are provided so that this is easier to accomplish, see the following sections.

There are several actions that the compiler needs to take to generate an interrupt service routine. The compiler has to be told to use an alternate form of return code. The function also needs to be linked to the interrupt vector. All ISRs must use either the MIPS32®r2 or the microMIPS™ ISA modes. Apply the 'nomips16' function attribute to each interrupt function.

Note: For devices that support multiple Instruction Set Architecture (ISA) modes, there may be a configuration bit that determines which mode the device uses for an exception/interrupt. If your device is configured to use the microMIPS ISA on interrupt, be sure to apply the micromips function attribute to your interrupt function. Consult your the data sheet for your target device to determine if it supports handling exceptions and interrupts in an alternate ISA mode.

An interrupt function must be declared as type void and may not have parameters. This is the only function prototype that makes sense for an interrupt function since they are never directly called in the source code.

Interrupt functions must not be called directly from C/C++ code (due to the different return instruction that is used), but they themselves may call other functions, both user-defined and library functions, but be aware that this may use additional registers which will need to be saved and restored by the context switch code.

A function is marked as an interrupt handler function, or ISR, via either the interrupt attribute or the interrupt pragma*. While each method is functionally equivalent to the other, the interrupt attribute is more commonly used and therefore the recommended method. The interrupt is specified as handling interrupts of a specific priority level or for operating in single vector mode.

For all interrupt vectors without specific handlers, a default interrupt handler will be installed. The default interrupt handler is supplied by the libpic32.a library and will cause a debug breakpoint and reset the device. An application may override the default handler and provide an application-specific default interrupt handler by declaring an interrupt function with the name _DefaultInterrupt.

Note: * Pre-processor macros are not expanded in pragma directives.