单片机非调试模式程序异常定位指南
前言:
在机器出现异常程序跑飞时,大多都是非调试状态下的,这时我们也不能使用keil进行仿真,一直仿真程序重启问题可能就无法复现,在这种情况下就可以不断电不重启软件使用JLink连接来实时获取单片机里的内容
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:内存映射分布
标明了内存映射分布,起始地址,大小,类型,属性等信息
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