hi_pri_ISR
for high priority interrupts,
lo_pri_ISR
for low priority interrupts.
A user specific interrupt service routine can be written at C level by using
the (non-standard) __interrupt__
keyword:
__interrupt__ void hi_pri_ISR() { /* interrupt service code */ }Note that this routine will replace the default one, because user libraries are scanned before
rtl.slb
.
The keyword __interrupt__
insures that
return 0
13.
The body of an ISR routine can be written in pure assembly language, using the __asm__
directive.
In this case, all previously mentionned registers can be freely altered, as long as FSR0 (the software stack pointer) is not altered when the ISR exits14.
When the interrupt code is written in C (or mix of C and asm code), registers used by the run-time library and user code must be saved and restored using the SAVE_REGS
and RESTORE_REGS
macros. Here is a typical example:
__interrupt__ void hi_pri_ISR() { SAVE_REGS ; /* MANDATORY */ if (INTCON & (1 << TMR0IF)) { // IT has occured on timer 0 timer0_ISR() ; // any code can be used here } RESTORE_REGS ; /* MANDATORY */ }
The SAVE_REGS and RESTORE_REGS macro are defined in the <interrupt.h> header, that should be included. These macros save the registers that are used by integer arthmetic routines, but do not save the registers that are used for floating point calculation. For this reason, do not use floating point data in an interrupt routine. However, if you really need to handle FP data in an interrupt routine, it is easy to write your own macro to save the FP context. See section 9.2 for details about the registers usage.
It is possible to take a full control of context saving. In this case, just omit the __interrupt__
keyword and insert yourself the code you need with __asm__
instructions. Beware! in this case you must know what you are doing.
AG 2013-04-10