作者:小湿基_517 | 来源:互联网 | 2024-10-26 12:18
本文深入解析了RTThread操作系统中的HardFault_Handler机制,详细探讨了其在故障定位中的应用与实现方法,为开发者提供了有效的调试工具和策略,有助于提升系统的稳定性和可靠性。
转载:https://blog.csdn.net/suny1234/article/details/89419075
在《RTThread中HardFault_Handler分析》一文中已经分析了RTThread中对于fault中断的处理方法。接下来讲解如何根据错误输出信息对程序出现fault的位置进行定位。
rtthread_simulator_v0.1.0 工程中的main.c中的我们添加以下3行代码
void(*fp)(void) ; //1
int main(void)
{fp = 0; //2fp(); //3return 0;
}
编译后按ctrl+5进入软件仿真状态,全速运行后,UART#1窗口输出如下信息
由此可见运行时候发生了fault,通过《RTThread中HardFault_Handler分析》的内容我们可以知道,输出窗口中打印出来了各个
上述寄存器信息中,lr寄存器中的值为0x08000151 ,此值为进入fault异常中断之前的lr的值。
我们知道lr为连接寄存器里面保存的是调用子程序之前的PC的值。 因为 CM3 内部 使用了指令流水线,读 PC 时返回的值是当前指令的地址+4 ,所以进入异常之前自动加载到lr的值也为调用子程序前的指令地址+4。由于PC的最低位保存ARM/Thumb 运行状态,Cortex-M3只能运行在Thumb 状态,即LSB = 1。所以我们想要找到出错误程序的指令位置, 只需要对打印出来的lr的值减去5即可。
0x08000151 减去5后为0x0800014C 说明我们程序出错位置在PC = 0x0800014C 附近。
在Disassembly窗口下,我们找到0x0800014C 指令位置
可以看到 0x0800014C 指令位置正好在fp()代码段内。
我们进一步分析产生错误的原因,根据打
用法 fault 状态寄存器(UFSR),地址:0xE000_ED2A
main()函数中我们将函数指针fp的值设为了0,然后去调用fp(),相当于让程序跳转到0地址处去运行。实际上真正出错的地方是0x0800014E处,这里执行了一条BLX 跳转指令,执行完将r0的值0更新到了PC,即PC=0。PC的最低位LSB被更新成了0,试图切换到ARM状态,状态寄存器(UFSR) 中的 INVSTATE 位被置位 ,因此产生了fault。