- IAR Embedded Workbench for RX 5.20
- IAR C/C++ Development
- Functions
- Primitives for interrupts, concurrency, and OS-related programming
Primitives for interrupts, concurrency, and OS-related programming
The IAR C/C++ Compiler for RX provides the following primitives related to writing interrupt functions, concurrent functions, and OS-related functions:
The extended keywords:
__interrupt,__nested,__task,__monitorThe pragma directive,
#pragma vectorThe intrinsic functions:
__enable_interrupt,__disable_interrupt.
Interrupt functions
In embedded systems, using interrupts is a method for handling external events immediately; for example, detecting that a button was pressed.
Interrupt service routines
In general, when an interrupt occurs in the code, the microcontroller immediately stops executing the code it runs, and starts executing an interrupt routine instead. It is important that the environment of the interrupted function is restored after the interrupt is handled—this includes the values of processor registers and the processor status register. This makes it possible to continue the execution of the original code after the code that handled the interrupt was executed.
Note that the RX microcontroller supports many interrupt sources. For each interrupt source, an interrupt routine can be written. Each interrupt routine is associated with a vector number, which is specified in the documentation from the chip manufacturer. If you want to handle several different interrupts using the same interrupt routine, you can specify several interrupt vectors.
Interrupt vectors and the interrupt vector table
For the RX microcontroller, the INTB (interrupt table) register points to the start of the interrupt vector table and is placed in the .inttable section. The interrupt vector number is the index into the interrupt vector table.
By default, the vector table is populated with a default interrupt handler which calls the abort function. For each interrupt source that has no explicit interrupt service routine, the default interrupt handler will be called. If you write your own service routine for a specific vector, that routine will override the default interrupt handler.
The header file iodevice.h, where device corresponds to the selected device, contains predefined names for the existing interrupt vectors.
Defining an interrupt function—an example
To define an interrupt function, the __interrupt keyword and the #pragma vector directive can be used. For example:
#include "iorx62n.h"
#pragma vector = VECT_CMT0_CMI0 /* Symbol defined in I/O header file */
__interrupt void MyInterruptRoutine(void)
{
/* Do something */
}Note
An interrupt function must have the return type void, and it cannot specify any parameters.
Interrupt and C++ member functions
Only static member functions can be interrupt functions.
Adding an exception handler
To overload a default exception handler such as an undefined or non-maskable interrupt, you define a user function with one of the names specified in the template file fixedint.c. These are:
__interrupt void __floating_point_handler(); __interrupt void __NMI_handler(); __interrupt void __privileged_handler(); __interrupt void __undefined_handler();
However, __floating_point_handler might already be overloaded with an “unimplemented processing handler” that emulates floating-point for subnormal arguments and results.
To overload the default floating-point exception handler, you must use this special linker mechanism:
If you are not using the unimplemented processing handler described above, specify the linker option:
--redirect __float_placeholder=_my_float_handler
where my_float_handler is the name you choose for this handler.
However, if you are using the unimplemented processing handler described above, specify the linker option:
--redirect __floating_point_handler=_my_float_handler
The unimplemented processing handler will call __floating_point_handler if the exception was not caused by unimplemented processing.