Manual

Interrupt Handling
The call to cyg_interrupt_create simply fills in a kernel data structure. A typical next step is to call
cyg_interrupt_attach using the handle returned by the create operation. This makes it possible to have
several different interrupt handlers for a given vector, attaching whichever one is currently appropriate.
Replacing an interrupt handler requires a call to cyg_interrupt_detach, followed by another call to
cyg_interrupt_attach for the replacement handler. cyg_interrupt_delete can be used if an interrupt
handler is no longer required.
Some hardware may allow for further control over specific interrupts, for example whether an interrupt is level or
edge triggered. Any such hardware functionality can be accessed using cyg_interrupt_configure: the level
argument selects between level versus edge triggered; the up argument selects between high and low level, or
between rising and falling edges.
Usually interrupt handlers are created, attached and configured during system initialization, while global interrupts
are still disabled. On most hardware it will also be necessary to call cyg_interrupt_unmask, since the sensible
default for interrupt masking is to ignore any interrupts for which no handler is installed.
Controlling Interrupts
eCos provides two ways of controlling whether or not interrupts happen. It is possible to disable and reenable all
interrupts globally, using cyg_interrupt_disable and cyg_interrupt_enable. Typically this works by ma-
nipulating state inside the cpu itself, for example setting a flag in a status register or executing special instructions.
Alternatively it may be possible to mask a specific interrupt source by writing to one or to several interrupt mask
registers. Hardware-specific documentation should be consulted for the exact details of how interrupt masking
works, because a full implementation is not possible on all hardware.
The primary use for these functions is to allow data to be shared between ISRs and other code such as DSRs or
threads. If both a thread and an ISR need to manipulate either a data structure or the hardware itself, there is a
possible conflict if an interrupt happens just when the thread is doing such manipulation. Problems can be avoided
by the thread either disabling or masking interrupts during the critical region. If this critical region requires only
a few instructions then usually it is more efficient to disable interrupts. For larger critical regions it may be more
appropriate to use interrupt masking, allowing other interrupts to occur. There are other uses for interrupt masking.
For example if a device is not currently being used by the application then it may be desirable to mask all interrupts
generated by that device.
There are two functions for masking a specific interrupt source, cyg_interrupt_mask and
cyg_interrupt_mask_intunsafe. On typical hardware masking an interrupt is not an atomic operation,
so if two threads were to perform interrupt masking operations at the same time there could be problems.
cyg_interrupt_mask disables all interrupts while it manipulates the interrupt mask. In situations where
interrupts are already know to be disabled, cyg_interrupt_mask_intunsafe can be used instead. There are
matching functions cyg_interrupt_unmask and cyg_interrupt_unmask_intsafe.
SMP Support
On SMP systems the kernel provides an additional two functions related to interrupt handling.
cyg_interrupt_set_cpu specifies that a particular hardware interrupt should always be handled on one specific
processor in the system. In other words when the interrupt triggers it is only that processor which detects it, and it
is only on that processor that the VSR and ISR will run. If a DSR is requested then it will also run on the same
CPU. The function cyg_interrupt_get_cpu can be used to find out which interrupts are handled on which
processor.
90