TI中文支持网
TI专业的中文技术问题搜集分享网站

MCU-PLUS-SDK-AM243X: 在R5的核上进入异常中断后怎么获取进入异常前的PC指针

Part Number:MCU-PLUS-SDK-AM243X

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

Gary Lu:

? ? 说:在R5的核上跑freertos的操作系统,进入异常中断后怎么获取进入异常前的PC指针?

通过读取特定的寄存器。

? ? 说:主要是想知道进入异常的时候程序运行到了哪里。该怎么实现?

读取特定的寄存器来获取进入异常前的PC指针。

? ? 说:怎么获取R14_USER寄存器?

用汇编指令

MRS r0, R14_USER

,

? ?:

我用内嵌汇编和纯汇编编译都没通过,这个问题和之前问的如何获取psp是一样的问题,报的错都是"invalid operand for instruction",如图 ,所以到底应该怎么获取psp和R14_USER这些特殊寄存器的值?

,

Gary Lu:

个人理解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

,

? ?:

你提到的内联汇编和纯汇编获取psp的方法都不行,报的就是invalid operand for instruction的错,所以我一直在追问的就是获取psp的正确方法是什么?感觉编译器不认psp

,

Gary Lu:

那应该就是不认了

,

? ?:

所以要怎么得到psp,是不是应该有别的指令方法?

,

Gary Lu:

MRS R0, PSP ; 将当前进程堆栈指针(PSP)的值读取到 R0 中

上述指令将当前进程堆栈指针(PSP)的值读取到通用寄存器 R0 中。

如果您希望在异常处理例程中获取进入异常前的 PSP 值,可以在异常入口处保存 PSP 的值,然后在异常处理例程中使用。例如:

在异常入口处保存 PSP 值:

MRS R1, PSP ; 保存当前进程堆栈指针(PSP)的值到 R1 中

赞(0)
未经允许不得转载:TI中文支持网 » MCU-PLUS-SDK-AM243X: 在R5的核上进入异常中断后怎么获取进入异常前的PC指针
分享到: 更多 (0)