Embedded ARM Cortex M3在发生硬故障之前如何确定程序计数器值?

Embedded ARM Cortex M3在发生硬故障之前如何确定程序计数器值?,embedded,arm,interrupt,cortex-m3,program-counter,Embedded,Arm,Interrupt,Cortex M3,Program Counter,我有一个使用STM32F103(ARM Cortex M3)的嵌入式项目,它在发布模式下偶尔会出现硬故障。作为恢复的一部分,我想从硬故障之前检索PC值,并将其存储在备有电池的区域中,以便以后进行调试 在硬故障点,如何确定程序计数器的值?显然,PC现在已设置到硬故障中断内的位置 我应该去哪里看?正常模式寄存器组有地址吗 谢谢 您应该查看异常部分中的。你需要注册才能得到它 通常,一个相关地址将被放入链路寄存器LR(R14)中,但其确切含义根据异常情况而不同,并且偏移量也不同 W.r.t.访问用户/系

我有一个使用STM32F103(ARM Cortex M3)的嵌入式项目,它在发布模式下偶尔会出现硬故障。作为恢复的一部分,我想从硬故障之前检索PC值,并将其存储在备有电池的区域中,以便以后进行调试

在硬故障点,如何确定程序计数器的值?显然,PC现在已设置到硬故障中断内的位置

我应该去哪里看?正常模式寄存器组有地址吗

谢谢

您应该查看异常部分中的。你需要注册才能得到它

通常,一个相关地址将被放入链路寄存器LR(R14)中,但其确切含义根据异常情况而不同,并且偏移量也不同


W.r.t.访问用户/系统模式注册库,我认为您需要切换模式以访问它。

我发现这些问题的常见原因是“for loop”延迟。当使用-O3时,如果您不是指易失性变量,它们只是得到优化。就个人而言,我更喜欢SysTick方法。

当出现异常时,处理器状态将从当前状态更改为中止状态。在中止状态下,处理器将使用一组新的sp和lr寄存器(分别为sp_abt和sp_lr)。对于数据中止,对于lr_abt+4中的Perfect about,可以在lr_abt+8中找到有问题的指令(根据ARMv7 Architecure参考手册)

Cortex-M3使用与以前完全不同的异常处理模型“经典”ARM,例如,它没有其他帖子中提到的“中止模式”。我建议您阅读。例如,对于硬故障:

SCB->BFAR的值表示导致总线故障的内存地址 如果设置了SCB->CFSR寄存器中的位BFARVALID,则为有效 SCB->MMFAR的值表示导致内存中断的内存地址 管理故障,如果位MMFAR在SCB->CFSR中有效,则有效 寄存器已设置


要在发生异常时确定PC值,您需要检查堆栈;处理器在执行处理程序之前推送R0-R3、R12、PC和LR。使用的堆栈可以是Main(如果LR的位2为0)也可以是Process(否则)。有关详细信息,请参阅应用程序说明的第13页。

我有一个关于此主题的常见问题解答。从常见问题解答链接到的页面包括将为您从堆栈中获取程序计数器的页面。

我也想知道,但您可能会在chiphacker.com.Ahh上得到更好的答案。酷!调试时检查它(目前不知道如何调用硬错误;p)并且它确实显示了调用方的地址。非常感谢!好的,我看到它不是调用方,而是返回地址。我通过以下方式生成硬错误:*((char*)0x00)=5;感谢@leppie,衷心同意。这里没有循环延迟,我也在使用SysTick进行计数。为了避免阻塞,每件事情都在状态机中。我认为如果我给它足够的时间,问题会在调试模式下出现。将sp_abt更改为lr_abt对我来说是一个非常严重的错误-现已修复这对经典的ARM b有效但不是Cortex-M3我想你指的是lr_abt-8和lr_abt-4。谢谢Igor,我如何从堆栈中取出PC?你需要取出PSP或MSP,并从中获取偏移量0x18处的一个字。请参见此处的示例实现:仍在尝试解决此问题。此偏移量比MSP高24字节吗?:uint32_t*PC=(uint32_t*)((char*)\u get_MSP()+24);您应该在汇编程序中进行,编译器可能会在堆栈值进入代码之前调整堆栈值。是的,我看到了。现在只需更正偏移量并获得正确的PC值。我需要在发布模式下进行测试,以确保偏移量不会更改。再次感谢!