Cortex M0 HardFault_Handler 并获取故障地址

Cortex M0 HardFault_Handler and getting the fault address

我在执行我的程序时遇到了 HardFault。我已经找到了数十种获得 PC 价值的方法,但我使用的是 Keil uVision 5,其中 none 有效。

据我所知,我不在多任务环境中,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。 有人会有工作代码吗?

否则,这是我手动执行的方法:

我做错了什么?

您的代码存在一些问题

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

MRS 仅支持注册目的地。您的汇编程序可能足够聪明,可以先将其传输到临时寄存器,但我希望看到从中生成的机器代码。

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

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

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

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

Whenever I read the PC's value, it's 0.

您的程序可能实际上已跳转到地址 0(例如,通过空函数指针),试图执行在那里找到的值,这可能不是有效指令,而是向量的初始 SP 值 table,并对此提出了错误。此代码

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

确实如此,我在偏移量 24 处看到 0x00000000。

Would anyone have working code for that?

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