当前位置:首页 > 单片机 > 单片机
[导读]这个 2440test里面的中断写的向量有些隐蔽,兜了很多个圈,也难怪这么难理解,下面就对这个东西抽丝剥茧,看清楚这究竟是一个怎么样的过程。中断向量bHandlerIRQ;handler for IRQ interrupt很自然,因为所有的单片机

这个 2440test里面的中断写的向量有些隐蔽,兜了很多个圈,也难怪这么难理解,下面

就对这个东西抽丝剥茧,看清楚这究竟是一个怎么样的过程。

中断向量

bHandlerIRQ;handler for IRQ interrupt

很自然,因为所有的单片机都是那样,中断向量一般放在开头,用过单片机的人都会很熟悉

那就不多说了。

异常服务程序

这里不用中断(interrupt)而用异常(exception),毕竟中断只是异常的一种情况,呵呵

下面主要分析的是“中断异常”说白了,就是我们平时单片机里面用的中断!!!所有有器件

引起的中断,例如TIMER中断,UART中断,外部中断等等,都有一个统一的入口,那就是中断

异常 IRQ ! 然后从IRQ的服务函数里面分辨出,当前究竟是什么中断,再跳转到相应的中断

服务程序。这样看来,ARM比单片机要复杂一些了,不过原理是不变的。

上面说的就是思路,跟着这个思路来接着分析。

HandlerIRQ 很明显是一个标号,我们找到了

HandlerIRQ HANDLER HandleIRQ

这里是一个宏定义,我们再找到这个宏,看他是怎么定义的:

MACRO

$HandlerLabel HANDLER $HandleLabel

$HandlerLabel

subsp,sp,#4;decrement sp(to store jump address)

stmfdsp!,{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)

MEND

用 HandlerIRQ 将这个宏展开之后得到的结果实际是这样的

HandlerIRQ

subsp,sp,#4;decrement sp(to store jump address)

stmfdsp!,{r0};PUSH the work register to stack(lr does not push because it return to original

address)

ldr r0,=HandleIRQ ;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)

至于具体的跳转原理下面再说

好了,这样的话就容易看的多了,很明显,HandlerIRQ 还是一个标号,IRQ异常向量就是跳

转到这里执行的,这里粗略看一下,应该是保存现场,然后跳转到真正的处理函数,那么很容易

发现了这么一句 ldr r0,=HandleIRQ ,没错,我们又找到了一个标号 HandleIRQ ,看来

真正的处理函数应该是这个 HandleIRQ ,继续寻找

AREA RamData, DATA, READWRITE

^ _ISR_STARTADDRESS; _ISR_STARTADDRESS=0x33FF_FF00

HandleReset # 4

HandleUndef # 4

HandleSWI# 4

HandlePabort # 4

HandleDabort # 4

HandleReserved # 4

HandleIRQ# 4

最后我们发现在这里找到了 HandleIRQ ,^ 其实就是 MAP ,这段程序的意思是,从 _ISR_STARTADDRESS

开始,预留一个变量,每个变量一个标号,预留的空间为 4个字节,也就是 32BIT,其实这里放的是真正

的C写的处理函数的地址,说白了,就是函数指针 - -

这样做的话就很灵活了

接着,我们需要安装IRQ处理句柄,说白了,就是设置处理函数的地址,让PC指针可以正确的跳转。

于是我们在接着的找到安装句柄的语句

; Setup IRQ handler

ldrr0,=HandleIRQ ;This routine is needed

ldrr1,=IsrIRQ;if there is not 'subs pc,lr,#4' at 0x18, 0x1c

strr1,[r0]

说白了就是将 IsrIRQ 的地址填到 HandleIRQ对应的地址里面,前面说了 HandleIRQ 放的是中断处理的

函数的入口地址,我们继续找 IsrIRQ

IsrIRQ

subsp,sp,#4 ;reserved for PC

stmfdsp!,{r8-r9}

ldrr9,=INTOFFSET

ldrr9,[r9];读入中断偏移码

ldrr8,=HandleEINT0;二级跳转表的首地址

addr8,r8,r9,lsl #2;R8=R8+R9X4得到相应的中断入口地址

ldrr8,[r8]

strr8,[sp,#8];中断入口地址送进SP(第一个代码留出的4字节空间)

ldmfdsp!,{r8-r9,pc}

要理解这个代码,得先学学2440的中断系统了,INTOFFSET存放的是当前中断的偏移号,根据偏移就知道

当前是哪个中断源发生的中断。

注意了,我们说的是中断,而不是异常,看看原来的表是啥样子的

^ _ISR_STARTADDRESS; _ISR_STARTADDRESS=0x33FF_FF00

HandleReset # 4

HandleUndef # 4

HandleSWI# 4

HandlePabort # 4

HandleDabort # 4

HandleReserved # 4

HandleIRQ# 4

HandleFIQ# 4

HandleEINT0# 4

HandleEINT1# 4

HandleEINT2# 4

HandleEINT3# 4

.......

可以看到,前面几个是异常,从 HandleEINT0 就是 IRQ异常的向量存放的地方了,这样就可以理解为

什么上面 IsrIRQ 里面里面要执行那条指令

ldrr8,=HandleEINT0

addr8,r8,r9,lsl #2

道理很简单, HandleEINT0 就是所有IRQ中断向量表的入口,在这个地址上面,加上一个适当的偏移量,

INTOFFSET ,那么我们知道现在,到底是哪个IRQ在申请中断了。

至于具体怎么跳转的?

首先,我们说了,HandleEINT0 开始的一段内存里面,存放的就是中断服务函数的函数指针,ARM的体系

的话,每个指针变量就是占4个字节,这里就解释了,为什么这里为每个标号分配了4个字节的空间,里面

放的就是函数指针!!!下面再看看怎么跳转,继续看 IsrIRQ 里面就实现了跳转了

strr8,[sp,#8]

ldmfdsp!,{r8-r9,pc}

其实最核心就是这两句了,先查找到当前中断服务程序的地址,将他放到 R8 里面,然后出栈,弹出给PC

那么PC很自然就跳到中断服务程序了。至于这里的堆栈问题又是一个非常棘手的,需要好好的参透ARM的

中断架构,需要了解的可以自己仔细的阅读 《ARM体系结构与编程》里面说的很详细。我们这里的重点

是研究怎么跳转。

最后,我们看看在C代码中是怎么安装终端向量的,例如看 按键的外部中断,是怎么具体设置的,参看

/src/keyscan.c 里面的代码

很简单,里面只有3个函数

KeyScan_Test 是按键测试的主函数

Key_ISR 是按键中断服务函数

在 KeyScan_Test里面,我们发现了有这么一句

pISR_EINT0 = pISR_EINT2 = pISR_EINT8_23 = (U32)Key_ISR;

可以理解否? Key_ISR就是上面提到的按键中断服务函数,函数的名字,代表的就是函数的地址!!!!

将中断服务函数的地址,注意了,是地址,这是一个 U32型的变量。送到几个变量,我们以pISR_EINT0

作为例子,查看头文件定义,在 2440addr.h 里面找到

// Interrupt vector

#define pISR_EINT0(*(unsigned *)(_ISR_STARTADDRESS+0x20))

_ISR_STARTADDRESS有没有似曾相识的感觉?没错,刚才分析的汇编代码里面就提到了

^ _ISR_STARTADDRESS; _ISR_STARTADDRESS=0x33FF_FF00

HandleReset # 4

HandleUndef # 4

......

对,地址就是这里,然后 _ISR_STARTADDRESS+0x20 就是跳过前面的异常向量,进入IRQ中断向量的入口

所以说到尾

pISR_EINT0 = (U32)Key_ISR;

完成的操作就是,将 Key_ISR 的地址存放到

HandleEINT0# 4

这个IRQ向量表里面!!!!

当按键中断发生的时候,发生IRQ异常中断

当前PC值-4 保存到LR_IRQ里面,然后执行

bHandlerIRQ

然后是执行

HandlerIRQ

sub

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

特朗普集团近日取消了其新推出的T1智能手机“将在美国制造”的宣传标语,此举源于外界对这款手机能否以当前定价在美国本土生产的质疑。

关键字: 特朗普 苹果 AI

美国总统特朗普在公开场合表示,他已要求苹果公司CEO蒂姆·库克停止在印度建厂,矛头直指该公司生产多元化的计划。

关键字: 特朗普 苹果 AI

4月10日消息,据媒体报道,美国总统特朗普宣布,美国对部分贸易伙伴暂停90天执行新关税政策,同时对中国的关税提高到125%,该消息公布后苹果股价飙升了15%。这次反弹使苹果市值增加了4000多亿美元,目前苹果市值接近3万...

关键字: 特朗普 AI 人工智能 特斯拉

3月25日消息,据报道,当地时间3月20日,美国总统特朗普在社交媒体平台“真实社交”上发文写道:“那些被抓到破坏特斯拉的人,将有很大可能被判入狱长达20年,这包括资助(破坏特斯拉汽车)者,我们正在寻找你。”

关键字: 特朗普 AI 人工智能 特斯拉

1月22日消息,刚刚,新任美国总统特朗普放出重磅消息,将全力支持美国AI发展。

关键字: 特朗普 AI 人工智能

特朗普先生有两件事一定会载入史册,一个是筑墙,一个是挖坑。在美墨边境筑墙的口号确保边境安全,降低因非法移民引起的犯罪率过高问题;在中美科技产业之间挖坑的口号也是安全,美国企业不得使用对美国国家安全构成威胁的电信设备,总统...

关键字: 特朗普 孤立主义 科技产业

据路透社1月17日消息显示,知情人士透露,特朗普已通知英特尔、铠侠在内的几家华为供应商,将要撤销其对华为的出货的部分许可证,同时将拒绝其他数十个向华为供货的申请。据透露,共有4家公司的8份许可被撤销。另外,相关公司收到撤...

关键字: 华为 芯片 特朗普

曾在2018年时被美国总统特朗普称作“世界第八奇迹”的富士康集团在美国威斯康星州投资建设的LCD显示屏工厂项目,如今却因为富士康将项目大幅缩水并拒绝签订新的合同而陷入了僵局。这也导致富士康无法从当地政府那里获得约40亿美...

关键字: 特朗普 富士康

今年5月,因自己发布的推文被贴上“无确凿依据”标签而与推特发生激烈争执后,美国总统特朗普签署了一项行政令,下令要求重审《通信规范法》第230条。

关键字: 谷歌 facebook 特朗普

众所周知,寄往白宫的所有邮件在到达白宫之前都会在他地进行分类和筛选。9月19日,根据美国相关执法官员的通报,本周早些时候,执法人员截获了一个寄给特朗普总统的包裹,该包裹内包含蓖麻毒蛋白。

关键字: 美国 白宫 特朗普
关闭