单片机非调试模式程序异常定位指南

前言:

在机器出现异常程序跑飞时,大多都是非调试状态下的,这时我们也不能使用keil进行仿真,一直仿真程序重启问题可能就无法复现,在这种情况下就可以不断电不重启软件使用JLink连接来实时获取单片机里的内容

  • Map文件
  • Map文件是keil工程自动生成的包含了函数调用关系、内存分布、未使用模块等关键信息

    1.Section Cross References:各文件模块中函数的交叉引用

            main.o(i.main) refers to power.o(i.Arm_PowerOn) for Arm_PowerOn

            在main.c文件中的main函数中调用了power.c文件中的Arm_PowerOn函数

    2。Removing Unused input sections from the image:移除未调用模块

           一些定义了但未被调用过模块,可以看情况去除以减轻对内存资源的占用

    3.Image Symbol Table:映射符号表

            标明了各个文件中的全局符号的存储位置,类型和大小

    4.Image component sizes:存储组成大小

    5.Memory Map of the image:内存映射分布

    标明了内存映射分布,起始地址,大小,类型,属性等信息

  • JLink 连接
  • 1.建立连接

    (1).输入connect建立连接后

    (2).选择所使用的芯片型号

    (3).选择使用的连接工具(这里用的是SWD)

    (4).选择下载速率(默认4000kHz)

    识别到内核后就建立连接成功

    三.程序异常定位

    引用调试休眠唤醒时开ACC后一直无法唤醒举例,休眠时无法进行仿真,这时使用JLink command连接

    常用指令
    Mem 读内存

    mem8 读8比特内存

    mem16 读16比特内存

    mem32 读32比特内存

    w1 写8比特内存

    w2 写16比特内存

    w4 写32比特内存

    h 停止cpu运行的程序

    setbp 设置断点

    g 跳到代码段地址执行

    s 单步执行(调试用)

    r 复位

    q 退出
    ————————————————                   
    原文链接:https://blog.csdn.net/qq_30095921/article/details/128311887

    堆栈指针R13(SP)

    当ARM进入异常模式的时候,程序就可以把一般通用寄存器压入堆栈,返回时再出栈,保证了各种模式下程序的状态的完整性。

    连接寄存器R14(LR)
    每种模式下r14都有自身版组,它有两个特殊功能:

    保存子程序返回地址。
    当异常发生时,异常模式的r14用来保存异常返回地址,将r14如栈可以处理嵌套中断。

    程序计数寄存器R15
    PC 指向当前的程序地址。如果修改它的值,就能改变程序的执行流。

    全速跑和单步调试PC指针都指向0x8006026 – 0x800602e  0x8006430 – 0x8006434 

    根据Map文件里内存映射一直都是在py32f031_hal.c文件里的HAL_Delay 和 HAL_GetTick 滴答定时器计数获取函数里重复运行。

    根据映射地址结合反编译出来的汇编文件就是在第二个HAL_GetTick的while循环里重复执行

    从这里可以分析出两个可能

    (1).Delay赋的值太大(毫秒级,长时间等待后程序还是运行在这个地方,基本排除)

    (2).获取计数有问题

    可以在map文件找到uwTick在RAM的地址为0x20000134

    全速跑之后,输入mem32 0x20000134 32 获取这个地址32位数据,多次读取后值都是一样,说明滴答定时器没起作用,导致程序一直卡在Delay。

     

    排查代码发现休眠前将定时器给禁用了,唤醒后未将定时器使能,唤醒后使能定时器后正常通过Delay,休眠唤醒成功。

    作者:Ah_777

    物联沃分享整理
    物联沃-IOTWORD物联网 » 单片机非调试模式程序异常定位指南

    发表回复