CHAPTER 12 INTERRUPT MANAGEMENT FUNCTIONS


This chapter describes the interrupt management functions performed by the RI600PX.

12.1 Interrupt Type

Interrupts are classified into kernel interrupt and non-kernel interrupt.

- Kernel interrupt
An interrupt whose interrupt priority level is lower than or equal to the kernel interrupt mask level is called the kernel interrupt.
A kernel interrupt handler can issue service calls.
Note, however, that handling of kernel interrupts generated during kernel processing may be delayed until the interrupts become acceptable.




- Non-kernel interrupt
An interrupt whose interrupt priority level is higher than the kernel interrupt mask level is called the non-kernel interrupt. The non-maskable interrupt is classified into non-kernel interrupt.
A non-kernel interrupt handler must not issue service calls.
Non-kernel interrupts generated during service-call processing are immediately accepted whether or not kernel processing is in progress.




Note The kernel interrupt mask level id defined by Kernel interrupt mask level (system_IPL) in System Information (system).

12.2 Fast Interrupt of the RX-MCU

The RX-MCU supports the "fast interrupt" function. Only one interrupt source can be made the fast interrupt. The fast interrupt is handled as the one that has interrupt priority level 15. To use the fast interrupt function, make sure there is only one interrupt source that is assigned interrupt priority level 15.

For the fast interrupt function to be used in the RI600PX, it is necessary that the interrupt concerned be handled as an non-kernel interrupt. In other words, the kernel interrupt mask level must be set to 14 or below.

And "os_int = NO;" and "pragma_switch = F;" are required for interrupt_vector[] definition.

And the FINTV register of the RX-MCU must be initialized to the start address of the handler in the Boot processing function (PowerON_Reset_PC( )).

12.3 CPU Exception

The following CPU exceptions are handled as non-kernel interrupt.

- Unconditional trap (INT, BRK instruction)
Note, INT #1 to #8 are reserved by the RI600PX.


- Undefined instruction exception

- Privileged instruction exception

- Floating-point exception

On the other hand, the access exception handler is handled as kernel interrupt.

12.4 Base Clock Timer Interrupt

The TIME MANAGEMENT FUNCTIONS is realized by using base clock timer interrupts that occur at constant intervals. When the base clock timer interrupt occurs, The RI600PX's time management interrupt handler is activated and executes time-related processing (system time update, delayed wake-up/time-out of task, cyclic handler activation, etc.).

12.5 Multiple Interrupts

In the RI600PX, occurrence of an interrupt in an interrupt handler is called "multiple interrupts".

It can be set whether each interrupt handler for relocatable vector permits multiple interrupts. For details, refer to "20.21 Relocatable Vector Information (interrupt_vector[])".

12.6 Interrupt Handlers

The interrupt handler is a routine dedicated to interrupt servicing that is activated when an interrupt occurs.

The RI600PX handles the interrupt handler as a non-task (module independent from tasks). Therefore, even if a task with the highest priority in the system is being executed, the processing is suspended when an interrupt occurs, and the control is passed to the interrupt handler.

12.6.1 Basic form of interrupt handlers

The following shows the basic form of interrupt handlers.

 #include    "kernel.h"              /*Standard header file definition*/
 #include    "kernel_id.h"           /*Header file generated by cfg600px*/
 
 void Inthdr1 (void)
 {
     /* ......... */
 
     return;                         /*Terminate interrupt handler*/
 }


Note The cfg600px outputs the prototype declaration and #pragma interrupt directive for the handler function to kernel_id.h.

- Stack
A interrupt handler uses the system stack.


- Service call
The RI600PX handles the interrupt handler as a "non-task".
The kernel interrupt handler can issue service calls whose "Useful range" is "Non-task".
No service call can be issued in non-kernel interrupt handler.




Note If a service call (isig_sem, iset_flg, etc.) which causes dispatch processing (task scheduling processing) is issued in order to quickly complete the processing in the interrupt handler during the interval until the processing in the interrupt handler ends, the RI600PX executes only processing such as queue manipulation, counter manipulation, etc., and the actual dispatch processing is delayed until a return instruction is issued by the interrupt handler, upon which the actual dispatch processing is performed in batch.

- PSW register when processing is started

Table 12-1 PSW Register When Interrupt Handler is Started

Bit

Value

Note

I

- "pragma_switch = E": 1

- Other cases: 0

IPL

- Interrupt: Interrupt priority level

- CPU exception: Same before exception

Do not lower IPL more than the start of processing.

PM

0

Supervisor mode

U

0

System stack

C, Z, S, O

Undefined

Others

0



12.6.2 Register interrupt handler

The RI600PX supports the static registration of interrupt handlers only. They cannot be registered dynamically by issuing a service call from the processing program.

Static interrupt handler registration means defining of interrupt handlers using static API "interrupt_vector[]" (relocatable vector) and "interrupt_fvector[]" (fixed vector/exception vector) in the system configuration file.

For details about the static API "interrupt_vector[]", refer to "20.21 Relocatable Vector Information (interrupt_vector[])", and for details about the static API "interrupt_fvector[]", refer to "20.22 Fixed Vector/Exception Vector Information (interrupt_fvector[])".

12.7 Maskable Interrupt Acknowledgement Status in Processing Programs

The maskable interrupt acknowledgement status of RX-MCU depends on the values of PSW.I and PSW.IPL. See the hardware manual for details.

The initial status is determined separately for each processing program. See Table 12-2 for details.

Table 12-2 Maskable Interrupt Acknowledgement Status upon Processing Program Startup

Processing Program

PSW.I

PSW.IPL

Task

1

0

Task exception handling routine

1

Same as IPL in the task just before the task exception handling routine starts.

Cyclic handler, Alarm handler

1

Interrupt Handler

- "pragma_switch = E": 1

- Other cases: 0

- Interrupt: Interrupt priority level

- CPU exception: Same before exception



12.8 Prohibit Maskable Interrupts

There is the following as a method of prohibiting maskable interrupts.

- Move to the CPU locked state by using loc_cpu, iloc_cpu

- Change PSW.IPL by using chg_ims, ichg_ims

- Change PSW.I and PSW.IPL directly (only for handlers)

12.8.1 Move to the CPU locked state by using loc_cpu, iloc_cpu

In the CPU locked state, PSW.IPL is changed to the Kernel interrupt mask level (system_IPL). Therefore, only kernel interrupts are prohibited in the CPU locked state.

Note, in the CPU locked state, service call issuance is restricted. For details, refer to "11.4 Lock and Unlock the CPU".

12.8.2 Change PSW.IPL by using chg_ims, ichg_ims

The PSW.IPL can be changed to arbitrary value by using chg_ims, ichg_ims.
When a task changes PSW.IPL to other than 0 by using chg_ims, the system is moved to the dispatching disabled state. When a task returns PSW.IPL to 0, the system returns to the dispatching enabled state.


Do not issue ena_dsp while a task changes PSW.IPL to other than 0 by using chg_ims. If issuing ena_dsp, the system moves to the dispatching enabled state. If task dispatching occurs, PSW is changed for the dispatched task. Therefore PSW.IPL may be lowered without intending it.

The handlers must not lower PSW.IPL more than it starts.

12.8.3 Change PSW.I and PSW.IPL directly (only for handlers)

The handlers can change PSW.I and PSW.IPL directly. This method is faster than ichg_ims.
The handlers must not lower PSW.IPL more than it starts.


Note, the compiler provides following intrinsic functions for operating PSW. See CubeSuite+ RX Build User's Manual for details about intrinsic functions.

- set_ipl(): Change PSW.IPL

- get_ipl(): Refer to PSW.IPL

- set_psw(): Change PSW

- get_psw(): Refer to PSW