CHAPTER 9 INTERRUPT MANAGEMENT FUNCTIONS


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

9.1 Outline

The RI78V4 provides as interrupt management functions related to the interrupt handlers activated when a maskable interrupt is occurred.

In the RI78V4, interrupt servicing managed by the RI78V4 is called "interrupt handler", which is distinguished from interrupt servicing that operates without being managed by the RI78V4.

The following lists the differences between interrupt handlers and interrupt servicing.

Table 9-1 Differences Between Interrupt Handlers and Interrupt Servicing

Interrupt Handler

Interrupt Servicing

Service call issuance

Available

Not available

Interrupt type

Maskable interrupt

Maskable interrupt

Software interrupt

Reset interrupt

Interrupt priority level

Levels 2, 3

Levels 0, 1 (*)

Definition in the

system configuration file

Defines in DEF_INH

Not define in DEF_INH



* It is also possible to assign a level of 2 or 3 to an application that disables multiple interrupts.

Note 1 The interrupt priority level is set using the priority specification flag register of the target CPU.

Note 2 The RI78V4 does not execute initialization of hardware that creates interrupts (clock controller, etc.). This initialization processing must therefore be coded by the user in the Boot Processing or Initialization Routine.

9.2 Interrupt Entry Processing

Interrupt entry processing is a routine dedicated to entry processing that is extracted as a user-own coding module to assign instructions to branch to relevant processing (such as Interrupt Handlers or Boot Processing), to the vector table address to which the CPU forcibly passes the control when an interrupt occurs.

When the interrupt handler is described by C language (the TA_HLNG attribute is specified in a interrupt handler definition of the system configuration file(DEF_INH)), the user does not have to describe interrupt entry processing because of the C compiler outputing "interrupt entry processing which corresponds to an interrupt request name" automatically.

When the interrupt handler is described by Assembly language (the TA_ASM attribute is specified in a interrupt handler definition of the system configuration file(DEF_INH)), the user has to describe interrupt entry processing. Futher it is necessory to describe by an assembly language about branch to boot processing.

9.2.1 Basic form of interrupt entry processing

The code of interrupt entry processing varies depending on whether the relevant processing (Interrupt Handlers, Boot Processing, or the like) is allocated to the near area or to the far area.

The following shows examples for coding interrupt entry processing.

[ When the relevant processing (Interrupt Handlers, Boot Processing, or the like) is allocated to the near area ]

 .PUBLIC   _func_inthdr
 _func_inthdr   .VECTOR  0x002C    ;Jump to boot processing
 
      .SECTION  .text, TEXT        ;Vector table address setting
 _func_inthdr:
 
         ............              ;Main processing
 


[ When the relevant processing (Interrupt Handlers, Boot Processing, or the like) is allocated to the far area ]

      .EXTERN _intent_RESET        ;Declares symbol external reference
      .EXTERN _intent_INTTM00      ;Declares symbol external reference
 
      .SECTION   .vecttable, TEXT  ;Vector table section setting
 _intent_RESET   .VECTOR  0x0000   ;Vector table address setting
 _intent_INTTM00 .VECTOR  0x002C   ;Vector table address setting
 
      .SECTION  .textf, TEXTF      ;Vector table section setting
 _intent_RESET:
         BR      !!_boot           ;Jump to boot processing
 _intent_INTTM00:
         BR      !!_func_inthdr    ;Jump to interrupt handler


9.2.2 Internal processing of interrupt entry processing

Interrupt entry processing is a routine dedicated to processing of entries called without using the RI78V4 when an interrupt occurs. Therefore, note the following points when coding interrupt entry processing.

- Coding method
Code interrupt entry processing in assembly language, in formats compliant with the assembler's function calling rules.


- Stack switching
No stack requiring switching exists in interrupt entry processing execution. The code regarding stack switching during interrupt entry processing is therefore not required.


- Service call issuance
The RI78V4 prohibits issuance of service calls in interrupt entry processing.


The following lists processing that should be executed in interrupt entry processing.

- Vector table address setting

- Passing of control to relevant processing (Interrupt Handlers, Boot Processing, or the like)

9.3 Interrupt Handlers

The interrupt handler is a routine dedicated to interrupt servicing that is activated when an interrupt occurs, and is called from Interrupt Entry Processing.

The RI78V4 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.

The following shows a processing flow from when an interrupt occurs until the control is passed to the interrupt handler.

Figure 9-1 Processing Flow (Interrupt Handler)



9.3.1 Define interrupt handler

Interrupt handler registration is realized by coding Interrupt Entry Processing (branch instruction to interrupt handler) to the vector table address to which the CPU forcibly passes control upon occurrence of an interrupt.

The code of Interrupt Entry Processing varies depending on whether the interrupt handler is allocated to the near area or to the far area.

When the interrupt handler is described by C language (the TA_HLNG attribute is specified in a interrupt handler definition of the system configuration file(DEF_INH)), the user does not have to describe interrupt entry processing because of the C compiler outputing "interrupt entry processing which corresponds to an interrupt request name" automatically.

When the interrupt handler is described by Assembly language (the TA_ASM attribute is specified in a interrupt handler definition of the system configuration file(DEF_INH)), the user has to describe interrupt entry processing.

9.3.2 Basic form of interrupt handlers

When coding interrupt handlers in C, use void type functions that do not have arguments (any function name is fine) .

The code of interrupt depending on whether the interrupt handler is allocated to the near area or to the far area.

The following shows the basic form of coding interrupt handlers in C.

[ When the interrupt handler is allocated to the near area ]

 #include    <kernel.h>          /*Standard header file definition*/
 #include    <kernel_id.h>       /*System information header file definition*/
 
 void
 __near func_inthdr ( void )
 {
     /* ............ */          /*Main processing*/
 
     return;                     /*Terminate interrupt handler*/
 }


Note 1 The TA_HLNG attribute and the TA_NEAR attribute are specified in a definition of a interrupt handler in the system configuration file (DEF_INH).

Note 2 The the #pragma rtos_interrupt directive is defined in the file "kernel_id.h" (CF78V4 outputs automatically). Therefore please the file "kernel_id.h" be sure to do include.

[ When the interrupt handler is allocated to the near area ]

 #include    <kernel.h>          /*Standard header file definition*/
 #include    <kernel_id.h>       /*System information header file definition*/
 
 void
 __far func_inthdr ( void )
 {
     /* ............ */          /*Main processing*/
 
     return;                     /*Terminate interrupt handler*/
 }
 


Note 1 The TA_HLNG attribute and the TA_FAR attribute are specified in a definition of a interrupt handler in the system configuration file (DEF_INH).

Note 2 The the #pragma rtos_interrupt directive is defined in the file "kernel_id.h" (CF78V4 outputs automatically). Therefore please the file "kernel_id.h" be sure to do include.

When coding interrupt handlers in assembly language, use void type functions that do not have arguments (function: any).

The code of interrupt depending on whether the interrupt handler is allocated to the near area or to the far area.

The following shows the basic form of coding interrupt handlers in assembly language.

- When the interrupt handler is allocated to the near area
Saves AX register and stores the vector table address when an interrupt occurs, calls processing to switch to the system stack (function name: _kernel_int_entry), and then call end processing at the end of the interrupt handler (function name: _kernel_int_exit). A near attribute section is specified as an allocated section of the interrupt handler.


[ When the interrupt handler is allocated to the near area in assembly language ]

 $INCLUDE        (kernel.inc)     ;Standard header file definition
 $INCLUDE        (kernel_id.inc)  ;System information header file definition
 .PUBLIC   _func_inthdr
 
 _func_inthdr   .VECTOR  0x002C   ;Switches to system stack, Saves registers
 
      .SECTION  .text, TEXT
 _func_inthdr:                    ;Interrupt handler 
      PUSH   AX                   ;Saves AX register
      MOV    AX, #0x002C          ;Stores the vector table address when an interrupt
                                  ;occurs
 
 CALL   !!__kernel_int_entry ;Switchs to the system stack and saves registers
 
         ............             ;Main processing
 
      BR     !!__kernel_int_exit  ;Terminate interrupt handler, Restores registers
 


Note The TA_ASM attribute and the TA_NEAR attribute are specified in a definition of a interrupt handler in the system configuration file (DEF_INH).

- When the interrupt handler is allocated to the far area
Calls processing to switch to the system stack (function name: _kernel_int_entry), and then call end processing at the end of the interrupt handler (function name: _kernel_int_exit). A far attribute section is specified as an allocated section of the interrupt handler.


 $INCLUDE        (kernel.inc)     ;Standard header file definition
 $INCLUDE        (kernel_id.inc)  ;System information header file definition
 .PUBLIC   _func_inthdr
 
 _func_inthdr   .VECTOR  0x002C
 
      .SECTION  .textf, TEXTF   ;Interrupt handler
 _func_inthdr:
 CALL   !!__kernel_int_entry ;Switchs to the system stack and saves registers
 
         ............             ;Main processing
 
      BR     !!__kernel_int_exit  ;Terminate interrupt handler, Restores registers
 


Note 1 The TA_ASM attribute and the TA_FAR attribute are specified in a definition of a interrupt handler in the system configuration file (DEF_INH).

Note 2 When allocating a interrupt handler in far area, the far branch information is needed. In other words, it jumps from the vector table address to far branch information and jumps to a interrupt handler from there. CF78V4 outputs this far branch information automatically in a system information table file.

Note 3 CF78V4 outputs processing code that saves AX register and sets the vector table address of the factor automatically in a system information table file.

9.3.3 Internal processing of interrupt handler

The RI78V4 handles the interrupt handler as a "non-task".

Moreover, the RI78V4 executes "original pre-processing" when passing control to the interrupt handler, as well as "original post-processing" when regaining control from the interrupt handler.

Therefore, note the following points when coding interrupt handlers.

- Coding method
Code interrupt handlers using C or assembly language in the format shown in "9.3.2 Basic form of interrupt handlers".


- Stack switching
When the interrupt handler is described by C language, the user does not have to describe to switch to the system stack (calls _kernel_int_entry) because of the C compiler outputing this code automatically. When the interrupt handler is described by assembly language, saves AX register and stores the vector table address when an interrupt occurs, calls processing to switch to the system stack (function name: _kernel_int_entry), and then call end processing at the end of the interrupt handler (function name: _kernel_int_exit).


- Saving/storing of data in register
When the interrupt handler is described by C language, the user does not have to describe to switch to the system stack (calls _kernel_int_entry) because of the C compiler outputing this code automatically. When the interrupt handler is described by assembly language, data of general-purpose registers (AX, BC, DE, HL) and registers ES CS is saved and restored in that function execution, by explicitly calling register data save processing (function name: _kernel_int_entry) at the beginning of the interrupt handler, and calling data restore processing (function name: _kernel_int_exit) at the end of the interrupt handler.


Note 1 Data of the PSW and PC are automatically saved and stored by the CPU.

- Interrupt status
The RI78V4 goes into the following state when passing control to an interrupt handler.
Consequently, after control has passed to an interrupt handler, if an interrupt occurs with a higher precedence than the current level, then multiple interrupts can be processed.



- Acceptance of maskable interrupts is permitted

IE = 0

- Interrupts with the precedence below are disabled

A level-2 interrupt handler process is ongoing: ISP1 = 0, ISP0 = 1

A level-3 interrupt handler process is ongoing: ISP1 = 1, ISP0 = 0

Note It is not possible to define level 0 or 1 as an interrupt handler.

Note Even if the acceptance of maskable interrupts is disabled inside an interrupt handler (IE = 0), it will be enabled (IE = 1) after control returns from the interrupt handler.

- Service call issuance
The RI78V4 handles the interrupt handler as a "non-task".
Service calls that can be issued in interrupt handlers are limited to the service calls that can be issued from non-tasks.



Note 1 For details on the valid issuance range of each service call, refer to Table 12-8 to Table 12-17.

Note 2 If a service call (ichg_pri, isig_sem, etc.) accompanying 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 RI78V4 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.

9.4 Controlling Enabling/Disabling of Interrupts

9.4.1 Interrupt level under management of the RI78V4

The microcontroller manages four levels of interrupts: level 0 to level 3. On the RI78V4, the interrupt levels at which service calls can be issued from an interrupt are permanently set to levels 2 and 3, these are treated as the interrupt levels managed by the RI78V4.

- Interrupt levels 2 and 3 are managed by the RI78V4.
Service calls can be issued from levels 2 and 3. Interrupt handlers, which are interrupts (including timer interrupts) managed by the RI78V4, must be set to level 2 or 3.


- Interrupt levels 0 and 1 are not managed by the RI78V4
Service calls cannot be issued from levels 0 or 1. Behavior is not guaranteed if a service call is issued from level 0 or 1. Interrupt processes, which are interrupts not managed by the RI78V4, must be set to level 0 or 1. There is, however, an exception: user applications that disable multiple interrupts (see below) can set interrupts to level 2 or 3.


9.4.2 Controlling enabling/disabling of interrupts in the RI78V4

The RI78V4 uses the "ISP1" and "ISP0" bits in the PSW register to enable and disable interrupts. Set ISP1 to 0 and ISP0 to 1 to disable interrupts in the RI78V4. Set ISP1 to 1 and ISP0 to 1 to enable interrupts in the RI78V4.

Figure 9-2 ISP1 and ISP0 Bits in PSW Register



The "IE" bit of the RI78V4's PSW register inherits the value of the service call or RI78V4-function issuer. EI and DI instructions do not manipulate the "IE" value. As exceptions, however, there are places in the RI78V4 where EI and DI instructions are used.

- Immediately before starting a task specifying interrupts as disabled, a DI instruction is used to set IE to 0.

- Immediately before starting a task specifying interrupts as enabled, an EI instruction is used to set IE to 1.

- Immediately before starting the idle routine, an EI instruction is used to set IE to 1.

- Inside the __kernel_int_entry function, which performs interrupt handler start processing, IE is set to 1.

9.4.3 Controlling enabling/disabling of interrupts in user processes

User applications use the EI function (or EI instruction) and DI function (or DI instruction) to manipulate interrupts. In a task or other user process, using the DI function disables all maskable interrupts from being accepted; using the EI function enables maskable interrupts to be accepted in accordance with the state of the "ISP1" and "ISP0" bits.

The RI78V4 sets whether interrupts are enabled or disabled upon start of the user process. The states are listed below.

Table 9-2 States Enabling and Disabling Interrupts upon Process Start

Process to Start

IE

ISP1

ISP0

Interrupt Enabled/Disabled on Start

Initialization routine

0

1

1

Interrupts disabled (behavior is not guaranteed when it is enabled by the process)

Idle routine

1

1

1

Interrupts enabled; all interrupt levels accepted

Task

When interrupts specified as enabled

1

1

1

Interrupts enabled; all interrupt levels accepted

When interrupts specified as disabled

0

1

1

Interrupts disabled (if enabled, all interrupt levels accepted)

Cyclic handler

When a level-2 interrupt occurs

1

0

1

Interrupts enabled; level-0 and level-1 levels accepted

When a level-3 interrupt occurs

1

1

0

Interrupts enabled; level-0, level-1, and level-2 levels accepted

Interrupt handler

When a level-2 interrupt occurs

1

0

1

Interrupts enabled; level-0 and level-1 levels accepted

When a level-3 interrupt occurs

1

1

0

Interrupts enabled; level-0, level-1, and level-2 levels accepted

Interrupt servicing

When a level-0 interrupt occurs

0

0

0

Interrupts disabled (if enabled, a lelvel-0 interrupt accepted)

When a level-1 interrupt occurs

0

0

0

Interrupts disabled (if enabled, a lelvel-0 interrupt accepted)

When a level-2 interrupt occurs

0

0

1

Interrupts disabled (if enabled, lelvel-0 and lebel-1 interrupts accepted)

When a level-3 interrupt occurs

0

1

0

Interrupts disabled (if enabled, lelvel-0, level-1, and lebel-2 interrupts accepted)



Note that a separate "IE" state is maintained for each task. If a suspended task is resumed, the IE state before suspension is restored.

9.5 Multiple Interrupts

The reoccurrence of an interrupt within an interrupt handler is called "multiple interrupt".

The following shows the flow of the processing for handling multiple interrupts.

Figure 9-3 Multiple Interrupts



When control moves to an interrupt handler, then the state changes to acceptance of maskable interrupts enabled ("IE = 1"). For this reason, multiple interrupts are generally accepted from interrupt handlers. Multiple interrupts are likewise accepted from timer interrupts and cyclic handlers called from them.

When control moves to an interrupt process, then the state changes to acceptance of maskable interrupts disabled (because the RI78V4 does not mediate, the behavior is in accordance with that of the microcontroller). For this reason, multiple interrupts are generally not accepted from interrupt processes. To enable the acceptance of multiple interrupts, it is necessary to call the EI function from the interrupt process. It is not allowed to accept multiple interrupt handlers from an interrupt process, and behavior is not guaranteed if this occurs.

If a user application enables multiple interrupts, then it is necessary to set the interrupt level of the interrupt handler/process as shown below.

Table 9-3 Settable Interrupt Level (Enabling Multiple Interrupts from User Application)

Interrupt Handler

Interrupt Servicing

Interrupt level 0

Not available

Available

Interrupt level 1

Not available

Available

Interrupt level 2

Available

Not available

Interrupt level 3

Available

Not available



If a user application disables multiple interrupts, then it is necessary to set the interrupt level of the interrupt handler/process to one of the patterns shown below.

Pattern 1: Set the level of all interrupt handlers and interrupt processes to 2.

Pattern 2: Set the level of all interrupt handlers and interrupt processes to 3.

Pattern 3: Set the level of all interrupt handlers and to 2, and the level of all interrupt processes to either 2 or 3. Interrupts are disabled during an interrupt process with an interrupt level of 3 (IE = 0).

Table 9-4 Settable Interrupt Level (Disabling Multiple Interrupts from User Application)

Pattern 1

Pattern 2

Pattern 3

Interrupt Handler

Interrupt Servicing

Interrupt Handler

Interrupt Servicing

Interrupt Handler

Interrupt Servicing

Interrupt level 0

Not available

Not available

Not available

Not available

Not available

Not available

Interrupt level 1

Not available

Not available

Not available

Not available

Not available

Not available

Interrupt level 2

Available

Available

Not available

Not available

Available

Available

Interrupt level 3

Not available

Not available

Available

Available

Not available

Available (*)



(*) Interrupts are disabled during this interrupt process (IE = 0).