历史上的今天
返回首页

历史上的今天

今天是:2024年10月20日(星期日)

正在发生

2021年10月20日 | ARM处理器架构-----异常/中断处理

2021-10-20 来源:eefocus

中断是我们嵌入式开发很常用到的一种资源和编程手段。这篇文章重点分析arm的中断处理流程。


首先,中断是异常的一种。当发生一种异常时,处理器会进入不同的工作模式。ARM的异常和相应的模式之间的对应关系见下表:

当一个异常导致模式的改变时,ARM核自动地:


1、把cpsr保存到相应模式下的spsr


2、把pc保存到相应模式下的lr


3、设置cpsr为相应异常模式


4、设置pc为相应异常处理程序的入口地址


对于IRQ或者FIQ而言,还多一项变化:禁用相关的中断IRQ或FIQ,禁止同类型的其他中断被触发。(这也是自动实现的,因此正常情况下,ARM中断不可嵌套)


从异常中断处理程序退出时,需要我们在程序中用软件实现下面两个操作:


1、从spsr_mode中恢复数据到cpsr中


2、从lr_mode中恢复内容到pc中,返回到异常中断的指令的下一条政令处执行.


2440默认的有一个异常向量表,即发生某一个异常后,会根据异常向量表设置pc为相应的处理函数入口地址。

image.png?imageView2/2/w/550

上表中的 指令都是在2440init.s中的程序表示。


下面,我们结合板子自带的2440test源代码中的2440init.s中的异常处理,来分析arm中断处理的实现。


首先,在2440init.s中有:


__ENTRY

b ResetHandler

b HandlerUndef ;handler for Undefined mode

b HandlerSWI     ;handler for SWI interrupt

b HandlerPabort ;handler for PAbort

b HandlerDabort ;handler for DAbort

b .         ;reserved

b HandlerIRQ ;handler for IRQ interrupt

b HandlerFIQ ;handler for FIQ interrupt

这里就是相应的 异常处理向量表。程序正常启动就跳转到resethandler,如果是发生中断就跳转到handlerIRQ。对于handlerIRQ,它是用一个宏实现的。


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 does't 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

上面是宏的声明。下面是具体用到宏的地方。

HandlerFIQ      HANDLER HandleFIQ

HandlerIRQ      HANDLER HandleIRQ

HandlerUndef    HANDLER HandleUndef

HandlerSWI      HANDLER HandleSWI

HandlerDabort   HANDLER HandleDabort

HandlerPabort   HANDLER HandlePabort

上面的这段程序在编译的时候会被编译器展开,我们可以将其中的IRQ相关的展开如下:

HandlerIRQ   HANDLER  HandleIRQ 会被下面的代码段替换:


HandlerIRQ

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

stmfd sp!,{r0} ;PUSH the work register to stack(lr does''t 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)


因此,发生中断时,就会b HandlerIRQ,跳转到上面的代码进行执行。按照上面的流程,处理器会把HandleIRQ地址中所存储的数 付给pc指针,作为下一条指令的地址,然后执行。那么HandleIRQ地址中存储的数是什么呢?


在2440init.s中有这样一段程序:


ldr r0,=HandleIRQ ;This routine is needed

ldr r1,=IsrIRQ    ;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c

str r1,[r0]

从这里,可以看出,HandleIRQ中存的是IsrIRQ。所以处理器会跳转到isrIRQ中执行。

IsrIRQ

sub sp,sp,#4       ;reserved for PC

stmfd sp!,{r8-r9}

 

ldr r9,=INTOFFSET

ldr r9,[r9]

ldr r8,=HandleEINT0

add r8,r8,r9,lsl #2

ldr r8,[r8]

str r8,[sp,#8]

ldmfd sp!,{r8-r9,pc}


在上面的程序中,INTOFFSET表示的是中断号对于EINT0的偏移号。这样计算得到中断向量号之后,跳转到中断函数进行处理。对于,上面的程序奇怪的一点是没有看到恢复cpsr和pc指针。因此,可以推断,对于中断函数在ADS中有特殊的声明方式,如:static void __irq Uart_DMA_ISR(void)。像这种声明方式,在编译的时候,编译器会自动在函数的末尾添加恢复cpsr和pc的语句。另外, 寄存器r0-r12也是需要保护的,因为在中断函数和原来的上下文中都会用到,所以,我认为 编译器在中断处理函数中对r0-r12也进行了保护和恢复。



另外,在ucosII中,对IsrIRQ函数进行了修改,我们后面再进行分析。


另外,我们用软件实现了一套中断向量表:


ALIGN

AREA RamData, DATA, READWRITE

^   _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00

HandleReset #   4

HandleUndef #   4

HandleSWI #   4

HandlePabort    #   4

HandleDabort    #   4

HandleReserved  #   4

HandleIRQ #   4

HandleFIQ #   4

 

;Don''t use the label 'IntVectorTable',

;The value of IntVectorTable is different with the address you think it may be.

;IntVectorTable

;@0x33FF_FF20

HandleEINT0 #   4

HandleEINT1 #   4

HandleEINT2 #   4

HandleEINT3 #   4

HandleEINT4_7 #   4

HandleEINT8_23 #   4

HandleCAM #   4 ; Added for 2440.

HandleBATFLT #   4

HandleTICK #   4

HandleWDT #   4

HandleTIMER0 #   4

HandleTIMER1 #   4

HandleTIMER2 #   4

HandleTIMER3 #   4

HandleTIMER4 #   4

HandleUART2  #   4

;@0x33FF_FF60

HandleLCD #   4

HandleDMA0 #   4

HandleDMA1 #   4

HandleDMA2 #   4

HandleDMA3 #   4

HandleMMC #   4

HandleSPI0 #   4

HandleUART1 #   4

HandleNFCON #   4 ; Added for 2440.

HandleUSBD #   4

HandleUSBH #   4

HandleIIC #   4

HandleUART0 #   4

HandleSPI1 #   4

HandleRTC #   4

HandleADC #   4

;@0x33FF_FFA0

之前,我们在发生中断时,pc指针就跳转到了 HandleIRQ地址中所存储的数 出执行。也就是说在HandleIRQ中存的是异常处理函数的入口地址。这就是异常处理向量表的作用。

所以,我们可以看出,对于2440init.s实现的异常处理,采用的是两级向量表机制。 第一级向量表是arm核自己实现的,发生相应的异常时,pc指针跳转到0x18地址中存的数,作为入口地址。 第二级向量表是由Handler宏实现的,继续跳转到 HandleIRQ地址中存的数,继续执行。 

而对于IRQ来讲,还有第三级的向量表,在IsrIRQ中,又会根据中断号,比如uart2的中断,跳转到 HandleUart2地址中 存的数,继续执行。



在2440init.s中,并没有给HandleUndef等这些地址处赋值,因此,一旦执行到,程序就会跑飞。

推荐阅读

史海拾趣

场效应半导体(Cmos)公司的发展小趣事

高通(Qualcomm)在移动通信领域的迅猛发展也离不开CMOS技术的支持。高通在CMOS技术研发方面投入了大量资源,成功地将CMOS技术应用于其移动通信芯片产品中。这些芯片产品以其卓越的性能和出色的功耗控制而广受手机制造商的青睐。随着移动通信技术的不断进步,高通在CMOS技术方面的创新也不断推动着移动通信产业的发展。

FARNELL公司的发展小趣事

为了保持在电子行业中的领先地位,FARNELL公司积极寻求创新与合作。公司与多家知名电子元器件制造商建立了长期合作关系,共同研发新产品、新技术。同时,FARNELL公司还致力于为客户提供定制化的解决方案,满足不同客户的需求。这种创新与合作的精神使FARNELL公司在电子行业中保持了持续的发展动力。

Hexawave公司的发展小趣事

随着业务的不断发展,FARNELL公司开始寻求全球化拓展。公司陆续在欧洲、美洲、亚洲等地设立分公司和办事处,形成了覆盖全球的销售网络。这一过程中,FARNELL公司始终坚持“供货可靠、方便快捷、物超所值”的经营理念,为全球客户提供优质的产品和服务。

CHONGQING PINGYANG ELECTRONICS CO.,LTD.公司的发展小趣事

经过多年的发展,重庆平洋电子有限公司已经成长为一家中型规模的电子企业,产品广泛应用于汽车、家电、通信等多个领域。面对未来,公司将继续坚持技术创新和市场拓展并重的发展战略,不断提升产品质量和服务水平,努力成为电子行业的领军企业。同时,公司还将积极拓展国际市场,参与全球竞争,为实现更加辉煌的未来而努力奋斗。

这五个故事只是重庆平洋电子有限公司发展历程中的一部分缩影,但它们却充分展示了公司在电子行业中的崛起之路和未来的发展前景。

睿赫(crechip)公司的发展小趣事

尽管睿赫公司在电子行业中取得了显著的成就,但公司也面临着诸多挑战。随着技术的不断进步和市场的不断变化,公司需要不断创新和进步,才能保持领先地位。

面对未来,睿赫公司将继续秉承“创新、卓越、诚信、共赢”的企业精神,不断加强技术研发和人才培养,推动公司的持续发展和壮大。同时,公司还将积极关注市场动态和客户需求,不断推出符合市场需求的新产品,为客户提供更加优质的服务和解决方案。

Datakey Electronics公司的发展小趣事

在环境问题日益严重的今天,绿色环保已经成为电子产品行业的重要发展趋势。Datakey Electronics积极响应国家号召,致力于绿色产品的研发和生产。公司投入巨资研发环保材料和生产工艺,成功推出了一系列符合环保标准的产品。这些产品不仅满足了客户的需求,还为公司赢得了良好的社会声誉。

问答坊 | AI 解惑

使用ftp server加载vxworks映像问题

我在BOOTROM中使用FTP SERVER的功能来加载vxworks映像(大小也只1414KB)中遇到加载映像耗时很久的问题。 在FTP SERVER的LOG窗口显示如下: [L 0077] 05/27/10 09:41:31 Connection accepted from 192.168.4.245 [C 0077] 05/27/10 09:41:31 Co ...…

查看全部问答>

二个程序谁的耗的资源少,效率高?

一个程序主函数中就是一个检测文件是否存在的循环. 另一个程序在主函数中另建一个线程,被建的线程中是一个检测文件是否存在的循环. …

查看全部问答>

求助: 安装EVC 电脑卡住

我的机子装不了eVC4,安装到配置wince platform manager 4.0 时,就死机了 重启后就出现未识别的硬件和硬件安装向导, 提示什么虚拟PC的 只要安装也就卡机了. 这是怎么回事? 我电脑是SP3的,台式机一样的系统都安装得好好的…

查看全部问答>

Virtual Audio Driver Volume(wave) Control(虚拟声卡波形音量控制)?

关于:Virtual Audio Driver Volume(wave) Control(虚拟声卡波形音量控制) 请教: 1. 如果要利用虚拟声卡控制从上层APP发送过来的Wave Stream Volume,是应该通过PortCtrl.sys控制呢还是采用别的方法控制? 每种方法的流程应该是什么样的呢 ...…

查看全部问答>

【原创】在VC/eVC中实现VB中的Split函数

VB中,sItem = Split(s, \",\")   CString s; CString sItem[13]; byte pItem; byte p1, p2; s += \",\"; p1 = 0; pItem = 0; for (p2 = 0; p2 < s.GetLength(); p2++) {         if (s.GetAt(p2) == \',\') &nb ...…

查看全部问答>

LED恒流驱动芯片及系统应用(1218网友会PPT)

LED恒流驱动芯片及系统应用方案内容:1)LED光源的工作原理;2)LED恒流源低压大电流驱动芯片及典型应用;3)LED恒流源非隔离驱动芯片及典型应用;4)LED恒流源隔离驱动芯片及典型应用; 5)LED灯具可控硅调光方案;6)LED日光灯驱动电源方案;7)L ...…

查看全部问答>

版主主120MHz的STM32出来没有?

                                 如题…

查看全部问答>

怎样驱动继电器

用单片机驱动继电器是接NPN 还是PNP,为什么??请教…

查看全部问答>

求解

本帖最后由 dontium 于 2015-1-23 13:10 编辑 介绍一下模拟电路吧 …

查看全部问答>

施密特触发器电路原理

什么叫触发器 施密特触发电路( 简称)是一种波形整形电路,当任何波形的信号进入电路时,输出在正、负饱和之间跳动,产生方波或脉波输出。不同于比较器,施密特触发电路有两个临界电压且形成一个滞后区,可以防止在滞后范围内之噪声干扰电路的正 ...…

查看全部问答>