The CC-RH can describe an "Interrupt handler" or "Exception handler" that is called if an interrupt or exception occurs. This section explains how to describe these handlers.
If an interrupt or exception occurs in the RH850 family, the program jumps to a handler address corresponding to the interrupt or exception.
The arrangement of the handler addresses and the available interrupts vary depending on the device of the RH850. See the Relevant Device's User's Manual of each device for details.
How to describe interrupt servicing is explained specifically in "(3) Describing interrupt/exception handler".
If an interrupt/exception occurs while a function is being executed, interrupt/exception processing must be immediately executed. When the interrupt/exception processing is completed, execution must return to the function that was interrupted.
Therefore, the register information at that time must be saved when an interrupt/exception occurs, and the register information must be restored when interrupt/exception processing is complete.
The format in which an interrupt/exception handler is described does not differ from ordinary C functions, but the functions described in C must be recognized as an interrupt/exception handler by the CC-RH. With the CC-RH, an interrupt/exception handler is specified using the #pragma interrupt directive.
#pragma interrupt ( function-specification [, function-specification]... )Note function-specification: function-name [(interrupt specification [, interrupt specification]...)] |
Describe functions that are described in the C language. In the case of a function, "void func1() {}", specify "func1".
The function exit code of an interrupt function is different from that of an ordinary function. You must therefore not call them in the same way as ordinary functions.
The following interrupt specification can be specified.
The parameter of the interrupt specification cannot be omitted.
For example, writing only "enable=" will cause a compilation error. The default interrupt specification signifies the behavior when individual interrupt specifications are not written.
The return type of an interrupt function should always be the void type.
For formal parameters of an interrupt function, a maximum of four can be written when the interrupt specification "param=" is specified and a maximum of one can be written when not specified.
The type of formal parameters should always be unsigned long.
When "param=" is not specified, the EIIC register value is stored in the formal parameter for an EI level exception and the FEIC register value is stored for any other exception.
When "param=" is specified, the value of each exception source register is stored in the corresponding formal parameter according to the specified contents.
#pragma interrupt handler1 (priority=EIINT) void handler1(unsigned long a) { /* a = EIIC; */ : } #pragma interrupt handler2 void handler2(unsigned long a) { /* a = FEIC */ : } #pragma interrupt handler3 (param=(eiic,feic,fpsr)) void handler3(unsigned long a, unsigned long b, unsigned long c) { /* a = EIIC, b = FEIC, c = FPSR */ : } |
The compiler inserts the following instructions at the entrance and exit of an EI level exception interrupt function. EIINT and FPI are some of the main corresponding items.
However, this is not inserted into all interrupt functions. Necessary processing is output in accordance with user-defined #pragma statements, compiler options, etc.
(1) Allocates stack area for saving context
(2) Saves Caller-Save register used in interrupt function
(4) If the function has a formal parameter, set EIIC to R6
(5) Enables multiplex interrupts
(8) Sets imprecise interrupt standby
(11) Disables multiplex interrupts
(13) Restores Caller-Save register used in interrupt function
(14) Frees stack area for saving context
Below is a specific example of the output code. Numbers (1) to (15) in the code correspond to the numbered actions above.
Note that the instructions in the output code will not necessarily be identical to this example. The instructions, general-purpose registers, and other details may differ from this example.
#pragma interrupt func1(enable=true, callt=true, fpu=true) void func1(unsigned long eiic) { User-coded processing; } |
Sample2: output of EI level exception |
#pragma interrupt func1(enable=true, callt=true, fpu=true) void func1(unsigned long eiic) { User-coded processing; } |
The compiler inserts the following instructions at the entrance and exit of an FE level exception interrupt function. FEINT and PIE are some of the main corresponding items.
However, this is not inserted into all interrupt functions. Necessary processing is output in accordance with user-defined #pragma statements, compiler options, etc.
(1) Allocates stack area for saving context
(2) Saves all Caller-Save register used in interrupt function
(3) If the function has a formal parameter, sets FEIC to R6
(8) Restores all Caller-Save register used in interrupt function
(9) Frees stack area for saving context
Below is a specific example of the output code. Numbers (1) to (10) in the code correspond to the numbered actions above.
Note that the instructions in the output code will not necessarily be identical to this example. The instructions, general-purpose registers, and other details may differ from this example.
#pragma interrupt func1(priority=feint, callt=true, fpu=true) void func1(unsigned long feic) { User-coded processing; } |
The compiler inserts the following instructions at the entrance and exit of an FE level exception (cannot recover/restore) interrupt function. FENMI and SYSERR are some of the main corresponding items.
(1) If the function has a formal parameter, sets FEIC to R6
Nothing is output if the function does not have any parameters.
No saving or restoration of context is output. |
Below is a specific example of the output code. Numbers (1) in the code correspond to the numbered actions above.
The compiler inserts the following instructions at the entrance and exit of an EI level exception interrupt function for which resbank is specified.
The instruction string differs from that output for a normal EI level exception interrupt function in the following points.
There is no instruction string for saving the context that is automatically saved by the register bank facility. |
The resbank instruction is output instead of the instruction string for restoring the above context. |
Note that information of the context to be automatically saved by the register bank facility is determined from the specified -Xresbank_mode option.
These are not always inserted in all interrupt functions, and the necessary processing is output in response to the #pragma directives written by the user or the compile options.
_handler: movea 0xFFFFFFA8, r3, r3 st.w r1, 0x14[r3] ; save r1 st.w r2, 0x18[r3] ; save r2 st.w r5, 0x1C[r3] ; save r5 st23.dw r6, 0x20[r3] ; save r6,r7 st23.dw r8, 0x28[r3] ; save r8,r9 st23.dw r10, 0x30[r3] ; save r10,r11 st23.dw r12, 0x38[r3] ; save r12,r13 st23.dw r14, 0x40[r3] ; save r14,r15 st23.dw r16, 0x48[r3] ; save r16,r17 st23.dw r18, 0x50[r3] ; save r18,r19 stsr 0x10, r8, 0x00 stsr 0x11, r9, 0x00 st23.dw r8, 0x00[r3] ; save CTPC,CTPSW stsr 0x06, r8, 0x00 st.w r8, 0x08[r3] ; save FPSR stsr 0x06, r8, 0x0A stsr 0x0D, r9, 0x0A st23.dw r8, 0x0C[r3] ; save FXSR,FXXP prepare 0x01, 0x00 ; save r31 jarl _sub, r31 dispose 0x00, 0x01 ; restore r31 ld23.dw 0x0C[r3], r8 ldsr r9, 0x0D, 0x0A ; restore FXXP ldsr r8, 0x06, 0x0A ; restore FXSR ld.w 0x08[r3], r8 ldsr r8, 6 ; restore FPSR ld23.dw 0x00[r3], r8 ldsr r9, 0x11, 0x00 ; restore CTPSW ldsr r8, 0x10, 0x00 ; restore CTPC ld23.dw 0x50[r3], r18 ; restore r18,r19 ld23.dw 0x48[r3], r16 ; restore r16,r17 ld23.dw 0x40[r3], r14 ; restore r14,r15 ld23.dw 0x38[r3], r12 ; restore r12,r13 ld23.dw 0x30[r3], r10 ; restore r10,r11 ld23.dw 0x28[r3], r8 ; restore r8,r9 ld23.dw 0x20[r3], r6 ; restore r6,r7 ld.w 0x1C[r3], r5 ; restore r5 ld.w 0x18[r3], r2 ; restore r2 ld.w 0x14[r3], r1 ; restore r1 movea 0x58, r3, r3 eiret |
_handler: movea 0xFFFFFFF0, r3, r3 stsr 0x10, r8, 0x00 stsr 0x11, r9, 0x00 st23.dw r8, 0x00[r3] ; save CTPC,CTPSW stsr 0x06, r8, 0x0A stsr 0x0D, r9, 0x0A st23.dw r8, 0x08[r3] ; save FXSR,FXXP prepare 0x01, 0x00 ; save r31 jarl _sub, r31 dispose 0x00, 0x01 ; restore r31 ld23.dw 0x08[r3], r8 ldsr r9, 0x0D, 0x0A ; restore FXXP ldsr r8, 0x06, 0x0A ; restore FXSR ld23.dw 0x00[r3], r8 ldsr r9, 0x11, 0x00 ; restore CTPSW ldsr r8, 0x10, 0x00 ; restore CTPC resbank ; restore r1-r19,r30,EIIC,FPSR eiret |
Even though the interrupt specification "resbank" is used, a code for setting a value to RBCR0 is not generated. The value must be directly set with the user program.
#pragma inline_asm, #pragma inline, #pragma noinline, #pragma interrupt,