热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

RTThread故障定位技术详解与应用

本文深入解析了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;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

编译后按ctrl+5进入软件仿真状态,全速运行后,UART#1窗口输出如下信息

在这里插入图片描述

由此可见运行时候发生了fault,通过《RTThread中HardFault_Handler分析》的内容我们可以知道,输出窗口中打印出来了各个


  • 寄存器的状态

    usage fault:

    psr: 0x60000000
    r00: 0x00000000
    r01: 0x20000000
    r02: 0x00000014
    r03: 0x0000000a
    r04: 0x00000000
    r05: 0xdeadbeef
    r06: 0xdeadbeef
    r07: 0xdeadbeef
    r08: 0xdeadbeef
    r09: 0xdeadbeef
    r10: 0xdeadbeef
    r11: 0xdeadbeef
    r12: 0x00000000
    lr: 0x08000151
    pc: 0x00000000

  • 出错的线程:main

    hard fault on thread: main

  • 具体的错误信息:用法 fault ,状态寄存器(UFSR) 值为 0x02 即视图切换到ARM状态

    usage fault:
    SCB_CFSR_UFSR:0x02 INVSTATE

上述寄存器信息中,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。


推荐阅读
author-avatar
小湿基_517
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有