Cortex-M3如何跳出BusFault,跳过出错代码,程序往下执行

为了方便演示如何实现该方法,采用构造触发BusFault,方便分析

  1. 首先需要对系统Handler控制及状态寄存器SHCSR.MEMFAULTENA使能
    在这里插入图片描述

  2. 往SRAM reserved写入数据,触发BusFault

在这里插入图片描述

如上图所示,可以看到触发BusFault前BFSR寄存器第7为高,表示BFAR寄存器有效,且BFAR与MMAR寄存器一致,都为0xE000EDF8

在这里插入图片描述

此时,需要注意SP指针为0x2000A208,并且存储内容为0x2000A20C,这有助于找到触发BusFault,压栈前的SP指针

在这里插入图片描述

进入中断前PC指针为0x77B4,这个有利于分析压栈地址正确与否

在这里插入图片描述

  1. 进入中断,如下图所示:
    在这里插入图片描述

可以看到BFSR寄存器为14,为不精确的数据访问违例(violation,本来应该时精确的数据访问违例,不知道为啥后来变成这样了),LR寄存器赋值解释如下

在这里插入图片描述

并且SP指针为0x2000A1E8(这个很重要)。根据入栈顺序以及入栈后堆栈中的内容表可反推出旧的SP位置为新的SP+32

在这里插入图片描述
在这里插入图片描述

可以发现,通过新SP+32的方式找到的旧SP与原来的SP一致

在这里插入图片描述

此时,新的SP+24就可以得到压栈前PC指针

在这里插入图片描述

通过对比可以发现此时0x77B4就是进入BusFault前,PC指针

在这里插入图片描述

也就是说假如清除中断标志位后退出中断,或者说出栈后PC指针就是该值。但是BusFault清除中断后退出中断,PC指针指向为该地址,并不会自动+4。因此还是会再次进入BusFault。这里就解释了为什么MemMange Fault, Bus Fault, Usage Fault清除中断标记位后还是出不来的原因

因此,只需要在该地址上,给0x77B4+4,这样清除中断标记位后,就能使程序不再进入BusFault。

  1. 但是当程序往下运行时,可以程序又执行了一次压栈,SP指针由0x2000A1E8变成0x2000A1E0,SP指针减了8,故在采用SP指针修改PC指针的时候,一定要注意压栈的次数,SP改变次数,反推进入Handler时候的SP指针 我这里一共改变了12

在这里插入图片描述

  1. 对BFSR寄存器清空,也就是清除中断标记位 注:USFR BFSR MFSR合称 CFSR

在这里插入图片描述

在这里插入图片描述

  1. 获取当前SP值,并进入Handler时候的SP指针,其中 24表示压栈后PC偏移地址,+24表示找到压栈后的PC地址,4*6表示压栈前的PC指针(这里指针同地址),可以看到修改后的PC值为0x77B8。此时程序往下执行便不会再次触发BusFault,程序往下继续执行。

在这里插入图片描述

便不会再次触发BusFault,程序往下继续执行。
在这里插入图片描述

注意:采用修改PC值跳出BusFault,最好在进入BusFault后不在有程序跳转,防止PC值改变,另外程序也应该尽量简短,防止压栈出栈次数太多破坏各寄存器值。并且触发BusFault的整体函数也应该减少程序调用。总之,通过修改PC值,在代码中不是一种好的方法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CinzWS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值