|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
在ARM处理器中,如果一个程序产生了错误并且被处理器检测到,这是就会产生错误异常。
% ~, s& ~0 [! u% w; ], J1 a. V4 D# v. p
错误是怎么发生的呢?- ~. ?; F. _1 T, a$ K
许多可能的原因都会引起错误发生,比如对于存储器相关错误,总线系统的异常响应可以有以下原因:
; k8 m8 q: m) u/ c- d访问的地址非法;& ? W: R- v. D0 i
由于传输的类型非法,总线的从设备不接受此次传输(从设备决定)! u. \: B# Y$ K/ H
由于传输未使能或初始化,总线的从设备无法进行此次传输(例如,如果外设的时钟被关闭,那么访问这个外设时,微控制器就可能会产生错误响应)。
9 g2 s& G: G9 h; c$ |5 x当确定了硬件错误异常的直接原因以后,我们可能还得花费一些时间来确定问题的根源。例如,总线错误可以由很多种情况引发,例如错误的指针操作、栈空间损坏、内存溢出、非法存储器映射以及其他原因。5 g* v2 H9 b' i
$ V1 v4 d9 ~( L h) i* A6 x) [分析错误
% G! u* l: r+ g. {. u根据错误类型的不同,通常能够直接确定引起硬件错误异常的指令的位置。要实现这个目的,就需要知道进入硬件错误异常时的寄存器的内容,以及异常处理前压入栈中的寄存器的内容。这些值中包含了程序返回地址,通过它也能知道引起错误的指令地址。
+ A" C$ E! b7 N* s. t6 m* K: Q4 m# ?6 C
如果使用了调试器,那么可在工程中创建硬件错误异常处理,并且在其中添加一个用以暂停处理器的断点指令;或者也可以在硬件错误异常处理的开始部分设置一个断点,这样当硬件错误发生时,处理器就会自动暂停。在处理器由于硬件错误暂停后,我们就可以尝试着按照下面图的流程对错误进行定位。
5 W8 U# y, K9 r' c8 k9 W: X w; h+ D, u! v0 G4 s
为了给分析提供更多的信息,也可以生成程序映像的汇编代码,并且利用在栈帧中找到的PC值确定错误的位置。如果错误的地址为存储器访问指令,就应该检查寄存器的值确定存储器访问的地址是否合法。除了检查地址范围,也应该确认存储器的地址是否正确地对齐。
; S& ?7 p4 O9 L9 T& o
" y) c$ k' R- h# k; K除了压入栈中的PC值(返回地址),栈帧中也包含了其他有助于调试的寄存器值。例如,压入栈的IPSR能够反映处理器是否在进行异常处理,EPSR则代表了处理器状态(EPSR的T位为0,则表示错误由意外切换至ARM状态引起)。
~: E+ ~5 V. B" g* k5 w7 ^( s! x- f) i _( j, f% O6 i
栈中的LR也可能会提供一些信息,例如发生错误的函数的返回地址,错误是否发生在异常处理中,以及EXC_RETURN的值是否被异常破坏等。
) t6 f! V8 z" A- }3 c# E! Q4 e
+ c, i' F5 k4 D% j. I. j另外,当前的寄存器值也可以提供有助于定位错误原因的各种信息,除了当前栈指针的值,当前的链接寄存器的值也可能有帮助。如果LR中为非法的EXC_RETURN的值,这就意味着它在前面异常处理中被错误地修改了。3 z& X1 V4 V% [
* u9 q1 e: L& S& |
8 }' A( O: }( p Y- q- y* }
CONTROL寄存器也可以提供帮助。在没有OS的简单应用程序中,进程栈指针(PSP)不会被用到,并且CONTROL寄存器会一直保持为0。如果CONTROL寄存器被设置为0x2(PSP用于线程状态),这就意味着LR在之前的异常处理中被错误地修改了,或者栈内容被破坏导致了EXC_RETURN的值错误。) z: d' A, u) g2 {6 k+ L6 Z
; W+ J, ?7 L% X* L, [" \
, j$ {) o' a8 U; @7 _- O5 L7 O
|
|