These interfaces contain definitions related to interrupt
handling. They include definitions of exception and interrupt numbers,
interrupt enabling and masking.
These definitions are normally found in
cyg/hal/hal_intr.h. This file is supplied by the
architecture HAL. Any variant or platform specific definitions will
be found in cyg/hal/var_intr.h,
cyg/hal/plf_intr.h or
cyg/hal/hal_platform_ints.h in the variant or platform
HAL, depending on the exact target. These files are include
automatically by this header, so need not be included explicitly.
CYGNUM_HAL_VECTOR_XXXX
CYGNUM_HAL_VSR_MIN
CYGNUM_HAL_VSR_MAX
CYGNUM_HAL_VSR_COUNT
CYGNUM_HAL_INTERRUPT_XXXX
CYGNUM_HAL_ISR_MIN
CYGNUM_HAL_ISR_MAX
CYGNUM_HAL_ISR_COUNT
CYGNUM_HAL_EXCEPTION_XXXX
CYGNUM_HAL_EXCEPTION_MIN
CYGNUM_HAL_EXCEPTION_MAX
CYGNUM_HAL_EXCEPTION_COUNT |
All possible VSR, interrupt and exception vectors are specified here,
together with maximum and minimum values for range checking. While the
VSR and exception numbers will be defined in this file, the interrupt
numbers will normally be defined in the variant or platform HAL file
that is included by this header.
There are two ranges of numbers, those for the vector service
routines and those for the interrupt service routines. The relationship
between these two ranges is undefined, and no equivalence should
be assumed if vectors from the two ranges coincide.
The VSR vectors correspond to the set of exception vectors that can be
delivered by the CPU architecture, many of these will be internal
exception traps. The ISR vectors correspond to the set of external
interrupts that can be delivered and are usually determined by extra
decoding of the interrupt controller by the interrupt VSR.
Where a CPU supports synchronous exceptions, the range of such
exceptions allowed are defined by CYGNUM_HAL_EXCEPTION_MIN and
CYGNUM_HAL_EXCEPTION_MAX. The
CYGNUM_HAL_EXCEPTION_XXXX definitions are
standard names used by target independent code to test for the
presence of particular exceptions in the architecture. The actual
exception numbers will normally correspond to the VSR exception
range. In future other exceptions generated by the system software
(such as stack overflow) may be added.
CYGNUM_HAL_ISR_COUNT, CYGNUM_HAL_VSR_COUNT and
CYGNUM_HAL_EXCEPTION_COUNT define the number of
ISRs, VSRs and EXCEPTIONs respectively for the purposes of defining
arrays etc. There might be a translation from the supplied vector
numbers into array offsets. Hence
CYGNUM_HAL_XXX_COUNT may not simply be
CYGNUM_HAL_XXX_MAX - CYGNUM_HAL_XXX_MIN or CYGNUM_HAL_XXX_MAX+1.
CYG_INTERRUPT_STATE
HAL_DISABLE_INTERRUPTS( old )
HAL_RESTORE_INTERRUPTS( old )
HAL_ENABLE_INTERRUPTS()
HAL_QUERY_INTERRUPTS( state ) |
These macros provide control over the state of the CPUs interrupt mask
mechanism. They should normally manipulate a CPU status register to
enable and disable interrupt delivery. They should not access an
interrupt controller.
CYG_INTERRUPT_STATE is a data type that should be
used to store the interrupt state returned by
HAL_DISABLE_INTERRUPTS() and
HAL_QUERY_INTERRUPTS() and passed to
HAL_RESTORE_INTERRUPTS().
HAL_DISABLE_INTERRUPTS() disables the delivery of
interrupts and stores the original state of the interrupt mask in the
variable passed in the old argument.
HAL_RESTORE_INTERRUPTS() restores the state of
the interrupt mask to that recorded in old.
HAL_ENABLE_INTERRUPTS() simply enables interrupts
regardless of the current state of the mask.
HAL_QUERY_INTERRUPTS() stores the state of the
interrupt mask in the variable passed in the state argument. The state stored here should also be
capable of being passed to
HAL_RESTORE_INTERRUPTS() at a later point.
It is at the HAL implementer’s discretion exactly
which interrupts are masked by this mechanism. Where a CPU has more
than one interrupt type that may be masked separately (e.g. the
ARM's IRQ and FIQ) only those that can raise DSRs need
to be masked here. A separate architecture specific mechanism may
then be used to control the other interrupt types.
HAL_INTERRUPT_IN_USE( vector, state )
HAL_INTERRUPT_ATTACH( vector, isr, data, object )
HAL_INTERRUPT_DETACH( vector, isr )
HAL_VSR_SET( vector, vsr, poldvsr )
HAL_VSR_GET( vector, pvsr )
HAL_VSR_SET_TO_ECOS_HANDLER( vector, poldvsr ) |
These macros manage the attachment of interrupt and vector service
routines to interrupt and exception vectors respectively.
HAL_INTERRUPT_IN_USE() tests the state of the
supplied interrupt vector and sets the value of the state parameter to
either 1 or 0 depending on whether there is already an ISR attached to
the vector. The HAL will only allow one ISR to be attached to each
vector, so it is a good idea to use this function before using
HAL_INTERRUPT_ATTACH().
HAL_INTERRUPT_ATTACH() attaches
the ISR, data pointer and object pointer to the given
vector. When an interrupt occurs on this
vector the ISR is called using the C calling convention and the vector
number and data pointer are passed to it as the first and second
arguments respectively.
HAL_INTERRUPT_DETACH() detaches the ISR from the
vector.
HAL_VSR_SET() replaces the VSR attached to the
vector with the replacement supplied in
vsr. The old VSR is returned in the location
pointed to by pvsr. On some platforms, possibly
only in certain configurations, the table of VSRs will be in read-only
memory. If so then this macro should be left undefined.
HAL_VSR_GET() assigns
a copy of the VSR to the location pointed to by pvsr.
HAL_VSR_SET_TO_ECOS_HANDLER() ensures that the
VSR for a specific exception is pointing at the eCos exception VSR and
not one for RedBoot or some other ROM monitor. The default when
running under RedBoot is for exceptions to be handled by RedBoot and
passed to GDB. This macro diverts the exception to eCos so that it may
be handled by application code. The arguments are the VSR vector to be
replaces, and a location in which to store the old VSR pointer, so
that it may be replaced at a later point. On some platforms, possibly
only in certain configurations, the table of VSRs will be in read-only
memory. If so then this macro should be left undefined.
HAL_INTERRUPT_MASK( vector )
HAL_INTERRUPT_UNMASK( vector )
HAL_INTERRUPT_ACKNOWLEDGE( vector )
HAL_INTERRUPT_CONFIGURE( vector, level, up )
HAL_INTERRUPT_SET_LEVEL( vector, level ) |
These macros exert control over any prioritized interrupt
controller that is present. If no priority controller exists, then
these macros should be empty.
Note: These macros may not be reentrant, so care should be taken to
prevent them being called while interrupts are enabled. This means
that they can be safely used in initialization code before
interrupts are enabled, and in ISRs. In DSRs, ASRs and thread code,
however, interrupts must be disabled before these macros are
called. Here is an example for use in a DSR where the interrupt
source is unmasked after data processing:
...
HAL_DISABLE_INTERRUPTS(old);
HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_ETH);
HAL_RESTORE_INTERRUPTS(old);
... |
HAL_INTERRUPT_MASK() causes the interrupt
associated with the given vector to be blocked.
HAL_INTERRUPT_UNMASK() causes the interrupt
associated with the given vector to be unblocked.
HAL_INTERRUPT_ACKNOWLEDGE() acknowledges the
current interrupt from the given vector. This is usually executed from
the ISR for this vector when it is prepared to allow further
interrupts. Most interrupt controllers need some form of acknowledge
action before the next interrupt is allowed through. Executing this
macro may cause another interrupt to be delivered. Whether this
interrupts the current code depends on the state of the CPU interrupt
mask.
HAL_INTERRUPT_CONFIGURE() provides
control over how an interrupt signal is detected. The arguments
are:
- vector
The interrupt vector to be configured.
- level
Set to true if the interrupt is detected by
level, and false if it is edge triggered.
- up
If the interrupt is set to level detect, then if this is
true it is detected by a high signal level,
and if false by a low signal level. If the
interrupt is set to edge triggered, then if this is
true it is triggered by a rising edge and if
false by a falling edge.
HAL_INTERRUPT_SET_LEVEL() provides control over
the hardware priority of the interrupt. The arguments are:
- vector
The interrupt whose level is to be set.
- level
The priority level to which the interrupt is to set. In some
architectures the masking of an interrupt is achieved by
changing its priority level. Hence this function,
HAL_INTERRUPT_MASK() and
HAL_INTERRUPT_UNMASK() may interfere with
each other.