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

📄 intr.cxx

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
{
    CYG_REPORT_FUNCTION();

    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");

    CYG_INSTRUMENT_INTR(ATTACH, vector, 0);

    HAL_INTERRUPT_SET_LEVEL( vector, priority );
    
#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN

    CYG_ASSERT( next == NULL , "Cyg_Interrupt already on a list");

    cyg_uint32 index;

    HAL_TRANSLATE_VECTOR( vector, index );

    if( chain_list[index] == NULL )
    {
        int in_use;
        // First Interrupt on this chain, just assign it and register
        // the chain_isr with the HAL.
        
        chain_list[index] = this;

        HAL_INTERRUPT_IN_USE( vector, in_use );
        CYG_ASSERT( 0 == in_use, "Interrupt vector not free.");
        HAL_INTERRUPT_ATTACH( 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 < priority ) break;
            
            p = &n->next;
        }
        next = *p;
        *p = this;
    }
    
#else
    
    {
        int in_use;


        HAL_INTERRUPT_IN_USE( vector, in_use );
        CYG_ASSERT( 0 == in_use, "Interrupt vector not free.");

        HAL_INTERRUPT_ATTACH( vector, isr, data, this );
    }

#endif    
    CYG_REPORT_RETURN();
}

// -------------------------------------------------------------------------
// Detach the ISR from the vector

void
Cyg_Interrupt::detach(void)
{
    CYG_REPORT_FUNCTION();

    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");    
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");

    CYG_INSTRUMENT_INTR(DETACH, vector, 0);

#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN

    // Remove the interrupt object from the vector chain.
    
    cyg_uint32 index;

    HAL_TRANSLATE_VECTOR( vector, index );

    Cyg_Interrupt **p = &chain_list[index];

    while( *p != NULL )
    {
        Cyg_Interrupt *n = *p;

        if( n == this )
        {
            *p = next;
            break;
        }
            
        p = &n->next;
    }

    // If this was the last one, detach the vector.
    
    if( chain_list[index] == NULL )
        HAL_INTERRUPT_DETACH( vector, chain_isr );
    
#else
    
    HAL_INTERRUPT_DETACH( vector, isr );

#endif

    CYG_REPORT_RETURN();
    
}

// -------------------------------------------------------------------------
// Get the current service routine

void
Cyg_Interrupt::get_vsr(cyg_vector vector, cyg_VSR **vsr)
{
    CYG_REPORT_FUNCTION();
    CYG_REPORT_FUNCARG2("vector = %d, mem to put VSR in is at %08x", vector,
                        vsr);

    CYG_ASSERT( vector >= CYGNUM_HAL_VSR_MIN, "Invalid vector");        
    CYG_ASSERT( vector <= CYGNUM_HAL_VSR_MAX, "Invalid vector");

    HAL_VSR_GET( vector, vsr );

    CYG_REPORT_RETURN();
}

// -------------------------------------------------------------------------
// Install a vector service routine

void
Cyg_Interrupt::set_vsr(cyg_vector vector, cyg_VSR *vsr, cyg_VSR **old)
{
    CYG_REPORT_FUNCTION();

    CYG_REPORT_FUNCARG3( "vector = %d, new vsr is at %08x, mem to put "
                         "old VSR in is at %08x", vector, vsr, old);

    CYG_INSTRUMENT_INTR(SET_VSR, vector, vsr);

    CYG_ASSERT( vector >= CYGNUM_HAL_VSR_MIN, "Invalid vector");    
    CYG_ASSERT( vector <= CYGNUM_HAL_VSR_MAX, "Invalid vector");    

    CYG_INTERRUPT_STATE old_ints;
    
    HAL_DISABLE_INTERRUPTS(old_ints);

    HAL_VSR_SET( vector, vsr, old );
    
    HAL_RESTORE_INTERRUPTS(old_ints);

    CYG_REPORT_RETURN();
}

// -------------------------------------------------------------------------
// Disable interrupts at the CPU


void
Cyg_Interrupt::disable_interrupts(void)
{
    CYG_REPORT_FUNCTION();

    CYG_INSTRUMENT_INTR(DISABLE, disable_counter[CYG_KERNEL_CPU_THIS()]+1, 0);

    HAL_SMP_CPU_TYPE cpu_this = CYG_KERNEL_CPU_THIS();

    // If the disable_counter is zero, disable interrupts and claim the spinlock.
    
    if( 0 == disable_counter[cpu_this] )
    {
        // Claim the spinlock and disable interrupts. We save the original interrupt
        // enable state to restore later.
        interrupt_disable_spinlock.spin_intsave(&interrupt_disable_state[cpu_this]);
    }

    // Now increment our disable counter.
    
    disable_counter[cpu_this]++;
    
    CYG_REPORT_RETURN();
}


// -------------------------------------------------------------------------
// Re-enable CPU interrupts

void
Cyg_Interrupt::enable_interrupts(void)
{
    CYG_REPORT_FUNCTION();
        
    CYG_INSTRUMENT_INTR(ENABLE, disable_counter[CYG_KERNEL_CPU_THIS()], 0);

    HAL_SMP_CPU_TYPE cpu_this = CYG_KERNEL_CPU_THIS();

    CYG_ASSERT( disable_counter[cpu_this] > 0 , "Disable counter not greater than zero");
    
    // If the disable counter goes to zero, then release the spinlock and restore
    // the previous interrupt state.
    
    if( --disable_counter[cpu_this] == 0 )
    {
        interrupt_disable_spinlock.clear_intsave(interrupt_disable_state[cpu_this]);
    }

    CYG_REPORT_RETURN();
}
    
// -------------------------------------------------------------------------
// Mask a specific interrupt in a PIC

void
Cyg_Interrupt::mask_interrupt(cyg_vector 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");

    CYG_INSTRUMENT_INTR(MASK, vector, 0);

    CYG_INTERRUPT_STATE old_ints;
    
    HAL_DISABLE_INTERRUPTS(old_ints);
    HAL_INTERRUPT_MASK( vector );
    HAL_RESTORE_INTERRUPTS(old_ints);

    CYG_REPORT_RETURN();
}

// -------------------------------------------------------------------------
// Mask a specific interrupt in a PIC (but not interrupt safe)

void
Cyg_Interrupt::mask_interrupt_intunsafe(cyg_vector 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");

    CYG_INSTRUMENT_INTR(MASK, vector, 0);

    HAL_INTERRUPT_MASK( vector );

    CYG_REPORT_RETURN();
}

// -------------------------------------------------------------------------
// Clear PIC mask

void
Cyg_Interrupt::unmask_interrupt(cyg_vector vector)
{
    CYG_REPORT_FUNCTION();

    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");    
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
    
    CYG_INSTRUMENT_INTR(UNMASK, vector, 0);

    CYG_INTERRUPT_STATE old_ints;
    
    HAL_DISABLE_INTERRUPTS(old_ints);
    HAL_INTERRUPT_UNMASK( vector );
    HAL_RESTORE_INTERRUPTS(old_ints);

    CYG_REPORT_RETURN();
}
    

// -------------------------------------------------------------------------
// Clear PIC mask (but not interrupt safe)

void
Cyg_Interrupt::unmask_interrupt_intunsafe(cyg_vector vector)
{
    CYG_REPORT_FUNCTION();

    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");    
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
    
    CYG_INSTRUMENT_INTR(UNMASK, vector, 0);

    HAL_INTERRUPT_UNMASK( vector );

    CYG_REPORT_RETURN();
}
    

// -------------------------------------------------------------------------
// Acknowledge interrupt at PIC

void
Cyg_Interrupt::acknowledge_interrupt(cyg_vector vector)
{
//    CYG_REPORT_FUNCTION();

    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");    
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");

    CYG_INSTRUMENT_INTR(ACK, vector, 0);

    HAL_INTERRUPT_ACKNOWLEDGE( vector );
}

// -------------------------------------------------------------------------
// Change interrupt detection at PIC

void
Cyg_Interrupt::configure_interrupt(
    cyg_vector vector,              // vector to control
    cyg_bool level,                 // level or edge triggered
    cyg_bool up                     // hi/lo level, rising/falling edge
    )
{
    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");

    CYG_INSTRUMENT_INTR(CONFIGURE, vector, (level<<1)|up);

    HAL_INTERRUPT_CONFIGURE( vector, level, up );

    CYG_REPORT_RETURN();
}

// -------------------------------------------------------------------------
// SMP support for setting/getting interrupt CPU

#ifdef CYGPKG_KERNEL_SMP_SUPPORT

void
Cyg_Interrupt::set_cpu(
    cyg_vector vector,              // vector to control
    HAL_SMP_CPU_TYPE cpu            // CPU to set
    )
{
    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");

    CYG_INSTRUMENT_INTR(SET_CPU, vector, cpu);

    HAL_INTERRUPT_SET_CPU( vector, cpu );

    CYG_REPORT_RETURN();
}

HAL_SMP_CPU_TYPE
Cyg_Interrupt::get_cpu(
    cyg_vector vector              // vector to control
    )
{
    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_SMP_CPU_TYPE cpu = 0;
    
    HAL_INTERRUPT_GET_CPU( vector, cpu );

    CYG_INSTRUMENT_INTR(GET_CPU, vector, cpu);
    
    CYG_REPORT_RETURN();

    return cpu;
}

#endif

// -------------------------------------------------------------------------
// EOF intr/intr.cxx

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -