⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drv_api.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
// 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 + -