SPRUI04F july 2015 – april 2023
A C/C++ interrupt routine is like any other C/C++ function in that it can have local variables and register variables; however, it should be declared with no arguments and should return void. C/C++ interrupt routines can allocate up to 32K on the stack for local variables. For example:
__interrupt void example (void)
{
...
}
If a C/C++ interrupt routine does not call any other functions, only those registers that the interrupt handler attempts to define are saved and restored. However, if a C/C++ interrupt routine does call other functions, these functions can modify unknown registers that the interrupt handler does not use. For this reason, the routine saves all usable registers if any other functions are called. Interrupts branch to the interrupt return pointer (IRP). Do not call interrupt handling functions directly.
Interrupts can be handled directly with C/C++ functions by using the INTERRUPT pragma or the __interrupt keyword. For more information, see Section 7.9.20 and Section 7.5.4, respectively.
You are responsible for handling the AMR control register and the SAT bit in the CSR correctly inside an interrupt. By default, the compiler does not do anything extra to save/restore the AMR and the SAT bit. Macros for handling the SAT bit and the AMR register are included in the c6x.h header file.
For example, you are using circular addressing in some hand assembly code (that is, the AMR does not equal 0). This hand assembly code can be interrupted into a C code interrupt service routine. The C code interrupt service routine assumes that the AMR is set to 0. You need to define a local unsigned int temporary variable and call the SAVE_AMR and RESTORE_AMR macros at the beginning and end of your C interrupt service routine to correctly save/restore the AMR inside the C interrupt service routine.
#include <c6x.h>
__interrupt void interrupt_func()
{
unsigned int temp_amr;
/* define other local variables used inside interrupt */
/* save the AMR to a temp location and set it to 0 */
SAVE_AMR(temp_amr);
/* code and function calls for interrupt service routine */
...
/* restore the AMR for your hand assembly code before exiting */
RESTORE_AMR(temp_amr);
}
If you need to save/restore the SAT bit (i.e. you were performing saturated arithmetic when interrupted into the C interrupt service routine which may also perform some saturated arithmetic) in your C interrupt service routine, it can be done in a similar way as the above example using the SAVE_SAT and RESTORE_SAT macros.
The compiler saves and restores the ILC and RILC control registers if needed.
For floating point architectures, you are responsible for handling the floating point control registers FADCR, FAUCR and FMCR. If you are reading bits out of the floating pointer control registers, and if the interrupt service routine (or any called function) performs floating point operations, then the relevant floating point control registers should be saved and restored. No macros are provided for these registers, as simple assignment to and from an unsigned int temporary will suffice.