您的位置 首页 电源

ARM的反常处理进程剖析

近来翻了翻uCOS-II官网给出来的ARM7-ARM9移植手册(AN-104),分析了在ARM中移植的问题,想想从来没有认真的学习过ARM的汇编,趁着这个机

近来翻了翻uC/OS-II官网给出来的ARM7-ARM9移植手册(AN-104),剖析了在ARM中移植的问题,想想从来没有仔细的学习过ARM的汇编,趁着这个机遇温习温习吧。其实底层的东西才是创造力的心脏。

其间的移植代码中存在的许多问题比方间断的封闭和敞开,使命等级的情形切换,间断到使命的情形切换都是咱们在平常移植中讲到,我也不在此强调了。在官网中供给的移植进程中存在反常处理机制,这个本不是在移植进程中考虑的,可是文档中的确供给了一个比较好的处理方法。我在此对这一段时刻的学习做一个总结。
首要需求了解ARM的反常处理机制,反常是每一种处理器都必须考虑的问题之一,关键在于怎么让处理,回来地址在什么方位都是需求考虑的,
ARM中支撑7种反常,其间包含复位、未定义指令反常、软间断反常、预取指令间断、数据间断、IRQ、IFQ。每一种反常运行在特定的处理器形式下。我在此逐个的剖析。
一般反常产生后,CPU都会进行一系列的操作,这些操作有一部分是CPU主动完结,有一部分是需求咱们程序员完结。
首要阐明CPU会主动完结的部分,用ARM结构手册中的代码描绘如下:
R14_ = return link //这个能够参看寄存器的阐明,两个效果
SPSR_< exception_mode > = CPSR
CPSR[4:0] = exception mode number
CPSR[5] = 0 ; //AEM指令
If ==Reset or Fiq then //只需在复位和FIQ形式下才会封闭FIQ间断
CPSR[6] = 1 ;
CPSR[7] = 1 ; //任何反常形式下都会封闭IRQ间断
PC = exceptionvectoraddress
从上面的代码中咱们能够发现CPU主动处理的进程包含如下:
1、 复制CPSR到SPSR_
2、 设置恰当的CPSR位:改动处理器状况进入ARM状况;改动处理器形式进入相应的反常形式;设置间断制止位制止相应间断。
3、 更新LR_,这个寄存器中保存的是反常回来时的链接地址
4、 设置PC到相应的反常向量
以上的操作都是CPU主动完结,反常的向量表如下:

回来地址问题
反常的回来地址也是需求咱们留意的当地,不同的反常形式回来地址也是存在差异的,这首要是因为各种反常产生的机理存在不同所导致的。这样咱们的需求在反常进入处理函数之前或许在回来时调整回来地址,一般选用进入反常处理函数前进行手动调整。下面每一种反常R14保存的值都给了出来,其间也包含了CPU主动处理的部分,依据保存的R14就能够知道怎样完结地址的回来。
复位反常:
能够看出该形式下的先对来说回来地址也比较简略,不需求做太多的描绘。
未定义的指令反常:
回来的方法也比较简略:
MOVSPC, R14
软间断反常:
回来的方法也比较简略:
MOVSPC, R14
预取指令间断反常:
回来需求做下面的调整:
SUBS PC, R14, #4
数据间断
回来地址需求做下面的调整:
假设需求从头拜访数据则:
SUBS PC, R14, #8
假设不需求从头拜访数据则:
SUBS PC, R14, #4
IRQ间断的处理进程:
回来地址需求做下面的调整:
SUBS PC,R14,#4
IFQ间断:
回来地址需求做下面的调整:
SUBSPC, R14 ,#4
从上面的代码能够知道,关于每一种反常,保存的回来地址都是不一样的,一般都需求咱们手动的跳转,当然调整的机遇也需求咱们挑选,是在进入处理前跳转仍是回来时调整都是需求咱们程序员操控的。
在ARM Developer Suite Developer Guide中对ARM处理器的反常处理操作供给能愈加具体的解说,每一种反常下的处理方法如下文描绘:
反常回来时另一个非常重要的问题是回来地址的确认,在前面曾说到进入反常时处理器会有一个保存LR的动作,可是该保存值并不一定是正确的回来地址,下面以一个简略的指令履行流水状况图来对此加以阐明。
咱们知道在ARM架构里,PC值指向当时履行指令的地址加8处,也便是说,当履行指令A(地址0x8000)时,PC等于指令C的地址(0x8008)。假设指令A是“BL”指令,则当履行该指令时,会把PC(=0x8008)保存到LR寄存器里边,可是接下去处理器会立刻对LR进行一个主动的调整动作:LR=LR-0x4。这样,终究保存在LR里边的是B指令的地址,所以当从BL回来时,LR里边正好是正确的回来地址。相同的调整机制在所有LR主动保存操作中都存在,比方进入间断呼应时,处理器所做的LR保存中,也进行了一次主动调整,而且调整动作都是LR=LR-0x4。
下面,咱们对不同类型的反常的回来地址顺次进行阐明:
假设在指令A处(地址0x8000)产生了反常,进入反常呼应后,LR上通过调整保存的地址值应该是B的地址0x8004。
1、假设产生的是软件间断,即A是“SWI”指令
反常是由指令自身引起的,从SWI间断回来后下一条履行指令便是B,正好是LR寄存器保存的地址,所以只需直接把LR康复给PC。
MOVS pc, lr
2、产生的是Undefined instruction反常
反常是由指令自身引起的,从反常回来后下一条履行指令便是B,正好是LR寄存器保存的地址,所以只需直接把LR康复给PC。
MOVS pc, lr
3、产生的是IRQ或FIQ间断
因为指令不可能被间断打断,所以A指令履行完今后才干呼应间断,此刻PC已更新,指向指令D的地址(地址0x800C),LR上通过调整保存的地址值是C的地址0x8008。间断回来后应该履行B指令,所以回来操作是:
SUBS pc, lr, #4
4、产生的是Prefetch Abort反常
该反常并不是处理器企图从一个不合法地址取指令时触发,取出的指令仅仅被标记为不合法,按正常处理流程放在流水线上,在履行阶段触发Prefetch Abort反常,此刻LR上通过调整保存的地址值是B的地址0x8004。反常回来应该回来到A指令,测验从头取指令,所以回来操作是:
SUBS pc, lr, #4
5、产生的是“Data Abort”
CPU拜访存储器时触发该反常,此刻PC指向指令D的地址(地址0x800C),LR上通过调整保存的地址值是C的地址0x8008。反常回来后,应回到指令A,测验从头操作存储器,所以回来操作是:
SUBS pc, lr, #8
以上便是ARM反常的CPU操作部分,接下来便是程序员应该完结的操作。
1.因为CPU会主动跳转到对应的反常向量中,因而只需求在在各个反常向量中寄存对应的操作,最简略的都是寄存一个B指令跳转到对应的反常处理函数的操作即可。但因为B指令的跳转回来只需+-32M,而反常处理函数的地址可能会超越+-32M,因而能够选用另一种方法完结方法:在反常向量中保存一条指令LDR PC [addr],其间的addr中就保存了反常处理函数的地址,当然addr的相对地址要小于+-32M。这样也就处理了跳转规模的问题。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/dianyuan/317783.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部