25.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 shown in the following table.

Interrupt type Description Compiler
<empty> Implement the default interrupt function.
low_priority The interrupt function corresponds to the low priority interrupt source. MPLAB XC8 - PIC18 only
high_priority The interrupt function corresponds to the high priority interrupt source. MPLAB XC8
save(symbol-list) Save on entry and restore on exit the listed symbols. MPLAB XC16, MPLAB XC-DSC
irq(irqid) Specify the interrupt vector associated with this interrupt. MPLAB XC8, MPLAB XC16, MPLAB XC-DSC
altirq(altirqid) Specify the alternate interrupt vector associated with this interrupt. MPLAB XC16, MPLAB XC-DSC
preprologue(asm) Specify assembly code to be executed before any compiler-generated interrupt code. MPLAB XC16, MPLAB XC-DSC
shadow Allow the ISR to utilize the shadow registers for context switching. MPLAB XC16, MPLAB XC-DSC
auto_psv The ISR will set the PSVPAG register and restore it on exit. MPLAB XC16, MPLAB XC-DSC
no_auto_psv The ISR will not set the PSVPAG register. MPLAB XC16, MPLAB XC-DSC

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 for an 8-bit PIC device.
__interrupt(low_priority) void getData(void) {
	if (TMR0IE && TMR0IF) {
		TMR0IF=0;
		++tick_count;
	}
}

Differences

The legacy interrupt function syntax used by MPLAB XC8 when targeting PIC MCUs has been the interrupt specifier and optionally the low_priority specifier. When targeting AVR devices, the MPLAB XC8 compiler has used the ISR() macro to define interrupt functions.

The MPLAB XC16, XC-DSC, and XC32 compilers have used the interrupt attribute to define interrupt functions.

Migration to the CCI

When building with the MPLAB XC8 compiler for PIC MCUs, change any instance of the interrupt specifier to __interrupt, for example, from:
void interrupt low_priority tckI(void)
to:
void __interrupt(low_priority) tckI(void)
When building with the MPLAB XC8 compiler for AVR MCUs, change any instance of the ISR() macro, for example, from:
ISR(TIMER1_OVF_vect)
to:
void __interrupt(TIMER1_OVF_vect_num) spi_Isr(void)
When building with XC16 or XC-DSC compilers, change any occurrence of the interrupt attribute, for example, from:
void _attribute_((interrupt(auto_psv,irq(52)))) _T1Interrupt(void);
to:
void __interrupt(auto_psv,irq(52))) _T1Interrupt(void);
For MPLAB XC32, 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.