This section details the Driver Kernel Interface. Note that most of these functions are identical to Kernel C API calls, and will in most configurations be wrappers for them. In non-kernel configurations they will be supported directly by the HAL, or by code to emulate the required behavior.
This API is defined in the header file <cyg/hal/drv_api.h>.
void cyg_drv_isr_lock() |
None
None
ISR
Disables delivery of interrupts, preventing all ISRs running. This function maintains a counter of the number of times it is called.
void cyg_drv_isr_unlock() |
None
None
ISR
Re-enables delivery of interrupts, allowing ISRs to
run. This function decrements the counter maintained by
cyg_drv_isr_lock()
, and only re-allows
interrupts when it goes to zero.
void cyg_drv_spinlock_init(cyg_spinlock_t *lock, cyg_bool_t locked ) |
lock
- pointer to spinlock to initialize
locked
- initial state of lock
None
Thread
Initialize a spinlock. The locked
argument indicates how the spinlock should be initialized:
TRUE for locked or FALSE
for unlocked state.
void cyg_drv_spinlock_destroy(cyg_spinlock_t *lock ) |
lock
- pointer to spinlock destroy
None
Thread
Destroy a spinlock that is no longer of use. There should be no CPUs attempting to claim the lock at the time this function is called, otherwise the behavior is undefined.
void cyg_drv_spinlock_spin(cyg_spinlock_t *lock ) |
lock
- pointer to spinlock to claim
None
ISR
Claim a spinlock, waiting in a busy loop until it is
available. Wherever this is called from, this operation
effectively pauses the CPU until it succeeds. This operations
should therefore be used sparingly, and in situations where
deadlocks/livelocks cannot occur. Also see
cyg_drv_spinlock_spin_intsave()
.
void cyg_drv_spinlock_clear(cyg_spinlock_t *lock ) |
lock
- pointer to spinlock to clear
None
ISR
Clear a spinlock. This clears the spinlock and allows another
CPU to claim it. If there is more than one CPU waiting in
cyg_drv_spinlock_spin()
then just one of
them will be allowed to proceed.
cyg_bool_t cyg_drv_spinlock_try(cyg_spinlock_t *lock ) |
lock
- pointer to spinlock to try
TRUE if the spinlock was claimed, FALSE otherwise.
ISR
Try to claim the spinlock without waiting. If the spinlock could be claimed immediately then TRUE is returned. If the spinlock is already claimed then the result is FALSE.
cyg_bool_t cyg_drv_spinlock_test(cyg_spinlock_t *lock ) |
lock
- pointer to spinlock to test
TRUE if the spinlock is available, FALSE otherwise.
ISR
Inspect the state of the spinlock. If the spinlock is not locked then the result is TRUE. If it is locked then the result will be FALSE.
void cyg_drv_spinlock_spin_intsave(cyg_spinlock_t *lock, cyg_addrword_t *istate ) |
lock
- pointer to spinlock to claim
istate
- pointer to interrupt state save location
None
ISR
This function behaves exactly like
cyg_drv_spinlock_spin()
except that it also
disables interrupts before attempting to claim the lock. The
current interrupt enable state is saved in
*istate
. Interrupts remain disabled once
the spinlock had been claimed and must be restored by calling
cyg_drv_spinlock_clear_intsave()
.
In general, device drivers should use this function to claim and
release spinlocks rather than the
non-_intsave()
variants, to ensure proper
exclusion with code running on both other CPUs and this CPU.
void cyg_drv_spinlock_clear_intsave( cyg_spinlock_t *lock, cyg_addrword_t istate ) |
lock
- pointer to spinlock to clear
istate
- interrupt state to restore
None
ISR
This function behaves exactly like
cyg_drv_spinlock_clear()
except that it
also restores an interrupt state saved by
cyg_drv_spinlock_spin_intsave()
. The
istate
argument must have been
initialized by a previous call to
cyg_drv_spinlock_spin_intsave()
.
void cyg_drv_dsr_lock() |
None
None
DSR
Disables scheduling of DSRs. This function maintains a counter of the number of times it has been called.
void cyg_drv_dsr_unlock() |
None
None
DSR
Re-enables scheduling of DSRs. This function decrements
the counter incremented by
cyg_drv_dsr_lock()
. DSRs are only allowed
to be delivered when the counter goes to zero.
void cyg_drv_mutex_init(cyg_drv_mutex_t *mutex) |
mutex
- pointer to mutex to initialize
None
Thread
Initialize the mutex pointed to by the mutex argument.
void cyg_drv_mutex_destroy( cyg_drv_mutex_t *mutex ) |
mutex
- pointer to mutex to destroy
None
Thread
Destroy the mutex pointed to by the
mutex
argument. The mutex should be unlocked
and there should be no threads waiting to lock it when this call
in made.
cyg_bool cyg_drv_mutex_lock( cyg_drv_mutex_t *mutex ) |
mutex
- pointer to mutex to lock
TRUE it the thread has claimed the lock, FALSE otherwise.
Thread
Attempt to lock the mutex pointed to by the
mutex
argument. If the mutex is already
locked by another thread then this thread will wait until that
thread is finished. If the result from this function is
FALSE then the thread was broken out of its
wait by some other thread. In this case the mutex will not have
been locked.
cyg_bool cyg_drv_mutex_trylock( cyg_drv_mutex_t *mutex ) |
mutex
- pointer to mutex to lock
TRUE if the mutex has been locked, FALSE otherwise.
Thread
Attempt to lock the mutex pointed to by the
mutex
argument without waiting. If the
mutex is already locked by some other thread then this function
returns FALSE. If the function can lock the
mutex without waiting, then TRUE is
returned.
void cyg_drv_mutex_unlock( cyg_drv_mutex_t *mutex ) |
mutex
- pointer to mutex to unlock
None
Thread
Unlock the mutex pointed to by the
mutex
argument. If there are any threads
waiting to claim the lock, one of them is woken up to try and
claim it.
void cyg_drv_mutex_release( cyg_drv_mutex_t *mutex ) |
mutex - pointer to mutex to release
None
Thread
Release all threads waiting on the mutex pointed to by the
mutex
argument. These threads will return
from cyg_drv_mutex_lock()
with a
FALSE result and will not have claimed the
mutex. This function has no effect on any thread that may have
the mutex claimed.
void cyg_drv_cond_init( cyg_drv_cond_t *cond, cyg_drv_mutex_t *mutex ) |
cond
- condition variable to initialize
mutex
- mutex to associate with this condition variable
None
Thread
Initialize the condition variable pointed to by the
cond
argument. The
mutex
argument must point to a mutex with
which this condition variable is associated. A thread may only
wait on this condition variable when it has already locked the
associated mutex. Waiting will cause the mutex to be unlocked,
and when the thread is reawakened, it will automatically claim
the mutex before continuing.
void cyg_drv_cond_destroy( cyg_drv_cond_t *cond ) |
cond
- condition variable to destroy
None
Thread
Destroy the condition variable pointed to by the
cond
argument.
void cyg_drv_cond_wait( cyg_drv_cond_t *cond ) |
cond
- condition variable to wait on
None
Thread
Wait for a signal on the condition variable pointed to by
the cond
argument. The thread must have
locked the associated mutex, supplied in
cyg_drv_cond_init()
, before waiting on this
condition variable. While the thread waits, the mutex will be
unlocked, and will be re-locked before this function returns. It
is possible for threads waiting on a condition variable to
occasionally wake up spuriously. For this reason it is necessary
to use this function in a loop that re-tests the condition each
time it returns. Note that this function performs an implicit
scheduler unlock/relock sequence, so that it may be used within
an explicit
cyg_drv_dsr_lock()...cyg_drv_dsr_unlock()
structure.
void cyg_drv_cond_signal( cyg_drv_cond_t *cond ) |
cond
- condition variable to signal
None
DSR
Signal the condition variable pointed to by the cond
argument. If there are any threads waiting on this variable at
least one of them will be awakened. Note that in some
configurations there may not be any difference between this
function and cyg_drv_cond_broadcast()
.
void cyg_drv_cond_broadcast( cyg_drv_cond_t *cond ) |
cond
- condition variable to broadcast to
None
DSR
Signal the condition variable pointed to by the
cond
argument. If there are any threads
waiting on this variable they will all be awakened.
void cyg_drv_interrupt_create( cyg_vector_t vector, cyg_priority_t priority, cyg_addrword_t data, cyg_ISR_t *isr, cyg_DSR_t *dsr, cyg_handle_t *handle, cyg_interrupt *intr ) |
vector
- vector to attach to
priority
- queuing priority
data
- data pointer
isr
- interrupt service routine
dsr
- deferred service routine
handle
- returned handle
intr
- put interrupt object here
None
Thread
Create an interrupt object and returns a handle to it. The
object contains information about which interrupt vector to use
and the ISR and DSR that will be called after the interrupt
object is attached to the vector. The interrupt object will be
allocated in the memory passed in the
intr
parameter. The interrupt object is
not immediately attached; it must be attached with the
cyg_interrupt_attach()
call.
void cyg_drv_interrupt_delete( cyg_handle_t interrupt ) |
interrupt
- interrupt to delete
None
Thread
Detach the interrupt from the vector and free the memory
passed in the intr
argument to
cyg_drv_interrupt_create()
for
reuse.
void cyg_drv_interrupt_attach( cyg_handle_t interrupt ) |
interrupt
- interrupt to attach
None
ISR
Attach the interrupt to the vector so that interrupts will be delivered to the ISR when the interrupt occurs.
void cyg_drv_interrupt_detach( cyg_handle_t interrupt ) |
interrupt
- interrupt to detach
None
ISR
Detach the interrupt from the vector so that interrupts will no longer be delivered to the ISR.
void cyg_drv_interrupt_mask(cyg_vector_t vector ) |
vector
- vector to mask
None
ISR
Program the interrupt controller to stop delivery of interrupts on the given vector. On architectures which implement interrupt priority levels this may also disable all lower priority interrupts.
void cyg_drv_interrupt_mask_intunsafe(cyg_vector_t vector ) |
vector
- vector to mask
None
ISR
Program the interrupt controller to stop delivery of
interrupts on the given vector. On architectures which implement
interrupt priority levels this may also disable all lower
priority interrupts. This version differs from
cyg_drv_interrupt_mask()
in not being
interrupt safe. So in situations where, for example, interrupts
are already known to be disabled, this may be called to avoid
the extra overhead.
void cyg_drv_interrupt_unmask(cyg_vector_t vector ) |
vector
- vector to unmask
None
ISR
Program the interrupt controller to re-allow delivery of
interrupts on the given vector
.
void cyg_drv_interrupt_unmask_intunsafe(cyg_vector_t vector ) |
vector
- vector to unmask
None
ISR
Program the interrupt controller to re-allow delivery of
interrupts on the given vector
. This
version differs from
cyg_drv_interrupt_unmask()
in not being
interrupt safe.
void cyg_drv_interrupt_acknowledge( cyg_vector_t vector ) |
vector
- vector to acknowledge
None
ISR
Perform any processing required at the interrupt
controller and in the CPU to cancel the current interrupt
request on the vector
. An ISR may also
need to program the hardware of the device to prevent an
immediate re-triggering of the interrupt.
void cyg_drv_interrupt_configure( cyg_vector_t vector, cyg_bool_t level, cyg_bool_t up ) |
vector
- vector to configure
level
- level or edge triggered
up
- rising/falling edge, high/low level
None
ISR
Program the interrupt controller with the characteristics
of the interrupt source. The level
argument chooses between level- or edge-triggered
interrupts. The up
argument chooses
between high and low level for level triggered interrupts or
rising and falling edges for edge triggered interrupts. This
function only works with interrupt controllers that can control
these parameters.
void cyg_drv_interrupt_level( cyg_vector_t vector, cyg_priority_t level ) |
vector
- vector to configure
level
- level to set
None
ISR
Program the interrupt controller to deliver the given interrupt at the supplied priority level. This function only works with interrupt controllers that can control this parameter.
void cyg_drv_interrupt_set_cpu( cyg_vector_t vector, cyg_cpu_t cpu ) |
vector
- interrupt vector to route
cpu
- destination CPU
None
ISR
This function causes all interrupts on the given vector to be routed to the specified CPU. Subsequently, all such interrupts will be handled by that CPU. This only works if the underlying hardware is capable of performing this kind of routing. This function does nothing on a single CPU system.
cyg_cpu_t cyg_drv_interrupt_set_cpu( cyg_vector_t vector ) |
vector
- interrupt vector to query
The CPU to which this vector is routed
ISR
In multi-processor systems this function returns the id of the CPU to which interrupts on the given vector are current being delivered. In single CPU systems this function returns zero.
typedef cyg_uint32 cyg_ISR_t( cyg_vector_t vector, cyg_addrword_t data ) |
vector
- vector being delivered
data
- data value supplied by client
Bit mask indicating whether interrupt was handled and whether the DSR should be called.
Interrupt Service Routine definition. A pointer to a
function with this prototype is passed to
cyg_interrupt_create()
when an interrupt
object is created. When an interrupt is delivered the function
will be called with the vector number and the data value that
was passed to cyg_interrupt_create()
.
The return value is a bit mask containing one or both of the following bits:
indicates that the interrupt was handled by this ISR. It is a configuration option whether this will prevent further ISR being run.
causes the DSR that was passed to
cyg_interrupt_create()
to be
scheduled to be called.
typedef void cyg_DSR_t( cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data ) |
vector
- vector being delivered
count
- number of times DSR has been scheduled
data
- data value supplied by client
None
Deferred Service Routine prototype. A pointer to a
function with this prototype is passed to
cyg_interrupt_create()
when an interrupt
object is created. When the ISR requests the scheduling of its
DSR, this function will be called at some later point. In
addition to the vector
and
data
arguments, which will be the same as
those passed to the ISR, this routine is also passed a
count
of the number of times the ISR has
requested that this DSR be scheduled. This counter is zeroed
each time the DSR actually runs, so it indicates how many
interrupts have occurred since it last ran.