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

【STM32F303开发】+ 关于连接寄存器LR的值 精华

[复制链接]
creep 提问时间:2015-7-7 22:50 /
昨天有位同学看了我之前的这个帖子:【STM32F303开发】+如何找到导致程序出现HardFault的代码   后在社区群里说他也遇到了这个问题,但是他不太清楚那个帖子最后的那个图片的中的有2个LR的值哪个才是有用的,该使用哪个LR的值去找跑飞的代码。我告诉他是debug viewer中输出的那个,他好像还是不太明白,下面我们就简单的看下LR的变化过程。他说的那个图片如下,其中包含了2个LR,左边一个寄存器R14的值,右边debug viewer输出一个。
lr.jpg
我们通常说的LR寄存器就是寄存器R14,它常用于在调用子程序分支时存储返回地址,调用完成后用于返回到调用之前的地方继续执行下面的代码,
《Cortex-M3 权威指南》对LR的描述如下,其中提到了LR的地址等于当前子程序分支的下一条指令的地址。
lr.jpg
我们知道当程序发生异常或者中断时会自动保存现场将xPSR,PC,LR,以及R0-R3由硬件自动压入堆栈以及一些其他的处理,然后程序进入异常或者中断函数,此时LR的值将会被自动被更新为特殊的EXC_RETURN.《Cortex-M3 权威指南》里的详细的介绍如下:
lr.jpg

下面我们根据上面的叙述结合实际的代码看下LR的值的变化过程:
1)我们在异常函数void HardFault_Handler(void)里面设置一个断点后debug下全速运行,这个函数是重载的系统的函数,当出现HardFault时会自动进入这个函数,可以看到此时的LR=0XFFFFFFF9,且此时处于Handler模式,和上面的描述相符。在这个函数里面首先判断是使用的MSP还是SPS,然后将这个SP的值保存到r0寄存器,然后调用函数void Hard_Fault_Handler(uint32_t stack[]),此时的r0,作为函数Hard_Fault_Handler的参数。
lr.jpg
下面我们进入到void Hard_Fault_Handler(uint32_t stack[]),具体如下,主要是打印一些信息出来,我们在下面的函数里设置一个断点,然后进入到下面的函数中去
  1. void Hard_Fault_Handler(uint32_t stack[])
  2. {
  3.    static char msg[80];
  4.                 printf("In Hard Fault Handler\n");
  5.                 sprintf(msg, "SCB->HFSR = 0x%08x\n", SCB->HFSR);
  6.                 printf(msg);
  7.                 if ((SCB->HFSR & (1 << 30)) != 0)
  8.                         {
  9.                          printf("Forced Hard Fault\n");
  10.                          sprintf(msg, "SCB->CFSR = 0x%08x\n", SCB->CFSR );
  11.                          printf(msg);
  12.                          if((SCB->CFSR & 0xFFFF0000) != 0) {
  13.                                         printUsageErrorMsg(SCB->CFSR);
  14.                          }
  15.                          if((SCB->CFSR & 0xFF00) != 0) {
  16.                                         printBusFaultErrorMsg(SCB->CFSR);
  17.                          }
  18.                          if((SCB->CFSR & 0xFF) != 0) {
  19.                                         printMemoryManagementErrorMsg(SCB->CFSR);
  20.                          }      
  21.                 }  
  22.                 stackDump(stack);
  23.                 __ASM volatile("BKPT #01");
  24.    while(1);
  25. }
复制代码
在断点暂停后我们发现LR的值还没有发生变化,还是刚进入中断函数的0xFFFFFFF9,
lr.jpg
程序在进入函数时把r0的值传给了r4,用于保存参数的值,因为下面要用到r0.
lr.jpg

继续看下面的汇编。将要输出的字符的地址传到r0保存,我们可以在内存中看到地址0x08000818中保存的就是要输出的字符串"In Hard Fault Handler\n",同时也可以在我们上次得到的反汇编文件中看到这个FLASH地址保存的输出字符。
lr.jpg
反汇编中得到保存的输出字符的位置,具体参考:【STM32F303开发】+使用fromelf反汇编keil生成的AXF文件
lr.jpg
保存好参数r0后程序会跳转到输出函数的地址0x08002080继续执行,注意输出字符串函数下面的一条语句的地址为0x080006c6,这个地址将会在程序跳转到输出函数时被保存在LR中,此时的LR的值将会发生变化。在0x08002080设置个断点,然后全速运行程序,程序会暂停在输出函数。
从下图中可以看到LR的值从进入中断函数时的0xFFFFFFF9变成了0x080006c7(指令最低bit0必须为1),这个值正好是我们跳转前的下一句代码的地址0x080006c6.
lr.jpg

综上,进入中断函数时的LR为特殊的EXC_RETURN,但是如果在中断函数中有发生子程序分支调用时,LR的值就会被压栈,然后发生变化用于存储子程序的返回地址。而我们用于保存跑飞代码的LR的值一直在保存着并没有发生变化,最后在debug viewer输出的正是我们要找的LR的值。


F303RE_Fault_Handler.rar (396.61 KB, 下载次数: 156)
收藏 6 评论14 发布时间:2015-7-7 22:50

举报

14个回答
Paderboy 回答时间:2015-7-7 22:55:09
沙发了。。。。多谢分享,学习了。。。
creep 回答时间:2015-7-7 23:22:25
Paderboy 发表于 2015-7-7 22:55
沙发了。。。。多谢分享,学习了。。。

   
风子 回答时间:2015-7-8 00:56:12
围观,有点高大上
你好我好大家好! 回答时间:2015-7-8 08:51:40
楼主好给力 啊   ,必定高手     
JackieLaura 回答时间:2015-7-8 09:11:59
看的云里雾里。。。知识点有点多,要仔细研究研究了
creep 回答时间:2015-7-8 09:16:55
JackieLaura 发表于 2015-7-8 09:11
看的云里雾里。。。知识点有点多,要仔细研究研究了

哈哈,我对汇编也不太懂,所以描述起来也不是很清晰,主要是想解释LR的基本用途。
如果真要研究的话,建议把《Cortex-M3 权威指南》好好看看,再分析代码就简单了!
JackieLaura 回答时间:2015-7-8 09:40:10
creep 发表于 2015-7-8 09:16
哈哈,我对汇编也不太懂,所以描述起来也不是很清晰,主要是想解释LR的基本用途。
如果真要研究的话,建 ...

51汇编倒是看得懂,ARM指令有点多,也没去看,要去深入的研究一下了。。
星辰一方 回答时间:2015-7-8 10:17:56
高手,学习了……没了解过这块
baisse-355648 回答时间:2016-5-30 12:48:11
楼主好给力 啊   ,必定高手   
creep 回答时间:2016-5-31 13:43:12
baisse-355648 发表于 2016-5-30 12:48
楼主好给力 啊   ,必定高手

逗比爱吃比豆 回答时间:2017-6-20 20:09:03
大神,看了你排查硬件错误中断的帖子,请教一个问题,hardfault函数加了__asm编译不通过,keil报错,这是为什么,我看你也没有修改什么
木叶飘 回答时间:2018-2-5 15:43:50
太厉害了,这个问题困惑了好久,谢谢高手!
叶樱枫 回答时间:2018-5-9 17:13:57
感谢楼主分享
founderHAN 回答时间:2018-10-26 11:44:20
正在参考学习,感谢分享!
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版