分类: 嵌入式
2015-04-30 14:23:22
原文地址:mini2440启动代码分析之第五篇(中断向量表) 作者:
;中断向量表一般位于启动代码的开始部分,它是用户程序与启动代码之间以及启动代码的各部分之间联系的纽带。它由一个一个的跳转函数组成,它就象一个普通的散转函数,只不过散转的过程中有硬件机制参与,当系统发生异常时,ARM 处理器会通过硬件机制强制将PC 指针指向中断向量表中对应的异常跳转函数存储的地址,然后程序会跳转到相应的中断服务程序去执行。(别忘了前篇有个复位b ResetHandler )
b HandlerUndef ;handler for Undefined mode 未定义异常,遇到无法识别的指令时0x04
b HandlerSWI ;handler for SWI interrupt,软中断异常0x08
b HandlerPabort ;handler for PAbort指令预取错误时进入0x0c
b HandlerDabort ;handler for DAbort数据访问不能完成时进入0x10
b . ;reserved, 保留 0x14
b HandlerIRQ ;handler for IRQ interrupt发生IRQ 中断时进入0x18
b HandlerFIQ ;handler for FIQ interrupt发生FIQ 中断时进入0x1c
b EnterPWDN ; Must be @0x20.
这个b EnterPWDN没太见过,然后点击查看到在2440lib.c头文件中可以见到这样的宏声明:
#define EnterPWDN(clkcon) ((void (*)(int))0x20)(clkcon)
不难看出,当我们编程调用EnterPWDN(clkcon)函数的时候,编译器在编译前首先把EnterPWDN(clkcon)转换为((void (*)(int))0x20)(clkcon)语句。现在分析这个语句,对于这个语句,我们先将之分解成3个部分来看:
如下: 1:(void (*)(int) 2:0x20 3:(clkcon)
其中(clkcon)是函数的参数,对照着看就知道了;0x20是要转换的函数的入口地址;着重看(void (*)(int),这部分作为一个整体,描述了转换后的函数的类型,即无返回值,带一个整形参数。而中间那个“(*)”,表示是要转换成一个函数,类比一下就像我们平常用的强制类型转换一样,(int)temp,只不过这里是将一个数转换为另一类型,而咱们刚说的是将一个地址转换为一个函数。