Microchip Technology SW006023-2 Data Sheet
MPLAB
®
XC32 C/C++ Compiler User’s Guide
DS51686E-page 134
2012 Microchip Technology Inc.
11.3
WRITING AN INTERRUPT SERVICE ROUTINE
An interrupt handler function is different to 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.
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.
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 ser-
vice 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. Only the mip32 instruction set
can be used in ISRs, so the compiler must be told to generate code using this instruc-
tion set, even if the option to generate mip16 instructions has been used.
vice 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. Only the mip32 instruction set
can be used in ISRs, so the compiler must be told to generate code using this instruc-
tion set, even if the option to generate mip16 instructions has been used.
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.
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.
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 (also known as an Interrupt
Service Routine or ISR) via either the interrupt attribute or the interrupt pragma
Service Routine or ISR) via either the interrupt attribute or the interrupt pragma
1
. 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.
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.
11.3.1
Interrupt Attribute
__attribute__((interrupt([IPLn[SRS|SOFT|AUTO]])))
Where n is in the range of 0..7, inclusive.
Use the interrupt attribute to indicate that the specified function is an interrupt handler.
The compiler generates function entry and exit sequences suitable for use in an
interrupt handler when this attribute is present. The generated code preserves context
by either using a shadow register set (SRS) or using generated software instructions
(SOFT) to push context onto the stack. See Example 11-1 for an interrupt attribute.
The compiler generates function entry and exit sequences suitable for use in an
interrupt handler when this attribute is present. The generated code preserves context
by either using a shadow register set (SRS) or using generated software instructions
(SOFT) to push context onto the stack. See Example 11-1 for an interrupt attribute.
EXAMPLE 11-1:
INTERRUPT ATTRIBUTE
void __attribute__((interrupt(IPL7SRS))) bambam (void);
Many PIC32 devices allow us to specify, via configuration-bit settings, which interrupt
priority level will use the shadow register set (e.g., #pragma config
FSRSSEL=PRIORITY_7). Refer to the device data sheet to determine if your PIC32
target device supports this feature. This means we must specify which context-saving
mechanism to use for each interrupt handler. The compiler will generate interrupt
function prologue and epilogue code utilizing shadow register context saving for the
IPLnSRS
priority level will use the shadow register set (e.g., #pragma config
FSRSSEL=PRIORITY_7). Refer to the device data sheet to determine if your PIC32
target device supports this feature. This means we must specify which context-saving
mechanism to use for each interrupt handler. The compiler will generate interrupt
function prologue and epilogue code utilizing shadow register context saving for the
IPLnSRS
Interrupt Priority Level (IPL) specifier. It will use software context saving for
the IPLnSOFT IPL specifier.
1. Note that pre-processor macros are not expanded in pragma directives.
Note:
Application code is responsible for applying the correct value to the
matching handler routine.
matching handler routine.