在R5的核上跑freertos的操作系统,进入异常中断后怎么获取进入异常前的PC指针?主要是想知道进入异常的时候程序运行到了哪里。该怎么实现?是不是下图中的R14_USER寄存器就存储了进入异常前的PC指针?如果是的话,怎么获取R14_USER寄存器?

This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
在R5的核上跑freertos的操作系统,进入异常中断后怎么获取进入异常前的PC指针?主要是想知道进入异常的时候程序运行到了哪里。该怎么实现?是不是下图中的R14_USER寄存器就存储了进入异常前的PC指针?如果是的话,怎么获取R14_USER寄存器?

个人理解R14_USER寄存器应该是用户模式下的链接寄存器,存储跳转到当前函数返回地址。发生异常时,LR值会被保存堆栈中
我画了个R5异常堆栈结构示意简图:
+-----------------------------+
| Exception Stack Frame |
+-----------------------------+
| R0 |
+-----------------------------+
| R1 |
+-----------------------------+
| R2 |
+-----------------------------+
| R3 |
+-----------------------------+
| R12 |
+-----------------------------+
| LR (R14_USER) |
+-----------------------------+
| PC (R15) |
+-----------------------------+
| xPSR |
+-----------------------------+
| S0 |
| |
| ... |
| |
| |
+-----------------------------+
在这个堆栈帧中,LR(R14_USER)的偏移量为4,因此可以通过读取堆栈中R14_USER的偏移地址来获取进入异常前的PC指针。
然后我自己写一个示例,您试一下使用这个方式获取R14_USER的值看是否可行,:
void exception_handler(void)
{
// Get the LR (R14_USER) value from the stack
uint32_t* stack_ptr = (uint32_t*)__get_PSP(); // or __get_MSP() depending on the stack used
uint32_t lr_value = stack_ptr[6]; // Assuming R14_USER is at offset 6 in the stack frame
// Now lr_value contains the value of LR (R14_USER) before the exception
// You can use it to determine where the exception occurred
}
`__get_PSP()`和`__get_MSP()`是CMSIS提供的宏,获取当前任务的堆栈指针。
如上述方法不行,您再试一下内嵌汇编或者纯汇编,我写了一段示例代码,供您参考下:
获取PSP
内嵌汇编:
uint32_t get_PSP(void)
{
uint32_t psp_value;
__asm volatile("MRS %0, PSP" : "=r" (psp_value));
return psp_value;
}
纯汇编:
get_PSP: MRS r0, PSP BX lr
获取R14_USER(LR)
内嵌汇编:
uint32_t get_LR(void)
{
uint32_t lr_value;
__asm volatile("MOV %0, LR" : "=r" (lr_value));
return lr_value;
}
纯汇编:
get_LR: MOV r0, LR BX lr