您的位置 首页 知识

2440中止解析

MACRO$HandlerLabelHANDLER$HandleLabel$HandlerLabelsubsp,sp,4;decrementsp(tostorejumpaddress)stmfdsp!

MACRO

$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)
ldr r0,=$HandleLabel; load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEN
将sp削减一个字节,使其在仓库高端留出存储回来地址,由于pc在寄存器组 中的方位大于r0,出栈时装入的是栈的高端的内容
保存r0
装载中止处理函数的指针
装载中止处理函数的地址
将中止处理函数的地址存入方才预留的方位,r0的上面
出栈后,pc指向的既是中止处理函数的地址
以上是个宏,用于把中止服务程序的首地址装载到pc中,我称它为“加载程序”。
本初始化程序界说了一个数据区(在文件最终),34个字空间,寄存相应中止服务程序的首地址。每个字空间都有一个标号,以Handle***命名。
在向量中止形式下运用“加载程序”来履行中止服务程序。

sub sp,sp,#4 是把SP的地址减4字节,而这个当地需求寄存跳转地址也便是第5行的HandleSWI指向的内容(ISR),将此内容写入pc,完成跳转

接下来是压栈所需求的寄存器r0,由于接下来需求运用r0所以先压栈r0,这也是为什么刚刚先把SP加四字节的原因,第6句话便是跳转到刚刚第5句所压栈的地址处,也便是HandleSWI指向的内容(ISR)处

下面是每个中止源的“加载程序”
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
下面这段程序的首地址将要被放到HandleIRQ中,在非向量中止形式下产生IRQ中止时,履行此程序来判别中止源以履行相应的中止服务程序。
IsrIRQ
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9}
ldr r9,=INTOFFSET
ldr r9,[r9]
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2
ldr r8,[r8]
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc}
下面便是把IsrIRQ的首地址装载到HandleIRQ的代码
; Setup IRQ handler
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;if there is not subs pc,lr,#4 at 0x18, 0x1c
str r1,[r0]
ALIGN
AREA RamData, DATA, READWRITE
反常向量表
^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset # 4
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
中止向量表
;Do not use the label IntVectorTable,
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
;@0x33FF_FF20
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleCAM # 4 ; Added for 2440.
HandleBATFLT # 4
HandleTICK # 4
HandleWDT # 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
;@0x33FF_FF60
HandleLCD # 4
HandleDMA0 # 4
HandleDMA1 # 4
HandleDMA2 # 4
HandleDMA3 # 4
HandleMMC # 4
HandleSPI0 # 4
HandleUART1 # 4
HandleNFCON # 4 ; Added for 2440.
HandleUSBD # 4
HandleUSBH # 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
;@0x33FF_FFA0
END
本程序的初始化中止部分完成的很奇妙,根据34个字单元将向量中止和非向量中止的完成结合在一起。
向量中止直接运用“加载程序”,把相应的中止服务程序首地址(寄存于Handle***)加载到PC。
非向量中止经过履行IsrIRQ判别中止源,并同时计算出相应Handle***的地址,再将此地址的内容加载到PC。
我有两个问题:
问题一,非向量中止有个缺陷,它一直从优先级最低的中止源开端辨认,且是经过过剖析I_ISPR寄存器的每一位来辨认,可是虽然有多个中止同时产生,I_ISPR只要一方位1。如此一来,频频产生低优先级中止是否会屏蔽其他中止?
我有过一次实验,设置两个中止INT_TICK和INT_TIMER5,两个中止服务程序都运用串口打印一串字符。当TIMER5以频率为1KHz(每毫秒一次)中止时,TICK中止服务程序毫无反响。
问题二,本代码中有这样一段
b HandlerIRQ
b HandlerFIQ
;***IMPORTANT NOTE***
;If the H/W vectored interrutp mode is enabled, The above two instructions should
;be changed like below, to work-around with H/W bug of S3C44B0X interrupt controller.
; b HandlerIRQ -> subs pc,lr,#4
; b HandlerIRQ -> subs pc,lr,#4
粗心是假如运用向量中止形式,必须用subs pc,lr,#4替代b HandlerIRQ。
首要我不太确认产生向量中止时,CPU是否履行b HandlerIRQ,仍是直接转向相应中止源的向量地址。假如不履行b HandlerIRQ,那么subs pc,lr,#4有何含义?假如履行b HandlerIRQ,那subs pc,lr,#4岂不是又使CPU从IRQ形式转换回SVC形式,持续履行被中止了的代码,这又是何含义?
别的,我依照他的办法试过,设置INTCON为向量中止,但一运转体系就重起,改回非向量中止一切正常。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/262915.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部