Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15101
  • 博文数量: 5
  • 博客积分: 147
  • 博客等级: 入伍新兵
  • 技术积分: 60
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-23 00:25
文章分类
文章存档

2013年(1)

2012年(4)

我的朋友

分类: 嵌入式

2012-11-06 19:56:19

 
  1. b ResetHandler
  2. b HandlerUndef   ;handler for Undefined mode  0x04
  3. b HandlerSWI     ;handler for SWI interrupt   0x08
  4. b HandlerPabort  ;handler for PAbort          0x0c
  5. b HandlerDabort  ;handler for DAbort          0x10
  6. b .              ;reserved                    0x14
  7. b HandlerIRQ     ;handler for IRQ interrupt   0x18
  8. b HandlerFIQ     ;handler for FIQ interrupt   0x1c
程序开始处设置异常中断跳转。跳转后的代码在这儿
  1. HandlerFIQ HANDLER HandleFIQ
  2. HandlerIRQ HANDLER HandleIRQ
  3. HandlerUndef HANDLER HandleUndef
  4. HandlerSWI HANDLER HandleSWI
  5. HandlerDabort HANDLER HandleDabort
  6. HandlerPabort HANDLER HandlePabort
这是一个宏,宏名为HANDLER。遇到类似$HandleLabel HANDLER $HandleLabel的语句则执行宏内指令。宏定义内容是下面这段,也是上面跳转之后运行的代码
  1.     MACRO
  2. $HandlerLabel HANDLER $HandleLabel
  3. $HandlerLabel
  4. sub sp,sp,#4
  5. stmfd sp!,{r0}
  6. ldr r0,=$HandleLabel
  7. ldr r0,[r0]
  8. str r0,[sp,#4]
  9. ldmfd sp!,{r0,pc}
  10.     MEND
上面这段的意思是:不改变r0和sp的值,使pc跳转到$HandleLabel标号所指向的地址处。在启动代码最后可以看到跳转到的标号。
  1. ^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00
  2. HandleReset # 4
  3. HandleUndef # 4
  4. HandleSWI # 4
  5. HandlePabort # 4
  6. HandleDabort # 4
  7. HandleReserved # 4
  8. HandleIRQ # 4
  9. HandleFIQ # 4
"^"=MAP,意思是从_ISR_STARTADDRESS开始定义一个内存表。内存表中为下面标号预留4字节空间。可以看出:当程序进入中断后,pc会跳转到HandleIRQ标号处。但是预留HandleIRQ的空间时,并没有为其写入内容。所以,我们要先为HandleIRQ地址初始化,使其指向一个地址。这样,每有中断发生时,则使pc跳转到指向的地址处。
  1. ; Setup IRQ handler
  2. ldr r0,=HandleIRQ ;This routine is needed
  3. ldr r1,=IsrIRQ ;if there is not 'subs pc,lr,#4' at 0x18, 0x1c
  4. str r1,[r0]
这段的意思是将IsrIRQ的地址赋予HandleIRQ。所以,IsrIRQ就是HandleIRQ所指向的地址,也是pc将要跳转到的地址。跳转之后,将执行下面代码:
  1. IsrIRQ
  2.     sub sp,sp,#4
  3.     stmfd sp!,{r8-r9}
  4.     ldr r9,=INTOFFSET
  5.     ldr r9,[r9]
  6.     ldr r8,=HandleEINT0
  7.     add r8,r8,r9,lsl #2
  8.     ldr r8,[r8]
  9.     str r8,[sp,#8]
  10.     ldmfd sp!,{r8-r9,pc}
INTOFFSET为中断源偏移量。例如,HandleEINT0偏移量为0,HandleEINT1偏移量为1,HandleEINT4_7偏移量为4,从下表可以看出
  1. ;@0x33FF_FF20
  2. HandleEINT0 # 4
  3. HandleEINT1 # 4
  4. HandleEINT2 # 4
  5. HandleEINT3 # 4
  6. HandleEINT4_7 # 4
  7. ...
IsrIRQ段的意思:r8为HandleEINT0的地址,r9为中断偏移量,也是相对HandleEINT0的偏移量。结果是将发生中断的中断源的标号地址赋予pc,即表中标号代表的地址。(具体执行需仔细看IsrIRQ段代码)但是,表中的标号的地址中也需要写入内容,以使pc跳转。结合2440addr.h中的
    #define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))
可以看出,在c编码中的pISR_EINTx = xxx(函数名)中的xxx函数入口地址即是pc将要跳转的地址,而接下来要执行的也就是c中编写的中断服务程序。






 
阅读(348) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:LDM/STM指令

给主人留下些什么吧!~~