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

📄 intr.cxx

📁 ecos实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      intr/intr.cxx////      Interrupt class implementations////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    nickg// Contributors: nickg// Date:         1999-02-17// Purpose:      Interrupt class implementation// Description:  This file contains the definitions of the interrupt//               class.////####DESCRIPTIONEND####////==========================================================================#include <pkgconf/kernel.h>#include <cyg/kernel/ktypes.h>             // base kernel types#include <cyg/infra/cyg_trac.h>           // tracing macros#include <cyg/infra/cyg_ass.h>            // assertion macros#include <cyg/kernel/instrmnt.h>           // instrumentation#include <cyg/kernel/intr.hxx>             // our header#include <cyg/kernel/sched.hxx>            // scheduler#include <cyg/kernel/sched.inl>// -------------------------------------------------------------------------// Staticsvolatile cyg_int32 Cyg_Interrupt::disable_counter[CYGNUM_KERNEL_CPU_MAX];Cyg_SpinLock Cyg_Interrupt::interrupt_disable_spinlock CYG_INIT_PRIORITY( INTERRUPTS );CYG_INTERRUPT_STATE Cyg_Interrupt::interrupt_disable_state[CYGNUM_KERNEL_CPU_MAX];// -------------------------------------------------------------------------Cyg_Interrupt::Cyg_Interrupt(    cyg_vector      vec,                // Vector to attach to    cyg_priority    pri,                // Queue priority    CYG_ADDRWORD    d,                  // Data pointer    cyg_ISR         *ir,                // Interrupt Service Routine    cyg_DSR         *dr                 // Deferred Service Routine    ){    CYG_REPORT_FUNCTION();    CYG_REPORT_FUNCARG5("vector=%d, priority=%d, data=%08x, isr=%08x, "                        "dsr=%08x", vec, pri, d, ir, dr);        vector      = vec;    priority    = pri;    isr         = ir;    dsr         = dr;    data        = d;#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST    dsr_count   = 0;    next_dsr    = NULL;#endif#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN    next        = NULL;    #endif    CYG_REPORT_RETURN();    };// -------------------------------------------------------------------------Cyg_Interrupt::~Cyg_Interrupt(){    CYG_REPORT_FUNCTION();    detach();    CYG_REPORT_RETURN();};// -------------------------------------------------------------------------// DSR handling statics:#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLECyg_Interrupt *Cyg_Interrupt::dsr_table[CYGNUM_KERNEL_CPU_MAX][CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE];cyg_ucount32 Cyg_Interrupt::dsr_table_head[CYGNUM_KERNEL_CPU_MAX];volatile cyg_ucount32 Cyg_Interrupt::dsr_table_tail[CYGNUM_KERNEL_CPU_MAX];#endif#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LISTCyg_Interrupt* volatile Cyg_Interrupt::dsr_list[CYGNUM_KERNEL_CPU_MAX];#endif// -------------------------------------------------------------------------// Call any pending DSRsvoidCyg_Interrupt::call_pending_DSRs_inner(void){//    CYG_REPORT_FUNCTION();    HAL_SMP_CPU_TYPE cpu = CYG_KERNEL_CPU_THIS();    #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE        while( dsr_table_head[cpu] != dsr_table_tail[cpu] )    {        Cyg_Interrupt *intr = dsr_table[cpu][dsr_table_head[cpu]];        dsr_table_head[cpu]++;        if( dsr_table_head[cpu] >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE )            dsr_table_head[cpu] = 0;        CYG_INSTRUMENT_INTR(CALL_DSR, intr->vector, 0);                CYG_ASSERT( intr->dsr != NULL , "No DSR defined");        intr->dsr( intr->vector, 1, (CYG_ADDRWORD)intr->data );    }    #endif#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST    while( dsr_list[cpu] != NULL )    {        Cyg_Interrupt* intr;        cyg_uint32 old_intr;        cyg_count32 count;                HAL_DISABLE_INTERRUPTS(old_intr);                intr = dsr_list[cpu];        dsr_list[cpu] = intr->next_dsr;        count = intr->dsr_count;        intr->dsr_count = 0;                HAL_RESTORE_INTERRUPTS(old_intr);                CYG_ASSERT( intr->dsr != NULL , "No DSR defined");        intr->dsr( intr->vector, count, (CYG_ADDRWORD)intr->data );            }    #endif    };externC voidcyg_interrupt_call_pending_DSRs(void){    Cyg_Interrupt::call_pending_DSRs_inner();}//// Use HAL supported function to run through the DSRs, but executing using// the separate interrupt stack if available.  This function calls back// into this module via 'cyg_interrupt_call_pending_DSRs' above, to keep// the whole process as general as possible.voidCyg_Interrupt::call_pending_DSRs(void){    CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1,                "DSRs being called with sched_lock not equal to 1");    HAL_INTERRUPT_STACK_CALL_PENDING_DSRS();}// -------------------------------------------------------------------------voidCyg_Interrupt::post_dsr(void){//    CYG_REPORT_FUNCTION();    HAL_SMP_CPU_TYPE cpu = CYG_KERNEL_CPU_THIS();        CYG_INSTRUMENT_INTR(POST_DSR, vector, 0);    cyg_uint32 old_intr;    // We need to disable interrupts during this part to    // guard against nested interrupts.        HAL_DISABLE_INTERRUPTS(old_intr);#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE        dsr_table[cpu][dsr_table_tail[cpu]++] = this;    if( dsr_table_tail[cpu] >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE )        dsr_table_tail[cpu] = 0;#endif#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST    // Only add the interrupt to the dsr list if this is    // the first DSR call.    // At present DSRs are pushed onto the list and will be    // called in reverse order. We do not define the order    // in which DSRs are called, so this is acceptable.        if( dsr_count++ == 0 )    {        next_dsr = dsr_list[cpu];        dsr_list[cpu] = this;    }    #endif        HAL_RESTORE_INTERRUPTS(old_intr);    };// -------------------------------------------------------------------------// A C callable interface to Cyg_Interrupt::post_dsr() that can be used from// the HAL.externC voidcyg_interrupt_post_dsr( CYG_ADDRWORD intr_obj ){    Cyg_Interrupt* intr = (Cyg_Interrupt*) intr_obj;    intr->post_dsr ();}// -------------------------------------------------------------------------// FIXME: should have better name - JiflexternC voidinterrupt_end(    cyg_uint32          isr_ret,    Cyg_Interrupt       *intr,    HAL_SavedRegisters  *regs    ){//    CYG_REPORT_FUNCTION();#ifdef CYGPKG_KERNEL_SMP_SUPPORT    Cyg_Scheduler::lock();#endif        // Sometimes we have a NULL intr object pointer.    cyg_vector vector = (intr!=NULL)?intr->vector:0;    CYG_INSTRUMENT_INTR(END, vector, isr_ret);        CYG_UNUSED_PARAM( cyg_vector, vector ); // prevent compiler warning    #ifndef CYGIMP_KERNEL_INTERRUPTS_CHAIN    // Only do this if we are in a non-chained configuration.    // If we are chained, then chain_isr below will do the DSR    // posting.        if( isr_ret & Cyg_Interrupt::CALL_DSR && intr != NULL ) intr->post_dsr();#endif    #ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT    // If we have GDB support enabled, and there is the possibility    // that this thread will be context switched as a result of this    // interrupt, then save the pointer to the saved thread context in    // the thread object so that GDB can get a meaningful context to    // look at.        Cyg_Scheduler::get_current_thread()->set_saved_context(regs);    #endif            // Now unlock the scheduler, which may also call DSRs    // and cause a thread switch to happen.        Cyg_Scheduler::unlock();#ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT    Cyg_Scheduler::get_current_thread()->set_saved_context(0);    #endif            CYG_INSTRUMENT_INTR(RESTORE, vector, 0);    }// -------------------------------------------------------------------------// Interrupt chaining statics.#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAINCyg_Interrupt *Cyg_Interrupt::chain_list[CYGNUM_HAL_ISR_TABLE_SIZE];#endif// -------------------------------------------------------------------------// Chaining ISR inserted in HAL vector#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAINcyg_uint32Cyg_Interrupt::chain_isr(cyg_vector vector, CYG_ADDRWORD data){    Cyg_Interrupt *p = *(Cyg_Interrupt **)data;    register cyg_uint32 isr_ret = 0;    register cyg_uint32 isr_chain_ret = 0;    CYG_INSTRUMENT_INTR(CHAIN_ISR, vector, 0);    while( p != NULL )    {        if( p->vector == vector )        {            isr_ret = p->isr(vector, p->data);            isr_chain_ret |= isr_ret;            if( isr_ret & Cyg_Interrupt::CALL_DSR ) p->post_dsr();            if( isr_ret & Cyg_Interrupt::HANDLED ) break;        }        p = p->next;    }#ifdef HAL_DEFAULT_ISR    if( (isr_chain_ret & (Cyg_Interrupt::HANDLED|Cyg_Interrupt::CALL_DSR)) == 0 )    {        // If we finished the loop for some reason other than that an        // ISR has handled the interrupt, call any default ISR to either        // report the spurious interrupt, or do some other HAL level processing        // such as GDB interrupt detection etc.        HAL_DEFAULT_ISR( vector, 0 );    }#endif        return isr_ret & ~Cyg_Interrupt::CALL_DSR;}#endif// -------------------------------------------------------------------------// Attach an ISR to an interrupt vector.voidCyg_Interrupt::attach(void)

⌨️ 快捷键说明

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