Debugging Cortex M0 HardFault_处理程序并获取故障地址

Debugging Cortex M0 HardFault_处理程序并获取故障地址,debugging,arm,keil,Debugging,Arm,Keil,我在执行程序时遇到了硬错误。我已经找到了几十种方法来获取PC的价值,但我使用的是Keil uVision 5,但没有一种有效 据我所知,我不是在一个多任务环境中,而PSP包含0xFFFFF1,所以添加24会导致溢出 以下是我设法实现的功能(例如,它编译并执行): 注意“+=0x20”,它在这里用于补偿C函数堆栈 每当我读取电脑的值时,它都是0。 有人会为此编写工作代码吗 否则,我将手动执行以下操作: 在HardFault_处理程序(原始处理程序)上放置断点 当它断裂时,看起来像MSP 在其值上

我在执行程序时遇到了硬错误。我已经找到了几十种方法来获取PC的价值,但我使用的是Keil uVision 5,但没有一种有效

据我所知,我不是在一个多任务环境中,而PSP包含0xFFFFF1,所以添加24会导致溢出

以下是我设法实现的功能(例如,它编译并执行):

注意“+=0x20”,它在这里用于补偿C函数堆栈

每当我读取电脑的值时,它都是0。 有人会为此编写工作代码吗

否则,我将手动执行以下操作:

  • 在HardFault_处理程序(原始处理程序)上放置断点
  • 当它断裂时,看起来像MSP
  • 在其值上加24
  • 在那个地址转储内存。 这就是0x00000000

我做错了什么?

您的代码有一些问题

uint32_t *stack;
__ASM volatile("MRS stack, MSP");
MRS
仅支持注册目的地。您的汇编器可能不够聪明,无法首先将其转移到临时寄存器,但我希望看到由此生成的机器代码

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

pc = stack[pc];
psr = stack[psr];
它使用以前的
pc
psr
值作为索引。应该是

pc = stack[6];
psr = stack[7];
每当我读取电脑的值时,它都是0

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

void (*f)(void) = 0;
f();
确实如此,我在偏移量24处看到0x00000000

有人会为此编写工作代码吗


请注意在psp和msp之间选择的代码,以及
\uuuuu attribute\uuuuu((裸))
指令。您可以尝试为您的编译器找到一些等价物,以防止编译器分配堆栈帧。

谢谢,我添加了一些精度和缺少的代码。我的编译器/汇编器实际上不支持“MRS R0,MSP”,但是我的“MRS stack,MSP”的结果是相同的。这限制了我很多,它似乎不理解任何寄存器。到目前为止,我还没有找到能够与编译器一起工作的_属性_u((裸))的等价物,但无论如何,您确认了这是完全正确的。非常感谢你们提供了调用空指针的技巧,我并没有想到,可能是一个丢失的回调…根据你们的回答,我看了一下压入堆栈的LR值。它指向一个有效的位置,所以我猜就是它了,谢谢!
void (*f)(void) = 0;
f();