4.4.10 Interrupt Functions

The __interrupt(type) specifier can be used to indicate that a function is to act as an interrupt service routine. The type is a comma-separated list of keywords that indicate information about the interrupt function.

The current interrupt types are:

<empty>Implement the default interrupt function.
low_priorityThe interrupt function corresponds to the low priority interrupt source.

(MPLAB XC8 - PIC18 only)

high_priorityThe interrupt function corresponds to the high priority interrupt source.

(MPLAB XC8)

save(symbol-list)Save the listed symbols on entry, and restore on exit.

(MPLAB XC16)

irq(irqid)Specify the interrupt vector associated with this interrupt. (MPLAB XC16 and XC8)
altirq(altirqid)Specify the alternate interrupt vector associated with this interrupt.

(MPLAB XC16)

base(address)Specify vector table address.

(MPLAB XC8)

preprologue(asm)Specify assembly code to be executed before any compiler-generated interrupt code.

(MPLAB XC16)

shadowAllow the ISR to utilize the shadow registers for context switching.

(MPLAB XC16)

auto_psvThe ISR will set the PSVPAG register and restore it on exit.

(MPLAB XC16)

no_auto_psvThe ISR will not set the PSVPAG register.

(MPLAB XC16)

Use the native keywords discussed in the Differences section to look up information on the semantics of this specifier.

Some devices may not implement interrupts. Use of this qualifier for such devices generates a warning. If the argument to the __interrupt specifier does not make sense for the target device, a warning or error is issued by the compiler.

Example

The following shows a function qualified using __interrupt.

__interrupt(low_priority) void getData(void) {
  if (TMR0IE && TMR0IF) {
     TMR0IF=0;
     ++tick_count;
  }
{

Differences

8-bit compilers have used the interrupt and low_priority qualifiers to indicate this meaning for some devices. Interrupt routines were, by default, high priority. The __interrupt() specifier may now be used outside of the CCI.

The 16-bit and 32-bit compilers have used the interrupt attribute to define interrupt functions.

Migration to the CCI

For 8-bit compilers, change any occurrence of the interrupt qualifier, e.g., from:

void interrupt myIsr(void)
void interrupt low_priority myLoIsr(void)

to the following, respectively:

void __interrupt(high_priority) myIsr(void)
void __interrupt(low_priority) myLoIsr(void)

For 16-bit compilers, change any occurrence of the __interrupt() attribute, e.g., from:

void _attribute_((interrupt(auto_psv,irq(52))))
_T1Interrupt(void);

to:

void __interrupt(auto_psv,irq(52))) _T1Interrupt(void);

For 32-bit compilers, the __interrupt() keyword takes two parameters, the vector number and the (optional) IPL value. Change code that uses the interrupt attribute, similar to these examples:

void __attribute__((vector(0), interrupt(IPL7AUTO), nomips16))
myisr0_7A(void) {}
void __attribute__((vector(1), interrupt(IPL6SRS), nomips16))
myisr1_6SRS(void) {}
/* Determine IPL and context-saving mode at runtime */
void __attribute__((vector(2), interrupt(), nomips16))
myisr2_RUNTIME(void) {}

to:

void __interrupt(0,IPL7AUTO) myisr0_7A(void) {}
void __interrupt(1,IPL6SRS) myisr1_6SRS(void) {}
/* Determine IPL and context-saving mode at runtime */
void __interrupt(2) myisr2_RUNTIME(void) {}

Caveats

None.