您的位置 首页 主动

关于44b0的中止调用的问题

关于44b0的中断调用的问题:我在网上下了一个源码,在阅读的过程中,我的理解来说。希望各位指教下,具体是这样的:下面的代码因为44b0中的…

关于44b0的中止调用的问题:

我在网上下了一个源码,在阅览的过程中,我的了解来说。期望各位指教下,详细是这样的:

下面的代码由于44b0中的各个中止类型类似的,所以仅仅以timer为例。

在init.s中有这样的代码:
首要是一个宏的界说:
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 doest 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)
MEND
然后有一个vector_branch
……
entry
……
VECTOR_BRANCH
……
ldr pc,=HandlerTIMER1
……
IRQ_Handler
IMPORTISR_IrqHandler
STMFDsp!, {r0-r12, lr}
BLISR_IrqHandler
LDMFDsp!, {r0-r12, lr}
SUBSpc, lr, #4

EXPORT IRQ_Handler
……
HandlerTIMER1HANDLER HandleTIMER1
……
;Setup IRQ handler
ldr r0,=HandleIRQ;This routine is needed
ldr r1,=IRQ_Handler;=IsrIRQ,if there isnt subs pc,lr,#4 at 0x18,

0x1c
str r1,[r0]

然后,在别的的文件isr_address.s中有下面的句子:

AREA ISR_STARTADDRESS, DATA, NOINIT
……
EXPORTHandleTIMER1
……
HandleTIMER1SPACE4
……
END

别的,在scat_ram.scf中对存储空间的分配有:
RAM_LOAD 0x00008000
{
RAM_EXEC 0x00008000
{
init.o (init, +First)
* (+RO)
}

RAM 0x0x00100000
{
* (+RW,+ZI)
}

HEAP +0 UNINIT
{
heap.o (+ZI)
}

STACKS 0x0020000 UNINIT
{
stack.o (+ZI)
}

ISR_STARTADDRESS 0x0020000
{
isr_address.o (+ZI)
}

}
在uHALr_InterruptRequestInit()中,有界说下面的东西
void uHALr_InterruptRequestInit()
{
pISR_UNDEF= (unsigned) DebugUNDEF;
pISR_SWI= (unsigned) DebugSWI;
……
SetISR_Interrupt(INT_TIMER1_OFFSET,OSTimeTick,NULL);
……
pISR_ADC= (unsigned) BreakPoint;
pISR_RTC= (unsigned) BreakPoint;
}
然后,在文件isr.c和isr.h中界说下面的函数和数据结构。
void (*InterruptHandlers[MAXHNDLRS])(void)={NULL,};
有函数
void SetISR_Interrupt(int vector, void (*handler)(), int Exint)
{
……
InterruptHandlers[vector] = handler;
……
}

在说的了解之前,要谨记44b0供给了两种向量和非向量的中止mode。
下面是我的了解:
(1)在向量中止时采纳的操作
从scat_ram.scf和isr_address.s中,能够得到从0x0020000处开端的方位,为每一个中止留出了4个字节

的空间,其间包含timer1.这些空间应该是用来存储isr的地址(指针)的。

持续,从scat_ram.scf也能够得到,从0x00008000开端寄存init.s的数据。
将HandlerTIMER1HANDLER HandleTIMER1的宏打开,得到

HandlerTIMER1
sub sp,sp,#4
stmfd sp!,{r0}
ldr r0,=HandleTIMER1
ldr r0,[r0]
str r0,[sp,#4]
ldmfd sp!,{r0,pc}
这儿结合VECTOR_BRACH中的代码
ldr pc,=HandlerTIMER1
来看,假定现在timer1中止到来,那么履行该ldr指令,pc值指向sub处开端履行。ldr

r0,=HandleTIMER1会将isr_address.s中export的HandleTIMER1加载到r0中,这儿的r0中所放的实际上也

是一个地址,指向相应isr指针的指针,履行ldrr0,[r0]后,r0中才是指向isr的指针(地址),经过

仓库的奇妙操作,pc指向了isr,开端履行相应的isr。这个isr怎样是怎样和相应的Handle对应的呢?在

函数uHALr_InterruptRequestInit()中,有pISR_UNDEF= (unsigned) DebugUNDEF等,这些的意思是在

pISR_UNDEF所代表的地址处放置指向DebugUNDEF的指针(地址)。
(2)非向量中止下的操作

回到init.s中,有句子
;Setup IRQ handler
ldr r0,=HandleIRQ;This routine is needed
ldr r1,=IRQ_Handler;=IsrIRQ,if there isnt subs pc,lr,#4 at 0x18,

0x1c
str r1,[r0]
这儿要注意了,HandleIRQ也是isr_address.s中的那个,仅仅这儿将IRQ_Handler的地址放到HandleIRQ预

留的空间中。
相同,如果在这种mode下,有一个irq中止到来,那么首要体系也会像(1)那样找到HandleIRQ,可是现在

那里放置的是IRQ_Handle的地址,所以转向IRQ_Handle,继而转向ISR_IrqHandler。在ISR_IrqHandler中

,使用I_ISPC寄存器找到中止源,然后调用相应源的处理函数。
借用linux的概念,这个履行的isr应该在体系初始化的时分被注册。这个使命应该是由函数
SetISR_Interrupt完结的,在SetISR_Interrupt中,调用了(*InterruptHandlers[MAXHNDLRS])(void),

有InterruptHandlers[vector] = handler;这个vector显着是44b0界说的若干irq中止的相对偏移。

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

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

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

微信扫一扫关注我们

返回顶部