原创eCos驱动分析 之 ISR是如何与硬件中断联系起来的 转载文章.docx
- 文档编号:29239146
- 上传时间:2023-07-21
- 格式:DOCX
- 页数:10
- 大小:20.54KB
原创eCos驱动分析 之 ISR是如何与硬件中断联系起来的 转载文章.docx
《原创eCos驱动分析 之 ISR是如何与硬件中断联系起来的 转载文章.docx》由会员分享,可在线阅读,更多相关《原创eCos驱动分析 之 ISR是如何与硬件中断联系起来的 转载文章.docx(10页珍藏版)》请在冰豆网上搜索。
原创eCos驱动分析之ISR是如何与硬件中断联系起来的转载文章
(原创)eCos驱动分析之ISR是如何与硬件中断联系起来的---转载文章
要想知道ecos的中断ISR是怎么与硬件中断向量联系起来的,是怎么被调用的?
那就要看下面这两个关键的函数:
cyg_drv_interrupt_create()cyg_drv_interrupt_attach()
这两个函数都声明在cyg/kernel/kapi.h中,其形式如下:
voidcyg_interrupt_create(cyg_vector_tvector,/*Vectortoattachto*/cyg_priority_tpriority,/*Queuepriority*/cyg_addrword_tdata,/*Datapointer*/cyg_ISR_t*isr,/*InterruptServiceRoutine*/cyg_DSR_t*dsr,/*DeferredServiceRoutine*/cyg_handle_t*handle,/*returnedhandle*/cyg_interrupt*intr/*putinterrupthere*/)__THROW;
voidcyg_interrupt_attach(cyg_handle_tinterrupt)__THROW;
(注:
__THROW是在C++中用的,是用来抛出异常的,详见我的博文这里可以视而不见.)其中文意义对照如下:
cyg_interrupt_create(中断号,中断优先级,传递的中断参数,ISR函数,DSR函数,被返回的中断句柄,存放与此中断相关的内核数据的变量空间);cyg_interrupt_attach(中断句柄);这样实际上去研究一下cyg_interrupt_create函数的定义内容,应该就能搞明白我们的问题了!
由于其函数声明在kapi.h中,很自然的就想到其定义应在kapi.c文件中,找到....\ecos\ecos-current\packages\kernel\current\src\common\kapi.cxx文件,找到这两个函数的定义如下:
/*---------------------------------------------------------------------------*//*Interrupthandling*/
externCvoidcyg_interrupt_create(cyg_vector_tvector,/*Vectortoattachto*/cyg_priority_tpriority,/*Queuepriority*/cyg_addrword_tdata,/*Datapointer*/cyg_ISR_t*isr,/*InterruptServiceRoutine*/cyg_DSR_t*dsr,/*DeferredServiceRoutine*/cyg_handle_t*handle,/*returnedhandle*/cyg_interrupt*intr/*putinterrupthere*/)__THROW{CYG_ASSERT_SIZES(cyg_interrupt,Cyg_Interrupt);
Cyg_Interrupt*t=new((void*)intr)Cyg_Interrupt((cyg_vector)vector,(cyg_priority)priority,(CYG_ADDRWORD)data,(cyg_ISR*)isr,(cyg_DSR*)dsr);t=t;
CYG_CHECK_DATA_PTR(handle,"Badhandlepointer");*handle=(cyg_handle_t)intr;}voidcyg_interrupt_attach(cyg_handle_tinterrupt)__THROW{((Cyg_Interrupt*)interrupt)->attach();}
函数内容比想象中的简单,所有的操作又都传给了Cyg_Interrupt这个类来完成,那就来对Cyg_Interrupt探个究竟吧:
(注意Cyg_Interrupt是个C++类,可不要找成了structcyg_interrupt,注意哟,cyg_interrupt_create函数的最后一个参数就是这个cyg_interruptstruct类型的,在cyg/kernel/kapidata.h中有个structcyg_interrupt定义,虽然名字和内容都很相似,但实际上不是.)
真正的classCyg_Interrupt定义在cyg/kernel/intr.hxx中,这个头文件没干别的,就是声明这个class了,可见这是一个很大的class,如下:
//-------------------------------------------------------------------------//Interruptclass.Thisbothrepresentseachinterruptandprovidesastatic//interfaceforcontrollingtheinterrupthardware.
classCyg_Interrupt{
friendclassCyg_Scheduler;friendvoidinterrupt_end(cyg_uint32,Cyg_Interrupt*,HAL_SavedRegisters*);friendvoidcyg_interrupt_post_dsr(CYG_ADDRWORDintr_obj);friendvoidcyg_interrupt_call_pending_DSRs(void);cyg_vectorvector;//Interruptvector
cyg_prioritypriority;//Queuingprioritycyg_ISR*isr;//PointertoISR
cyg_DSR*dsr;//PointertoDSR
CYG_ADDRWORDdata;//Datapointer//DSRhandlinginterfacecalledbythescheduler
//CheckforpendingDSRsstaticcyg_boolDSRs_pending();
//CallanypendingDSRsstaticvoidcall_pending_DSRs();staticvoidcall_pending_DSRs_inner();
//DSRhandlinginterfacecalledbytheschedulerandHAL//interruptarbiters.
voidpost_dsr();//PosttheDSRforthisinterrupt//DatastructuresforhandlingDSRcalls.WeimplementtwoDSR//handlingmechanisms,alistbasedoneandatablebased//one.Thelistbasedmechanismissafewithrespecttotemporary//overloadsandwillnotrunoutofresource.Howeveritrequires//extradataperinterruptobject,andinterruptsmustbeturned//offbrieflywhendeliveringtheDSR.Thetablebasedmechanism//doesnotneedunnecessaryinterruptswitching,butmaybeprone//tooverflowonoverload.However,sinceacorrectlyprogrammed//realtimeapplicationshouldnotexperiencesuchacondition,//thetablebasedmechanismismoreefficientforrealuse.The//listbasedmechainsmisenabledbydefaultsinceitissaferto//useduringdevelopment.
#ifdefCYGIMP_KERNEL_INTERRUPTS_DSRS_TABLEstaticCyg_Interrupt*dsr_table[CYGNUM_KERNEL_CPU_MAX][CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE]CYGBLD_ANNOTATE_VARIABLE_INTR;
staticcyg_ucount32dsr_table_head[CYGNUM_KERNEL_CPU_MAX]CYGBLD_ANNOTATE_VARIABLE_INTR;
staticvolatilecyg_ucount32dsr_table_tail[CYGNUM_KERNEL_CPU_MAX]CYGBLD_ANNOTATE_VARIABLE_INTR;
#endif#ifdefCYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
//NumberofDSRpostsmadevolatilecyg_ucount32dsr_countCYGBLD_ANNOTATE_VARIABLE_INTR;
//nextDSRinlistCyg_Interrupt*volatilenext_dsrCYGBLD_ANNOTATE_VARIABLE_INTR;
//staticlistofpendingDSRsstaticCyg_Interrupt*volatiledsr_list[CYGNUM_KERNEL_CPU_MAX]CYGBLD_ANNOTATE_VARIABLE_INTR;#endif
#ifdefCYGIMP_KERNEL_INTERRUPTS_CHAIN
//Thedefaultmechanismforhandlinginterruptsistoattachjust//oneInterruptobjecttoeachvector.Insomecases,andonsome//hardware,thisisnotpossible,andeachvectormustcarryachain//ofinterrupts.
Cyg_Interrupt*next;//NextInterruptinlist
//ChainingISRinsertedinHALvectorstaticcyg_uint32chain_isr(cyg_vectorvector,CYG_ADDRWORDdata);
//TableofinterruptchainsstaticCyg_Interrupt*chain_list[CYGNUM_HAL_ISR_TABLE_SIZE];#endif
//Interruptdisabledata.Interruptdisablecanbenested.On//eachCPUthisiscontrolledbydisable_counter[cpu].Whenthe//counterisfirstincrementedfromzerotoone,the//interrupt_disable_spinlockisclaimedusingspin_intsave(),the//originalinterruptenablestatebeingsavedin//interrupt_disable_state[cpu].Whenthecounterisdecremented//backtozerothespinlockisclearedusingclear_intsave().
//ThespinlockisnecessaryinSMPsystemssinceathread//accessingdatasharedwithanISRmaybescheduledona//differentCPUtotheonethathandlestheinterrupt.So,merely//blockinglocalinterruptswouldbeineffective.SMPaware//devicedriversshouldeitherusetheirownspinlockstoprotect//data,orusetheAPIsupportedbythisclass,via//cyg_drv_isr_lock()/_unlock().Notethatitnowbecomes//essentialthatISRsdothisiftheyaretobeSMP-compatible.
//InasingleCPUsystem,thismechanismreducestojust//disabling/enablinginterrupts.
//Disablelevelcounter.Thiscountsthenumberoftimes//interruptshavebeendisabled.staticvolatilecyg_int32disable_counter[CYGNUM_KERNEL_CPU_MAX]CYGBLD_ANNOTATE_VARIABLE_INTR;
//Interruptdisablespinlock.ThisisclaimedbyanyCPUthathas//disabledinterruptsviatheCyg_InterruptAPI.staticCyg_SpinLockinterrupt_disable_spinlockCYGBLD_ANNOTATE_VARIABLE_INTR;
//Savedinterruptstate.WheneachCPUfirstdisablesinterrupts//theoriginalstateoftheinterruptsaresavedheretobe//restoredlater.staticCYG_INTERRUPT_STATEinterrupt_disable_state[CYGNUM_KERNEL_CPU_MAX]CYGBLD_ANNOTATE_VARIABLE_INTR;
public:
Cyg_Interrupt//Initializeinterrupt(cyg_vectorvector,//Vectortoattachtocyg_prioritypriority,//QueuepriorityCYG_ADDRWORDdata,//Datapointercyg_ISR*isr,//InterruptServiceRoutinecyg_DSR*dsr//DeferredServiceRoutine);
~Cyg_Interrupt();//ISRreturnvaluesenum{HANDLED=1,//InterruptwashandledCALL_DSR=2//ScheduleDSR};
//Interruptmanagementvoidattach();//Attachtovectorvoiddetach();//Detachfromvector//StaticInterruptmanagementfunctions
//Getthecurrentserviceroutinestaticvoidget_vsr(cyg_vectorvector,cyg_VSR**vsr);
//Installavectorserviceroutinestaticvoidset_vsr(cyg_vectorvector,//hardwarevectortoreplacecyg_VSR*vsr,//mynewserviceroutinecyg_VSR**old=NULL//pointertooldvsr,ifrequired);//Staticinterruptmaskingfunctions
//DisableinterruptsattheCPUstaticvoiddisable_interrupts();
//Re-enableCPUinterruptsstaticvoidenable_interrupts();
//AreinterruptsenabledattheCPU?
staticinlinecyg_boolinterrupts_enabled(){return(0==disable_counter[CYG_KERNEL_CPU_THIS()]);}//Getthevectorforthefollowingcallsinlinecyg_vectorget_vector(){returnvector;}//StaticPICcontrolfunctions//MaskaspecificinterruptinaPICstaticvoidmask_interrupt(cyg_vectorvector);//Thesamebutnotinterruptsafestaticvoidmask_interrupt_intunsafe(cyg_vectorvector);
//ClearPICmaskstaticvoidunmask_interrupt(cyg_vectorvector);//Thesamebutnotinterruptsafestaticvoidunmask_interrupt_intunsafe(cyg_vectorvector);
//AcknowledgeinterruptatPICstaticvoidacknowledge_interrupt(cyg_vectorvector);
//ChangeinterruptdetectionatPICstaticvoidconfigure_interrupt(cyg_vectorvector,//vectortocontrolcyg_boollevel,//leveloredgetriggeredcyg_boolup//hi/lolevel,rising/fallingedge);
#ifdefCYGPKG_KERNEL_SMP_SUPPORT
//SMPsupportforassociatinganinterruptwithaspecificCPU.staticvoidset_cpu(cyg_vector,HAL_SMP_CPU_TYPEcpu);staticHAL_SMP_CPU_TYPEget_cpu(cyg_vector);#endif};
这只是声明了这个class,这个class的构造/析构函数和成员函数的实现,还要找cyg/kernel/intr.hxx头文件相对应的C文件,在这里....\packages\kernel\current\src\intr\intr.cxx找到了intr.cxx文件,
因为cyg_interrupt_create函数实际上调用了classCyg_Interrupt的构造函数,我们就来看看这个构造函数:
Cyg_Interrupt:
:
Cyg_Interrupt(cyg_vectorvec,//Vectortoattachtocyg_prioritypri,//QueuepriorityCYG_ADDRWORDd,//Datapointercyg_ISR*ir,//InterruptServiceRoutinecyg_DSR*dr//DeferredServiceRoutine){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;
#ifdefCYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
dsr_count=0;next_dsr=NULL;
#endif
#ifdefCYGIMP_KERNEL_INTERRUPTS_CHAIN
next=NULL;#endif
CYG_REPORT_RETURN();};也就是分配了一下成员变量,把cyg_interrupt_create函数传进来的中断号、ISR、DSR等分配给类的成员变量,好像也没什么特别的。
看来整个cyg_interrupt_create函数也就是在构造这个类对象了。
这样重要的好戏是在cyg_interrupt_attach函数里完成了,看cyg_interrupt_attach的源代码,只一行,再次列出如下:
voidcyg_interrupt_attach(cyg_handle_tinterrupt)__T
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 原创eCos驱动分析 ISR是如何与硬件中断联系起来的 转载文章 原创 eCos 驱动 分析 ISR 如何 硬件 中断 联系 起来 转载 文章