我在执行程序时遇到了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。 有没有人有这方面的工作代码?
否则,请按照以下方式手动执行:
我做错了什么?
答案 0 :(得分:0)
您的代码存在一些问题
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];
每当我读取PC的值时,它就是0.
你的程序实际上可能已经跳转到地址0(例如通过空函数指针),试图执行那里找到的值,这可能不是有效的指令,而是来自向量表的初始SP值,并且出现了错误。这段代码
void (*f)(void) = 0;
f();
就是这样,我在偏移24处看到0x00000000。
有人会为此工作代码吗?
This works for me.注意在psp和msp之间选择的代码,以及__attribute__((naked))
指令。您可以尝试为编译器找到一些等价物,以防止编译器分配堆栈帧。