打印
[APM32F4]

在APM32F407上研究hardfault响应时机

[复制链接]
182|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 onemoren 于 2025-6-25 14:45 编辑

#每日话题# #技术资源#

在APM32F407上研究hardfault响应时机


一般来说,在自己的软件、硬件平台上遇到hardfault还是比较容易定位的。此文以APM32F407做为实验平台,在一个GPIO的例程上制造hardfault,来看其产生后,通过栈中内容回溯hardfault产生的时机。
实验程序如下,很简单:
Faulttest()中包含了越界内存的写入语句,执行时必然会引起hardfault。在仿真条件下全速运行,果然看到PC跳进了硬件错误中断函数中:
此时可以查出SP即栈地址为0x20000640,在memory窗口中查这个地址,可以直接查到hardfault响应前的LR地址为0x08000733。在汇编程序中查找0x08000733位置(0x08000732对齐后的地址),发现LR指向的是while(1)循环体的开始语句:
矛盾点出现了:在调用faulttest(0x55)时,LR应该指向Delay_Init()首地址。当hardfault响应时,LR应该保持指向Delay_Init()首地址并入栈保存,LR应该是0x0800072E,而不是0x08000733。百思不得其解。
除非在hardfault响应中断前,PC指针已指向Delay_Init()甚至可能已经执行了Delay_Init()中的部分程序?
难道hardfault响应是有一定的滞后性?当程序执行*(uint8_t *)0xAF00000 = 0x55时,芯片此时并不立即响应hardfault,而是PC指针又再往下执行了若干条指令?PC指针可能跑到或跑进Delay_Init()中?
接着实验。在Delay_Init()前加入6条NOP指令:
可以看到,hardfault响应时,LR指向0x800072F,也就是说,LR保持着调用faulttest(0x55)时的PC返回值。Hardfault响应前,PC并没有跑到或跑进Delay_Init()中。
将NOP指令减少到3条:
和6条NOP指令效果一致。再将NOP指令减少到2条:
LR值变为0x8000737,说明hardfault产生前PC指向过或跑进过Delay_Init()。
以上实验说明,MCU遇到hardfault时,并不是在产生hardfault的那条指令上立即停止后去执行硬件错误中断服务函数,而是有一定的滞后性,PC指针可能还会向下执行几条指令,才被hardfault中断掉。
当然,我这个实验只研究了内存越界访问时的hardfault响应时机是这样。不知道其它类型的hardfault(如真正的硬件异常引起的错误)是否会“立即”中断程序执行(无滞后性)。这种缺陷芯片可要有缘遇到才有机会研究。

使用特权

评论回复
沙发
发光的梦| | 2025-6-25 17:56 | 只看该作者
PC指针可能还会向下执行几条指令,才被hardfault中断掉。
我还一直以为立即进入hardfault了呢?
不过,会不会是MCU对指令进行了预取了呢?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

44

主题

62

帖子

2

粉丝