关于44b0中的中断调用问题,(有点长,各位见谅)

[复制链接]
2990|1
 楼主| luocolor 发表于 2007-1-13 01:25 | 显示全部楼层 |阅读模式
关于44b0的中断调用的问题:<br /><br />我在网上下了一个源码,在阅读的过程中,就我的理解来说,碰到些问题。希望各位指教下,具体是这样<br /><br />的:<br /><br />下面的代码因为44b0中的各个中断类型相似的,所以只是以timer为例。<br /><br />在init.s中有这样的代码:<br />首先是一个宏的定义:<br />MACRO<br />$HandlerLabel&nbsp;HANDLER&nbsp;$HandleLabel<br /><br />$HandlerLabel<br />&nbsp;&nbsp;&nbsp;&nbsp;sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp,sp,#4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;decrement&nbsp;sp(to&nbsp;store&nbsp;jump&nbsp;address)<br />&nbsp;&nbsp;&nbsp;&nbsp;stmfd&nbsp;&nbsp;&nbsp;sp!,{r0}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;PUSH&nbsp;the&nbsp;work&nbsp;register&nbsp;to&nbsp;stack(lr&nbsp;doest&nbsp;push&nbsp;because&nbsp;it&nbsp;return&nbsp;<br /><br />to&nbsp;original&nbsp;address)<br />&nbsp;&nbsp;&nbsp;&nbsp;ldr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,=$HandleLabel;load&nbsp;the&nbsp;address&nbsp;of&nbsp;HandleXXX&nbsp;to&nbsp;r0<br />&nbsp;&nbsp;&nbsp;&nbsp;ldr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,[r0]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;load&nbsp;the&nbsp;contents(service&nbsp;routine&nbsp;start&nbsp;address)&nbsp;of&nbsp;HandleXXX<br />&nbsp;&nbsp;&nbsp;&nbsp;str&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,[sp,#4]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;store&nbsp;the&nbsp;contents(ISR)&nbsp;of&nbsp;HandleXXX&nbsp;to&nbsp;stack<br />&nbsp;&nbsp;&nbsp;&nbsp;ldmfd&nbsp;&nbsp;&nbsp;sp!,{r0,pc}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;POP&nbsp;the&nbsp;work&nbsp;register&nbsp;and&nbsp;pc(jump&nbsp;to&nbsp;ISR)<br />&nbsp;&nbsp;&nbsp;&nbsp;MEND<br />然后有一个vector_branch<br />&nbsp;&nbsp;&nbsp;&nbsp;......<br />entry<br />&nbsp;&nbsp;&nbsp;&nbsp;......<br />VECTOR_BRANCH<br />&nbsp;&nbsp;&nbsp;&nbsp;......<br />&nbsp;&nbsp;&nbsp;&nbsp;ldr&nbsp;pc,=HandlerTIMER1<br />&nbsp;&nbsp;&nbsp;&nbsp;......<br /><br />HandlerTIMER1&nbsp;&nbsp;&nbsp;&nbsp;HANDLER&nbsp;HandleTIMER1<br /><br />然后,在另外的文件isr_address.s中有下面的语句:<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;AREA&nbsp;&nbsp;&nbsp;&nbsp;ISR_STARTADDRESS,&nbsp;DATA,&nbsp;NOINIT<br />&nbsp;&nbsp;&nbsp;&nbsp;......<br />&nbsp;&nbsp;&nbsp;&nbsp;EXPORT&nbsp;&nbsp;&nbsp;&nbsp;HandleTIMER1<br />&nbsp;&nbsp;&nbsp;&nbsp;......<br />&nbsp;&nbsp;&nbsp;&nbsp;HandleTIMER1&nbsp;&nbsp;&nbsp;&nbsp;SPACE&nbsp;&nbsp;&nbsp;&nbsp;4<br />&nbsp;&nbsp;&nbsp;&nbsp;......<br />&nbsp;&nbsp;&nbsp;&nbsp;END<br /><br />另外,在scat_ram.scf中对存储空间的分配有:<br />RAM_LOAD&nbsp;0x00008000<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;RAM_EXEC&nbsp;0x00008000<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init.o&nbsp;(init,&nbsp;+First)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;(+RO)<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;RAM&nbsp;0x0x00100000<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;(+RW,+ZI)<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;HEAP&nbsp;+0&nbsp;UNINIT<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;heap.o&nbsp;(+ZI)<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;STACKS&nbsp;0x0020000&nbsp;UNINIT<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stack.o&nbsp;(+ZI)<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;ISR_STARTADDRESS&nbsp;0x0020000&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isr_address.o&nbsp;(+ZI)<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />}<br />然后,在文件isr.c和isr.h中定义下面的函数和数据结构。<br />void&nbsp;(*InterruptHandlers[MAXHNDLRS])(void)={NULL,};<br />有函数<br />void&nbsp;SetISR_Interrupt(int&nbsp;vector,&nbsp;void&nbsp;(*handler)(),&nbsp;int&nbsp;Exint)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;......<br />&nbsp;&nbsp;&nbsp;&nbsp;InterruptHandlers[vector]&nbsp;=&nbsp;handler;<br />&nbsp;&nbsp;&nbsp;&nbsp;......<br />}<br />最后,在整个系统的初始化时,用到了下面的语句:<br /><br />SetISR_Interrupt(INT_TIMER1_OFFSET,OSTimeTick,NULL);<br /><br />下面是我的理解:<br />从scat_ram.scf和isr_address.s中,可以得到从0x0020000处开始的位置,为每一个中断留出了4个字节<br /><br />的空间,其中包括timer1.这些空间应该是用来存储isr的地址(指针)的。<br /><br />继续,从scat_ram.scf也可以得到,从0x00008000开始存放init.s的数据。<br />将HandlerTIMER1&nbsp;&nbsp;&nbsp;&nbsp;HANDLER&nbsp;HandleTIMER1的宏展开,得到<br /><br />HandlerTIMER1<br />&nbsp;&nbsp;&nbsp;&nbsp;sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp,sp,#4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;stmfd&nbsp;&nbsp;&nbsp;sp!,{r0}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;ldr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,=HandleTIMER1<br />&nbsp;&nbsp;&nbsp;&nbsp;ldr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,[r0]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;str&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,[sp,#4]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;ldmfd&nbsp;&nbsp;&nbsp;sp!,{r0,pc}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />这里结合VECTOR_BRACH中的代码<br />ldr&nbsp;pc,=HandlerTIMER1<br />来看,假设现在timer1中断到来,那么执行该ldr命令,pc值指向sub处开始执行。ldr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />r0,=HandleTIMER1会将isr_address.s中export的HandleTIMER1加载到r0中,这里的r0中所放的实际上也<br /><br />是一个地址,指向相应isr指针的指针,执行ldr&nbsp;&nbsp;&nbsp;&nbsp;r0,[r0]后,r0中才是指向isr的指针(地址),通过<br /><br />堆栈的巧妙操作,pc指向了isr,开始执行相应的isr。<br /><br />借用linux的概念,这个执行的isr应该在系统初始化的时候被注册。这个任务应该是由函数<br />SetISR_Interrupt完成的,在SetISR_Interrupt中,调用了(*InterruptHandlers[MAXHNDLRS])(void),<br /><br />有InterruptHandlers[vector]&nbsp;=&nbsp;handler;这个vector明显是44b0定义的若干irq中断的相对偏移。<br /><br />但是让我很很很困惑的是:这个InterruptHandlers是在函数里面自己(程序员)定义的,可以说它并不与<br /><br />系统的相硬件有什么关系。我的意思是,在pc指向isr后,为什么相应的isr就是InterruptHandlers相应<br /><br />偏移处指向的函数。它们中间是怎样联系的呢?<br /><br />我知道或许我还有些东西不明了,希望各位大侠点化我下。呵呵。多谢了。
 楼主| luocolor 发表于 2007-1-14 16:55 | 显示全部楼层

现在明白了。

原来我没有将向量中断和非向量中断理解清楚。呵呵
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

105

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部