Cortex M0 HardFault_Handler并获取故障地址

时间:2017-02-03 11:06:14

标签: debugging arm keil

我在执行程序时遇到了HardFault。我已经找到了很多方法来获得PC的价值,但是我使用的是Keil uVision 5,但没有一种方法可以使用。

据我所知,我不在多任务上下文中,并且PSP包含0xFFFFFFF1,因此向其添加24会导致溢出。

这是我设法工作的原因(如编辑和执行):

enum { r0, r1, r2, r3, r12, lr, pc, psr};

extern "C" void HardFault_Handler()
{
  uint32_t *stack;
  __ASM volatile("MRS stack, MSP");

  stack += 0x20;

  pc = stack[pc];
  psr = stack[psr];
  __ASM volatile("BKPT #01");   
}

注意" + = 0x20",这是为了补偿C函数堆栈。

每当我读取PC的值时,它就是0。 有没有人有这方面的工作代码?

否则,请按照以下方式手动执行:

  • 在HardFault_Handler(原始版本)上放置一个断点
  • 当它破裂时,看作MSP
  • 将24添加到其值。
  • 转储该地址的内存。 它就是,0x00000000。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

您的代码存在一些问题

uint32_t *stack;
__ASM volatile("MRS stack, MSP");

MRS仅支持注册目的地。你的汇编程序迁移是否足够聪明,首先将它传输到临时寄存器,但我希望看到由此生成的机器代码。

如果您使用某种多任务系统,它可能会使用PSP而不是MSP。请参阅下面的链接代码,了解如何区分它。

pc = stack[pc];
psr = stack[psr];

它使用pcpsr的先前值作为索引。应该是

pc = stack[6];
psr = stack[7];
  

每当我读取PC的值时,它就是0.

你的程序实际上可能已经跳转到地址0(例如通过空函数指针),试图执行那里找到的值,这可能不是有效的指令,而是来自向量表的初始SP值,并且出现了错误。这段代码

void (*f)(void) = 0;
f();

就是这样,我在偏移24处看到0x00000000。

  

有人会为此工作代码吗?

This works for me.注意在psp和msp之间选择的代码,以及__attribute__((naked))指令。您可以尝试为编译器找到一些等价物,以防止编译器分配堆栈帧。