ecos中断分析Word下载.docx
《ecos中断分析Word下载.docx》由会员分享,可在线阅读,更多相关《ecos中断分析Word下载.docx(10页珍藏版)》请在冰豆网上搜索。
nop
t0,0x80000180
#destaddr//将other_vector拷贝到0x80000180处,完成中断向量的安装
t1,other_vector
t3,other_vector_end
.endm
.section"
.other_vector"
"
ax"
//中断处理代码安装的位置
#Commonvectorat0x80000080or0xBFC00180
FUNC_START(other_vector)//MIPS异常处理程序的入口,packages/hal/mips/arch/v2_0/src/vectors.S
mfc0
k0,cause
#K0=exceptioncause//读取cause寄存器
andi
k0,k0,0x7F
#isolateexceptioncode//取cause寄存器中的ExcCode值
la
k1,hal_vsr_table
#addressofVSRtable//取VSR表的基地址
add
k1,k1,k0
#offsetofVSRentry//根据ExcCode值取得VSR表的入口地址
lw
k1,0(k1)
#k1=pointertoVSR//取得VSR表中对应处理程序的地址
jr
k1
#gothere//跳转执行
nop
#(delayslot)
FUNC_END(other_vector)
##VSRtable.
##ThemaininterruptcodeindirectsthroughheretofindtheVSR
##toexecuteforeacharchitecturedefinedinterrupt.
##Thisisonlyusedforsimulatedtargets,onrealtargetsafixedlocationVSR
##tableisnowallocatedat0x80000100.
#ifndefCYG_HAL_MIPS_VSR_TABLE_DEFINED
##
.section"
.vsr_table"
a"
//VSR表
.data//VSR表在data段中
.globl
hal_vsr_table
hal_vsr_table:
.long
__default_interrupt_vsr
//定义了64个interrupt入口
.rept
63
__default_exception_vsr
.endr
#endif
##DefaultinterruptVSR.
##SavesmachinestateandcallsappropriateISR.Whendone,calls
##interrupt_end()tofinishupandpossiblyreschedule.
FUNC_START(__default_interrupt_vsr)//缺省的中断处理程序
#WeenterherewithalloftheCPUstatestill
#initsregistersexcept:
#K0=vectorindex
#K1=addressofthisfunction
move
k1,sp
#K1=originalSP//保存原始SP
addi
sp,sp,-mips_exception_decrement//分配stack空间
#spaceforregisters+safetymargin
sw
k0,mipsreg_vector(sp)
#storevector//将异常类型(即ExcCode值)存入堆栈
#storeGPRs//保存通用寄存器
.set
noat
sgpr
0,sp
1,sp
2,sp
3,sp
4,sp
5,sp
6,sp
7,sp
8,sp
9,sp
10,sp
11,sp
12,sp
13,sp
14,sp
15,sp
16,sp
17,sp
18,sp
19,sp
20,sp
21,sp
22,sp
23,sp
24,sp
25,sp
#
26,sp
#==K0
27,sp
#==K1
28,sp
#==GP
29,sp
#==SP
30,sp
#==FP
31,sp
#==RA
at
mfhi
a0//保存hi和lo寄存器
mflo
a1
shi
a0,sp
slo
a1,sp
#K1containsoriginalSP
ssp
#storeinregdump
//保存原始SP到新的stack中的特殊位置上
t1,status//保存status,cachectrl和epc寄存器
t2,cachectrl
mvafc0
t3,epc
t1,mipsreg_sr(sp)
t2,mipsreg_cachectrl(sp)
sva
t3,mipsreg_pc(sp)//epc寄存器
hal_fpu_savesp//保存浮点寄存器,packages/hal/mips/arch/v2_0/include/arch.inc,如果处理器没有fpu则该宏为空,Lupine没有浮点寄存器
//到此为止处理器的状态已经保存到栈上了
#Themachinestateisnowallsavedonthestack.
#LoadGlobalPointerregister.
gp,_gp//加载gp指针
#ifdefCYGFUN_HAL_COMMON_KERNEL_SUPPORT
.extern
cyg_scheduler_sched_lock
v0,cyg_scheduler_sched_lock//锁住调度器
a0,0(v0)
a0,a0,1
#endif
s0,sp
#savepointertosavedstate//取sp指针,留做后用
#ifdefCYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK//如果中断使用独立堆栈
a0,__interrupt_stack
#a0=stacktop//栈顶指针
a1,__interrupt_stack_base
#a1=stackbase//栈基址,定义如下:
.bss
.balign16
.globalcyg_interrupt_stack_base
cyg_interrupt_stack_base
__interrupt_stack_base:
.reptCYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE//stack的大小
.byte0
sub
a3,sp,a1
#a3=sp-base//现在的sp是否比__interrupt_stack_base小
bltz
a3,1f
#notonistackif<
0
#delayslot
t0,a0,sp
#t0=top-sp//现在的sp是否比__interrupt_stack大
bgtz
t0,8f
#alreadyonistackif>
sp,a0
#switchtoistack//notonistack
8:
sp,sp,-8
#spaceforoldSP//onistack,为保存现在的sp留出空间
#(8tokeepdwordalignment!
)
s0,0(sp)
#saveoldSPonstack//保存现在的sp
subu
sp,sp,mips_stack_frame_size
#makeanullframe
//做一个空的栈帧(32bytes)
#Needtosetupbackpointersetc.?
?
#Decodeexternalinterruptviainterruptcontroller
hal_intc_decode
s2//根据cause寄存器的IP位解码,返回IP号,packages/hal/mips/tx39/v2_0/include/variant.inc
#Here,s2containsthenumberoftheinterruptbeingserviced,
#weneedtoderivefromthatthevectornumbertocallintheISR
#table.
hal_intc_translates2,s1//packages/hal/mips/tx39/v2_0/include/variant.inc
#Heres1isthenumberofthevectortobecalledands2is
#thenumberoftheinterruptbeingserviced.
hal_diag_intr_start//中断诊断程序,可以不实现,packages/hal/mips/vrc437x/v2_0/include/platform.inc
#ifdefined(CYGPKG_KERNEL_INSTRUMENT)&
&
defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
#Callcyg_instrumenttorecordthatthisinterruptisbeingraised.//记录程序
li
a0,0x0301
#a0=type=INTR,RAISE
a1,s1
#a1=vectornumber
jal
cyg_instrument
#callinstrumentfunction
move
a2,s2
#a2=interruptnumber
#ifdefined(CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_SUPPORT)
#IfwearesupportingCtrl-CinterruptsfromGDB,wemustsquirrel
#awayapointertothesaveinterruptstateheresothatwecan
#plantabreakpointatsomelatertime.
hal_saved_interrupt_state//使用GDBstub调试时,用于保存中断状态
v0,hal_saved_interrupt_state
s0,0(v0)//s0是sp指针
sll
s1,s1,2
#s1=byteoffsetofvector//根据中断向量号计算中断向量偏移
//在此之前都是禁用中断的
hal_cpu_except_enable
#reenableexceptions//启用中断,packages/hal/mips/arch/v2_0/include/arch.inc
t2,hal_interrupt_handlers
#handlertable//加载中断处理程序表,如果未定以CYG_HAL_MIPS_ISR_TABLES_DEFINED,该表在packages/hal/mips/arch/v2_0/src/vectors.S中,否则根据platform不同有不同定义,如packages/hal/mips/tx39/v2_0/src/variant.S
t2,t2,s1
#addressofISRptr//根据中断向量号计算在中断处理程序表中的偏移
t2,0(t2)
#ISRpointer//取中断处理程序地址
a1,hal_interrupt_data
#datatable//加载中断处理程序数据表,定义位置与hal_interrupts_handlers一样
a1,a1,s1
#addressofdataptr//计算中断处理程序数据偏移
a1,0(a1)
#Datapointer//将中断处理程序数据地址存入a1,作为参数
a0,s2
#passinterruptnumber//将中断号存入a0寄存器,作为参数
jalr
t2
#callISRviat2//调用具体的中断处理程序,有两个参数,分别是中断向量号和中断处理程序数据
#ifdefCYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
#Ifwearereturningfromthelastnestedinterrupt,moveback
#tothethreadstack.interrupt_end()mustbecalledonthe
#threadstacksinceitpotentiallycausesacontextswitch.
#Sincewehavearrangedforthetopofstacklocationto
#containthespweneedtogobacktohere,justpopitoff
#andputitinSP.
sp,mips_stack_frame_size(sp)
#sp=*sp
#ifdefCYGFUN_HAL_COMMON_KERNEL_SUPPORT
#Weonlyneedtocall_interrupt_end()whenthereisakernel
#presenttodoanytidyingup.
#Onreturnv0bit1willindicatewhetheraDSRis
#tobeposted.Passthistogetherwithapointerto
#theinterruptobjectwehavejustusedtothe
#interrupttidyuproutine.
#Notethats0,s1ands2aredefinedtobepreservedacross
#callsbythecallingconvention,sotheystillcontain
#theregisterdump,thevectoroffsetandtheinterruptnumber
#respectively.
s2,v0//临时保存中断处理程序的返回值
a1,hal_interrupt_objects
#interruptobjecttable//取中断对象,定义位置与hal_interrupt_handlers一样,将地址存入a1,用作参数
#addressofobjectptr
#a1=objectptr
a2,s0
#arg3=savedregisterdump//堆栈指针存入a2,作为参数
interrupt_end
interrupt_end
#callintoCtofinishoff//调用interrupt_end做后面的处理(挂起DSR,解锁调度器,执行DSR),有三个参数,分别是ISR返回值,中断对象,堆栈指针,此处可能导致线程上下文切换