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。
有人会有工作代码吗?
否则,这是我手动执行的方法:
- 在HardFault_Handler(原来的那个)上打个断点
- 断线时看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];
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))
指令。您可以尝试为您的编译器找到一些等效项,以防止编译器完全分配堆栈帧。
我在执行我的程序时遇到了 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。 有人会有工作代码吗?
否则,这是我手动执行的方法:
- 在HardFault_Handler(原来的那个)上打个断点
- 断线时看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];
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))
指令。您可以尝试为您的编译器找到一些等效项,以防止编译器完全分配堆栈帧。