你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

ARM CM3/4 异常进入与返回的过程

[复制链接]
qianfan 发布时间:2015-12-6 21:46
    之前在使用中断的时候,对内部的机制不是很了解。特别是相关寄存器的自动保存与恢复。在调试HardFault的时候,(见帖子https://www.stmcu.org.cn/module/forum/thread-604503-1-1.html )不明白出错的地址为什么是从PC处(更准确的说法应该是返回地址)开始找,而不是LR。因此,这里做个简单的实验分享一下。实验相关的代码在附件中可以下载。使用arm gcc进行编译,arm gdb进行调试。keil mdk虽然有不同的地方,但是原理还是相同的。
7 J" p) R1 d% u1 x  ^
. G- t5 b# d$ i& k* V    在《嵌入式软件设计基础,基于ARM cortex-m3》一书中,介绍了进入异常处理程序和从异常处理程序返回的步骤:
6 V- x$ \9 o; q( X& a2 R+ i7 S- Q
  • 进入异常处理程序:
    6 Q' P) u* J% J  E- ]: w
       当处理器识别出异常的时候,会通过特定序列的行为来进行自动响应。
$ F3 G5 z, Z* @
  • 压栈:将寄存器R0-R3和R12的内容,返回地址(并不是PC),PSR和链接寄存器的内容压栈。其中,在栈中存放的顺序从低地址到高地址依次是:R0-R3,R12,LR,返回地址,PSR。
  • 在进行压栈操作的同时,处理器识别异常。将其对异常的识别结果作为PSR中的异常号记录下来,然后使用该数字从向量表中定位和拷贝对应异常处理程序的地址到PC中。
  • LR寄存器中装载除了最低的4位全1的序列,最低4位记录指向异常的处理器模式(线程模式或者异常处理模式)。(注意,LR不包含返回地址!LR中存储的值,通常为EXC_RETURN)作为特殊值由处理器识别,并用在异常处理程序返回时回复之前的模式。
  • 异常处理模式使能。
  • 异常处理程序开始执行。
    ' S; s; f( k; R
- m) C8 R6 s  h1 ?- H& z; C0 ]4 G! ^) j
    2. 从异常处理程序返回2 @& g3 W7 r1 N7 d% J
  • 在异常处理程序将执行EXC_RETURN值装入PC时,处理器初始化返回序列。EXC RETURN通知处理器开始返回序列,确定处理器是返回线程模式还是异常处理模式。然后从栈中弹出8个字,将之恢复到R0-R3,R12,LR和PSR。并将返回地址加载到PC。/ I: y+ i4 e+ ]! ?6 H# G( j
+ [, D. n, t( G. L, I
  • (注1:因为原书是基于ARM CM3讲解的,ARM CM3没有FPU,因此不必处理FPU相关的寄存器。如果是ARM CM4,这里需要保存与回复的不止这些寄存器。还有FPU相关的寄存器。)
  • (注2:这里说的栈中的返回地址和PC还是有区别的。下面还会讲解。)9 A1 j  s( M5 q! \2 O, L/ l% n

/ g7 y) W4 d0 ~6 ^( l- B9 P
5 W( x9 Z8 j( I# a# Y    看下部分源代码:代码中添加的nop指令没有什么作用。主要是为了方便观察自动入栈的LR和PC值的不同。往0xE000ED04处写0x10000000是为了触发PendSV中断。在触发PendSV中断之后,会发生中断的自动保存。
9 H( `$ g8 }. s  d4 a: p' Z5 s7 s 2015-12-06 20:55:19屏幕截图.png
& f& Y  C  D& ~3 r( E- h6 Z" E& Y) j6 v
1. 使用arm gdb进行调试。在PendSV_Handler中断处理函数上点一个断点。之后输入continue继续运行。直到断点处停止。: I" d/ u9 Z- Z  |4 Q2 K
2015-12-06 21:23:50屏幕截图.png
3 k+ O/ m) L1 ^! A6 m" g
* E6 t+ H1 H* t9 V# e  U8 L& E2.这时候进入了PendSV中断,并且相关的寄存器已经得到入栈保存。可以使用disassemble查看当前的汇编代码。可以发现在自动保存R0-R3,R12,LR,返回地址,PSR之后,编译器还push 了R7和LR。' {' k) _) U$ c* H
2015-12-06 21:25:48屏幕截图.png
& r5 U) K+ X! ]- H/ B! \4 t; A) J  k3 B0 R, u0 D0 }
3.通过info reg查看相关的寄存器。LR的值是0xFFFFFFF9。这个数就是EXC_RETURN。更加具体的解释可以参考ARM cortex-m3权威指南。这里看到的一个比较重要的地址是sp。发生中断之后,自动保存的寄存器就在他里面。+ e' J8 C" `$ `! w
2015-12-06 21:27:58屏幕截图.png
" |8 _' ~0 ^3 ]! ]; w/ O使用x/10xw 0x2000ffd0查看sp处连续的四个字。因为进入PendSV之后,编译器自动压入了R7和LR。所以前两个数是当前的R7和LR(数据正好和我们使用info reg读出来的吻合)。0x0000000a是R0 ... 中断发生时,自动保存的LR是0x08008637,返回地址是0x08002646。因为ARM CM3/4只能执行THUMB指令,所以LR的实际地址应该是0x08008636。(具体为什么是这样,可以查看ARM CM3权威指南)6 T; }- l- k( r4 ^0 [! w
2015-12-06 21:30:47屏幕截图.png 6 y% b0 N( l7 P9 u" l( I( N

! b; F1 O% [+ |4.使用disassemble查看main的汇编代码:(PS:使用disassemble查看汇编代码的时候,他会一些ldr的数据当成指令来翻译。准确的翻译可以使用arm-none-eabi-objdump -d main.o来查看)。8 L9 j3 `8 f$ d) V2 _+ K+ U( t
2015-12-06 21:36:04屏幕截图.png
2 h+ k, I4 G7 d/ A2 q使用objdump查看的代码,明显的不同是对ldr数据的翻译上。
- ^) r5 ^4 G* H2 Q/ ^ 2015-12-06 21:38:09屏幕截图.png 6 N; g- c$ h$ A9 P( `
实际触发PendSV的代码是0x08002644的那一行代码。因此从中断返回的代码也就是他的下一条指令。也就是0x08002646。这个值也就是自动保存在栈中的返回地址。; E3 y& S; J9 I1 g" H" w9 j
在触发中断之前,最后一条能够更新LR的指令是bl hello。他将LR的位置更新到bl hello的下一条指令。也就是0x08002636。由于是thumb指令,所以将最低位置1。因此自动保存在栈中的数值也就是0x08002637。
  H& l. X( o: S9 j/ ~' X
0 D6 U5 i  R# [好了,暂时就解释这么多。更加具体的解释请参考ARM cortex-m3权威指南。* c+ o4 `. \9 H2 N
之前有朋友在社区群中问,ARM CM3权威指南中的汇编部分是不是要看。我觉得还是要看的。虽然不一定要会使用汇编写程序,但是简单的汇编代码一定要懂。这对你写程序帮助不是很大。但是对你debug确实受益匪浅。! @2 i1 T) @3 Y2 i# U. V; I
, j5 a6 I" x' d$ z

interrupt.zip

下载

523.46 KB, 下载次数: 21

评分

参与人数 1 ST金币 +20 收起 理由
沐紫 + 20

查看全部评分

赞 收藏 1 评论7 发布时间:2015-12-6 21:46

举报

7个回答
Paderboy 回答时间:2015-12-6 22:45:18
多谢分享,大师出手不凡。。。4 u* y7 B# |+ A

2 y; w# u0 h. i% M2 ` STMCU-Logo.png & A# i9 `1 `  X! q# y
qianfan 回答时间:2015-12-7 16:58:07
Paderboy 发表于 2015-12-6 22:45" t! X5 H6 Y! I+ {/ L8 \
多谢分享,大师出手不凡。。。

; K$ f* I/ m. C7 i4 p* p
stary666 回答时间:2015-12-7 17:00:06
看看,,,,,,,,,,,,,,,,
mark0668 回答时间:2015-12-7 17:02:56
多谢分享
STM32.png
埃斯提爱慕 回答时间:2015-12-7 19:57:06
提示: 作者被禁止或删除 内容自动屏蔽
moyanming2013 回答时间:2015-12-7 22:01:44
, p" H; w( h* x  |; q
多谢分享,大师出手不凡
yanhaijian 回答时间:2015-12-10 19:31:34
学习了。

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版