Hardware interrupt handler (#pragma interrupt)
|
Output object code required by hardware interrupt.
[Function]
- | An interrupt vector is generated. |
- | A code for returning with RETI is generated with the target function definition used as a hardware interrupt handler. |
- | A stack or a register bank can be specified as the area for saving general registers. |
- | The interrupt handler definition is output to the .text or .textf section in the same way as normal function definitions. The section name can be changed through #pragma section.
Note however when the vector table is specified, the start address of the interrupt handler should be a location that can be accessed in 16-bit addressing. |
- | When the vector table is specified, the specification becomes __near forcibly, regardless of whether __far is specified explicitly or implicitly. No warning message is output. |
- | When the vector table is not specified, the __near or __far specification by the function takes priority, regardless of whether the specification is explicit or implicit. |
[Effect]
- | Interrupt handlers can be written in the C source level. |
[Usage]
- | Specify a function name and interrupt specifications through the #pragma directive. |
- | Write the #pragma directive before the target function definition. |
#pragma interrupt [(]interrupt-handler-name[(interrupt-specification [,...])][)]
|
The interrupt specifications can include the following.
|
|
|
Vector table specification
|
vect=address
|
Address of the vector table where the start address of the interrupt handler is to be stored.
When this setting is omitted, no vector table is generated.
Address of the vector table where the start address of the interrupt handler is to be stored.
When this setting is omitted, no vector table is generated.
Address: Binary, octal, decimal, or hexadecimal constant
Only an even value within the range from 0x0 to 0x7c can be specified
(a value outside this range will cause an error).
|
Register bank specification
|
bank={RB0|RB1|RB2|RB3}
|
Register bank for use by the interrupt handler.Note 1
Execution of the interrupt handler uses the register in the specified bank.
ES and CS are saved in the stack.
Saving and restoring of general registers are implemented by using the SEL instruction that switches register banks. This can reduce the code size.
When this setting is omitted, the general registers are saved in the stack.Note 2
|
Nested interrupt enable specification
|
enable={true|false}
|
true: Enables nested interrupts at the entry to a function; that is, EI is generated before the codes of saving registers.
false: EI is not generated.
When enable is omitted, EI is not generated.
|
Note 1. | Specify a register bank that differs from the register bank that was used before the interrupt handler was called. If the same register bank is specified, the contents of the saved register can no longer be restored. |
If a single item is used more than once in a statement, a compilation error will occur.
However, more than one vector table can be specified as long as the addresses do not overlap. [V1.06 or later]
#pragma interrupt func(vect=2,vect=2) // Error
|
#pragma interrupt func(vect=2,vect=8) // OK
|
#pragma interrupt func(vect=2)
#pragma interrupt func(vect=8) // OK
|
When "vect= address" is specified, a vector table is generated. Therefore, if a vector table is defined through Section definition directives in the assembly language (for example, in the startup routine), a linkage error will occur.
When "vect= address" is specified, use the .VECTOR directive to write a vector table in the assembly language instead of using the section definition directive.
[Restrictions]
- | If an interrupt handler is called in the same way as a normal function, a compilation error will occur. |
- | If __inline, __callt or another #pragma is specified, a compilation error will occur. |
- | The parameters and return value of an interrupt handler should be declared as void (e.g., void func (void);).
If the type is not void, a compilation error will occur. |
- | When no register is used or no function is called in an interrupt handler, the instruction for switching register banks is not output even if register bank switching is specified in #pragma interrupt.
Examples of this situation include the following: |
- | When only the instructions that do not use registers, such as instructions that specify constant values in SFR, are output in the interrupt handler |
[Example]
(1) | When there is no function call in the interrupt handler |
(a) | Default setting is used |
[ Input program ]
#include "iodefine.h" /*Including iodefine.h enables*/
#pragma interrupt inter (vect=INTP0) /*interrupt source names to be used*/
/*for vect setting*/
void inter ( void ) {
/*Interrupt processing (only AX, HL, and ES are used)*/
}
|
[ Output program ]
_inter .vector 0x0008 ;INTP0
.section .text, TEXT ;Assumed to be the __near specification
;because the vector table is specified
_inter:
push AX ;Code for saving the general registers to be
;used in the stack
push HL
mov A, ES
push AX
;Interrupt processing for the INTP0 pin
;(body of the function. only AX, HL, and ES are used)
pop AX ;Code for restoring the general registers to be
;used from the stack
mov ES, A
pop HL
pop AX
reti
|
(b) | Register bank is specified |
[ Input program ]
#pragma interrupt inter (vect=INTP0, bank=RB1)
void inter ( void ) {
/*Interrupt processing (ES is used but CS is not used)*/
}
|
[ Output program ]
_inter .vector 0x0008 ;INTP0
.section .text, TEXT ;Assumed to be the __near specification
;because the vector table is specified
_inter:
sel RB1 ;Code for switching register banks
mov A, ES ;Code for saving ES and CS registers to be
;used in the stack
push AX
;Interrupt processing for the INTP0 pin
;(body of the function. ES is used but CS is not used.)
pop AX ;Code for restoring ES and CS registers to be
;used from the stack
mov ES, A
reti
|
(2) | When a function is called in the interrupt handler (including a call of the function declared with #pragma inline_asm) |
(a) | Default setting is used |
[ Input program ]
#pragma interrupt inter (vect=INTP0)
void inter ( void ) {
/*Interrupt processing*/
}
|
[ Output program ]
_inter .vector 0x0008 ;INTP0
.section .text, TEXT ;Assumed to be the __near specification
;because the vector table is specified
_inter:
push AX
push BC
push DE
push HL
mov A, ES ;Code for saving ES, CS, and all general
;registers in the stack
mov X, A
mov A, CS
push AX
;Interrupt processing for the INTP0 pin (body of the function)
pop AX ;Code for restoring ES, CS, and all general
;registers from the stack
mov CS, A
mov A, X
mov ES, A
pop HL
pop DE
pop BC
pop AX
reti
|
(b) | Register bank is specified |
[ Input program ]
#pragma interrupt inter (vect=INTP0, bank=RB1)
void inter ( void ) {
/*Interrupt processing*/
}
|
[ Output program ]
_inter .vector 0x0008 ;INTP0
.section .text, TEXT ;Assumed to be the __near specification
;because the vector table is specified
_inter:
sel RB1 ;Code for switching register banks
mov A, ES ;Code for saving ES and CS registers in the
;stack
mov X, A
mov A, CS
push AX
;Interrupt processing for the INTP0 pin (body of the function)
pop AX ;Code for restoring ES and CS registers in the
;stack
mov CS, A
mov A, X
mov ES, A
reti
|