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

📄 intr.cxx

📁 eCos1.31版
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      intr/intr.cxx////      Interrupt class implementations////==========================================================================//####COPYRIGHTBEGIN####//                                                                          // -------------------------------------------                              // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in         // compliance with the License.  You may obtain a copy of the License at    // http://www.redhat.com/                                                   //                                                                          // Software distributed under the License is distributed on an "AS IS"      // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the // License for the specific language governing rights and limitations under // the License.                                                             //                                                                          // The Original Code is eCos - Embedded Configurable Operating System,      // released September 30, 1998.                                             //                                                                          // The Initial Developer of the Original Code is Red Hat.                   // Portions created by Red Hat are                                          // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             // All Rights Reserved.                                                     // -------------------------------------------                              //                                                                          //####COPYRIGHTEND####//==========================================================================//#####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>// -------------------------------------------------------------------------// Statics// Interrupt disable counter. Note that this is initialized to 1 since// enable_interrupts() is called in Cyg_Scheduler::start().cyg_int32 Cyg_Interrupt::disable_counter = 1;// -------------------------------------------------------------------------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_INTERRUPTS_DSRS_TABLE_SIZE];cyg_ucount32 Cyg_Interrupt::dsr_table_head = 0;cyg_ucount32 Cyg_Interrupt::dsr_table_tail = 0;#endif#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LISTCyg_Interrupt *Cyg_Interrupt::dsr_list = NULL;#endif// -------------------------------------------------------------------------// Call any pending DSRsvoidCyg_Interrupt::call_pending_DSRs_inner(void){//    CYG_REPORT_FUNCTION();#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE        while( dsr_table_head != dsr_table_tail )    {        Cyg_Interrupt *intr = dsr_table[dsr_table_head];        dsr_table_head++;        if( dsr_table_head >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE )            dsr_table_head = 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 != NULL )    {        Cyg_Interrupt *intr;        cyg_uint32 old_intr;        cyg_count32 count;                HAL_DISABLE_INTERRUPTS(old_intr);                intr = dsr_list;        dsr_list = 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){    HAL_INTERRUPT_STACK_CALL_PENDING_DSRS();}// -------------------------------------------------------------------------voidCyg_Interrupt::post_dsr(void){//    CYG_REPORT_FUNCTION();    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[dsr_table_tail++] = this;    if( dsr_table_tail >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE )        dsr_table_tail = 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;        dsr_list = 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();    // Sometimes we have a NULL intr object pointer.    cyg_vector vector = (intr!=NULL)?intr->vector:0;        CYG_INSTRUMENT_INTR(END, vector, isr_ret);        #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_COUNT];#endif// -------------------------------------------------------------------------// Chaining ISR inserted in HAL vector#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAINcyg_uint32Cyg_Interrupt::chain_isr(cyg_vector vector, CYG_ADDRWORD data)

⌨️ 快捷键说明

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