Exemplo n.º 1
0
void hal_deliver_interrupt( cyg_uint32 vector )
{
    register cyg_uint32 isr_result;
    register cyg_isr *isr;
    cyg_bool pendsvc = false;
    
#if defined(CYGPKG_KERNEL_INSTRUMENT) && \
    defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
    CYG_INSTRUMENT_INTR(RAISE, vector, 0);
#endif

    isr = (cyg_isr *)hal_interrupt_handlers[vector];
    
    // Call the ISR
    isr_result = isr( vector, hal_interrupt_data[vector] );


#if !defined(CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN)
    // If the ISR has returned the CALL_DSR bit, post the DSR and set
    // the pendable SVC exception pending.
    if( isr_result & CYG_ISR_CALL_DSR )
    {
        cyg_interrupt_post_dsr( hal_interrupt_objects[vector] );

        // Post the pendable SVC to call interrupt_end(). But only if
        // the scheduler lock is currently zero. If it is non zero
        // then interrupt_end will do nothing useful, so avoid calling
        // it.
        if( cyg_scheduler_sched_lock == 0 )
            pendsvc = true;
    }
#else
    // When chaining we don't know here whether the nested interrupt
    // has posted a DSR, so we have to run interrupt_end() regardless.
    // However, the same considerations as above regarding the
    // scheduler lock still apply.
    if( cyg_scheduler_sched_lock == 0 )
        pendsvc = true;
#endif

    // Post the pendable SVC if required.
    if( pendsvc )
    {
        cyg_uint32 icsr;
        HAL_READ_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_ICSR, icsr );
        icsr |= CYGARC_REG_NVIC_ICSR_PENDSVSET;
        HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_ICSR, icsr );
    }
}
Exemplo n.º 2
0
static inline cyg_uint32
hal_call_isr (cyg_uint32 vector)
{
    cyg_ISR *isr;
    CYG_ADDRWORD data;
    cyg_uint32 isr_ret;

    isr = (cyg_ISR*) hal_interrupt_handlers[vector];
    data = hal_interrupt_data[vector];

    isr_ret = (*isr) (vector, data);

#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
    if (isr_ret & CYG_ISR_CALL_DSR) {
        cyg_interrupt_post_dsr (hal_interrupt_objects[vector]);
    }
#endif

    return isr_ret & ~CYG_ISR_CALL_DSR;
}