interrupt (for the DSP56800E)

This pragma controls the compilation of object code for interrupt routines.

Compatibility

This pragma is not compatible with the DSP56800, but it is compatible with the DSP56800E. For the DSP56800, see interrupt (for the DSP56800).

Syntax
#pragma interrupt [<options>] [<mode>] [on|off|reset]
Remarks

An Interrupt Service Routine (ISR) is a routine that is executed when an interrupt occurs. Setting C routines as ISRs is done using pragmas (pragma interrupt). To make a routine service an interrupt, you must:

The pragma interrupt option can be used to:

There are several ways to use this pragma, with an on|off|reset arguments, or with no arguments.

Table 1. Arguments
<options> alignsp Aligns the stack pointer register correctly to allow long values to be pushed on to the stack. Use this option when your project mixes C code and assembly code. Use this option specifically on ISRs which may interrupt assembly routines that do not maintain the long stack alignment requirements at all times. Restores the stack pointer to its original value before returning from the subroutine.
  comr The Operating Mode Register (OMR) is set for the following to ensure correct execution of C code in the ISR:
  • 36-bit values used for condition codes.(CM bit cleared)
  • Convergent Rounding(R bit cleared)
  • No Saturation mode(SA bit cleared)
  • Instructions fetched from P memory.(XP bit cleared)
<mode> saveall Preserves register values by saving and restoring all registers by calling the INTERRUPT_SAVEALL and INTERRUPT _ RESTOREALL routines in the Runtime Library.
  called Preserves register values by saving and restoring registers used by the routine. The routine returns with an RTS. Routines with pragma interrupt enabled in this mode are safe to be called by ISRs.
  default This is the mode when no mode is specified. In this mode, the routine preserves register values by saving and restoring the registers that are used by the routine. The routine returns with an RTI.
  fast 56800E fast interrupt processing has lower overhead than normal interrupts processing and should be used for all low-latency time-critical interrupts. Place before any function that is a fast interrupt handler: #pragma interrupt fast.
on|off|reset on Enables the option to compile all C routines as interrupt routines.
  off Disables the option to compile all C routines as interrupt routines.
  reset Restores the option to its previous setting.
Note: Use on or off to change the pragma setting, and then use reset to restore the previous pragma setting.

To disable the pragma, use #pragma interrupt off after #pragma interrupt, in the following listing.

Listing: Sample Code - #pragma interrupt on | off | reset
#pragma interrupt off  // To be used as default value
// Non ISR code

#pragma interrupt on
void ISR_1(void) {
  // ISR_1 code goes here.
}

void ISR_2(void) {
  // ISR_2 code goes here.
}
#pragma interrupt reset

If the pragma is inside a function block, compile the current routine as an interrupt routine. If the pragma is not inside a function block, compile the next routine as an interrupt routine. This concept is developed in the following listing.

Listing: Sample Code - #pragma interrupt and Function Block
// Non ISR code
void ISR_1(void) {
#pragma interrupt
  // ISR_1 code goes here.
}
#pragma interrupt
void ISR_2(void) {
  // ISR_2 code goes here.
}
#pragma interrupt off

See the following listing for an example of using the 'called' option in the interrupt pragma.

Listing: Sample Code - Using the `called' Option in #pragma interrupt
extern long Data1, Data2, Datain;
void ISR1_inc_Data1_by_Data2(void)
{
/* This is a routine called by the interrupt service routine ISR1(). */
#pragma interrupt called
Data1+=Data2;
return;
}
void ISR1(void)
{
/* This is an interrupt service routine. */
#pragma interrupt
Data2 = Datain+2;
ISR_inc_Data1_by_Data2();
}

56800E fast interrupt processing has lower overhead than normal interrupts processing and should be used for all low-latency time-critical interrupts. A new compiler pragma exists and it has to be placed before any function that is a fast interrupt handler: #pragma interrupt fast.

Fast interrupt processing uses the FRTID instruction to return from the handler. The FRTID instruction has 2 delay slots in which instructions from the handler can be scheduled and the compiler performs this task automatically. If no eligible instructions are found, NOPs are inserted in these delay slots.

For the following C function:

#pragma interrupt fast
void foo () {
int x = 0;
}

The compiler generates the following assembly code:

clr.w X:(SP+0)
frtid 
adda  #0x000002,SP
suba  #2,SP

Instead of:

clr.w X:(SP+0)
adda  #0x000002,SP
suba  #2,SP
frtid
nop
nop

According to 56800E core manual, there are a series of limitations for the first instructions in a fast interrupt handler. The compiler generates assembly code following these associated rules.

Consider the handler below:

 #pragma interrupt fast
 void foo() {
  asm (jsr 0);
  asm (move.w 1, x0);
}

for which the compiler generates the following sequence with 3 NOPs before the JSR instruction, according to the hardware rules for fast interrupts handlers:

 adda  #0x000002,SP
 move.wX0,X:(SP)
 nop  
 nop  
 nop
 jsr   0x000000
 move.w#1,X0
 frtid
 move.wX:(SP),X0
 suba  #2,SP