📄 drv_api.c
字号:
// Signal a condition variable. This sets the wait member to zero, which
// has no effect when there is no waiter, but will wake up any waiting
// thread.
externC void cyg_drv_cond_signal( cyg_drv_cond_t *cond )
{
CYG_REPORT_FUNCTION();
cond->wait = 0;
CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
// Broadcast to condition variable. This is exactly the same a signal since
// there can only be one waiter.
externC void cyg_drv_cond_broadcast( cyg_drv_cond_t *cond )
{
CYG_REPORT_FUNCTION();
cond->wait = 0;
CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
// Spinlock support.
// Since we can only support a single CPU in this version of the API, we only
// set and clear the lock variable to keep track of what's happening.
void cyg_drv_spinlock_init(
cyg_drv_spinlock_t *lock, /* spinlock to initialize */
cyg_bool_t locked /* init locked or unlocked */
)
{
CYG_REPORT_FUNCTION();
lock->lock = locked;
CYG_REPORT_RETURN();
}
void cyg_drv_spinlock_destroy( cyg_drv_spinlock_t *lock )
{
CYG_REPORT_FUNCTION();
lock->lock = -1;
CYG_REPORT_RETURN();
}
void cyg_drv_spinlock_spin( cyg_drv_spinlock_t *lock )
{
CYG_REPORT_FUNCTION();
CYG_ASSERT( lock->lock == 0 , "Trying to lock locked spinlock");
lock->lock = 1;
CYG_REPORT_RETURN();
}
void cyg_drv_spinlock_clear( cyg_drv_spinlock_t *lock )
{
CYG_REPORT_FUNCTION();
CYG_ASSERT( lock->lock == 1 , "Trying to clear cleared spinlock");
lock->lock = 0;
CYG_REPORT_RETURN();
}
cyg_bool_t cyg_drv_spinlock_try( cyg_drv_spinlock_t *lock )
{
cyg_bool_t result = true;
CYG_REPORT_FUNCTION();
if( lock->lock == 1 ) result = false;
lock->lock = 1;
CYG_REPORT_RETURN();
return result;
}
cyg_bool_t cyg_drv_spinlock_test( cyg_drv_spinlock_t *lock )
{
cyg_bool_t result = true;
CYG_REPORT_FUNCTION();
if( lock->lock == 1 ) result = false;
CYG_REPORT_RETURN();
return result;
}
void cyg_drv_spinlock_spin_intsave( cyg_drv_spinlock_t *lock,
cyg_addrword_t *istate )
{
CYG_REPORT_FUNCTION();
HAL_DISABLE_INTERRUPTS( *istate );
lock->lock = 1;
CYG_REPORT_RETURN();
}
void cyg_drv_spinlock_clear_intsave( cyg_drv_spinlock_t *lock,
cyg_addrword_t istate )
{
CYG_REPORT_FUNCTION();
lock->lock = 0;
HAL_RESTORE_INTERRUPTS( istate );
CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
// Create an interrupt object.
externC 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
)
{
CYG_REPORT_FUNCTION();
intr->vector = vector;
intr->priority = priority;
intr->isr = isr;
intr->dsr = dsr;
intr->data = data;
intr->next_dsr = NULL;
intr->dsr_count = 0;
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
intr->next = NULL;
#endif
*handle = (cyg_handle_t)intr;
CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
// Delete an interrupt object. This merely ensures that it is detached from
// the vector.
externC void cyg_drv_interrupt_delete( cyg_handle_t interrupt )
{
CYG_REPORT_FUNCTION();
cyg_drv_interrupt_detach( interrupt );
CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
//
externC void cyg_drv_interrupt_attach( cyg_handle_t interrupt )
{
cyg_interrupt *intr = (cyg_interrupt *)interrupt;
CYG_REPORT_FUNCTION();
CYG_ASSERT( intr->vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
CYG_ASSERT( intr->vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
HAL_INTERRUPT_SET_LEVEL( intr->vector, intr->priority );
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
CYG_ASSERT( intr->next == NULL , "cyg_interrupt already on a list");
{
cyg_uint32 index;
HAL_TRANSLATE_VECTOR( intr->vector, index );
if( chain_list[index] == NULL )
{
// First Interrupt on this chain, just assign it and
// register the chain_isr with the HAL.
chain_list[index] = intr;
HAL_INTERRUPT_ATTACH( intr->vector, chain_isr,
&chain_list[index], NULL );
}
else
{
// There are already interrupts chained, add this one into
// the chain in priority order.
cyg_interrupt **p = &chain_list[index];
while( *p != NULL )
{
cyg_interrupt *n = *p;
if( n->priority < intr->priority ) break;
p = &n->next;
}
intr->next = *p;
*p = intr;
}
}
#else
HAL_INTERRUPT_ATTACH( intr->vector, intr->isr, intr->data, intr );
#endif
CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
// Detach an interrupt from its vector.
externC void cyg_drv_interrupt_detach( cyg_handle_t interrupt )
{
cyg_interrupt *intr = (cyg_interrupt *)interrupt;
CYG_REPORT_FUNCTION();
CYG_ASSERT( intr->vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
CYG_ASSERT( intr->vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
// Remove the interrupt object from the vector chain.
{
cyg_uint32 index;
cyg_interrupt **p;
HAL_TRANSLATE_VECTOR( intr->vector, index );
p = &chain_list[index];
while( *p != NULL )
{
cyg_interrupt *n = *p;
if( n == intr )
{
*p = intr->next;
break;
}
p = &n->next;
}
// If this was the last one, detach the vector.
if( chain_list[index] == NULL )
HAL_INTERRUPT_DETACH( intr->vector, chain_isr );
}
#else
HAL_INTERRUPT_DETACH( intr->vector, intr->isr );
#endif
CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
// Mask delivery of an interrupt at the interrupt controller.
// (Interrupt safe)
externC void cyg_drv_interrupt_mask( cyg_vector_t vector )
{
CYG_INTERRUPT_STATE old_ints;
CYG_REPORT_FUNCTION();
CYG_REPORT_FUNCARG1("vector=%d", vector);
CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
HAL_DISABLE_INTERRUPTS(old_ints);
HAL_INTERRUPT_MASK( vector );
HAL_RESTORE_INTERRUPTS(old_ints);
CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
// Mask delivery of an interrupt at the interrupt controller.
// (Not interrupt safe)
externC void cyg_drv_interrupt_mask_intunsafe( cyg_vector_t vector )
{
CYG_REPORT_FUNCTION();
CYG_REPORT_FUNCARG1("vector=%d", vector);
CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
HAL_INTERRUPT_MASK( vector );
CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
// Unmask delivery of an interrupt at the interrupt controller.
// (Interrupt safe)
externC void cyg_drv_interrupt_unmask( cyg_vector_t vector )
{
CYG_INTERRUPT_STATE old_ints;
CYG_REPORT_FUNCTION();
CYG_REPORT_FUNCARG1("vector=%d", vector);
CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
HAL_DISABLE_INTERRUPTS(old_ints);
HAL_INTERRUPT_UNMASK( vector );
HAL_RESTORE_INTERRUPTS(old_ints);
CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
// Unmask delivery of an interrupt at the interrupt controller.
// (Not interrupt safe)
externC void cyg_drv_interrupt_unmask_intunsafe( cyg_vector_t vector )
{
CYG_REPORT_FUNCTION();
CYG_REPORT_FUNCARG1("vector=%d", vector);
CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
HAL_INTERRUPT_UNMASK( vector );
CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
// Acknowledge an interrupt at the controller to allow another interrupt
// to be delivered.
externC void cyg_drv_interrupt_acknowledge( cyg_vector_t vector )
{
// CYG_REPORT_FUNCTION();
CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
HAL_INTERRUPT_ACKNOWLEDGE( vector );
// CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
// Configure interrupt detection parameters.
externC void cyg_drv_interrupt_configure(
cyg_vector_t vector,
cyg_bool_t level,
cyg_bool_t up
)
{
CYG_REPORT_FUNCTION();
CYG_REPORT_FUNCARG3("vector = %d, level = %d, up = %d", vector, level,
up);
CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
HAL_INTERRUPT_CONFIGURE( vector, level, up );
CYG_REPORT_RETURN();
}
//--------------------------------------------------------------------------
// Configure interrupt priority level.
externC void cyg_drv_interrupt_level( cyg_vector_t vector, cyg_priority_t level )
{
CYG_REPORT_FUNCTION();
CYG_REPORT_FUNCARG2("vector = %d, level = %d", vector, level);
CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
HAL_INTERRUPT_SET_LEVEL( vector, level );
CYG_REPORT_RETURN();
}
// -------------------------------------------------------------------------
// CPU interrupt routing
externC void cyg_drv_interrupt_set_cpu( cyg_vector_t vector, cyg_cpu_t cpu )
{
CYG_REPORT_FUNCTION();
CYG_REPORT_FUNCARG2("vector = %d, cpu = %d", vector, cpu);
CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
#ifdef CYGPKG_HAL_SMP_SUPPORT
HAL_INTERRUPT_SET_CPU( vector, cpu );
#endif
CYG_REPORT_RETURN();
}
externC cyg_cpu_t cyg_drv_interrupt_get_cpu( cyg_vector_t vector )
{
cyg_cpu_t cpu = 0;
CYG_REPORT_FUNCTION();
CYG_REPORT_FUNCARG1("vector = %d", vector);
CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
#ifdef CYGPKG_HAL_SMP_SUPPORT
HAL_INTERRUPT_GET_CPU( vector, cpu );
#endif
CYG_REPORT_RETURN();
return cpu;
}
// -------------------------------------------------------------------------
// Exception delivery function called from the HAL as a result of a
// hardware exception being raised.
externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data )
{
CYG_FAIL(" !!! Exception !!! ");
}
#endif
//--------------------------------------------------------------------------
// EOF drv_api.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -