目录
在日常开发中,经常会遇到单片机卡死机等问题,经常很难定位到问题代码在哪里。
常见的会导致单片机跑飞卡死的原因比如说死循环、数组越界、野指针等,尤其野指针最难调试,一般调试只能看见程序掉进 HardFault_Handler 死循环,无从得知是什么导致程序掉进了HardFault_Handler,连什么问题卡死都不知道,更别提上哪找了。
(一些硬件问题也会导致HardFault_Handler,了解就好)
Keil调试技巧:
一.不破坏现场连接仿真器与进入debug
假如死机触发比较难,好不容易触发一次想连接仿真器,连完debug自动把单片机reset了,又要等它再触发。
Keil只需按如下设置即可:
1.不要进入debug自动回到startup
2.Jlink连接仿真器自动reset
STlink也一样
3.连接仿真器,点击debug,但发现C语言代码未发生关联,无从得知现在运行到哪了
解决办法:在debug的command窗口输入 LOAD %L INCREMENTAL
然后就会发现C语言关联上了,可以定位到当前代码。
二.栈回溯
首先看调试页面左侧,会有一列寄存器在Core中,它们是ARM的内核寄存器
在ARM中,R0到R15是通用寄存器,除此之外还有特殊寄存器。
R0到R11也叫通用目的寄存器,可以存数值进行运算,
其中R0到R3可以存函数参数, 所以设计函数传参最好不要超过4个,超过4个的话,CPU会有额外负担。
另外函数结束返回时,R0和R1也可以存函数返回值。
我们的关注点在于R13 R14 R15,也叫SP LR PC, 用来存储地址(内存或flash)
SP保存内存中的栈指针地址;
LR保存函数的返回地址;
PC保存当前程序指令的地址。
所以根据上图可知,发生异常中断如 HardFault_Handler 时,通过SP寄存器的栈指针即可找到保存现场的栈结构,
再通过其中的PC和LR上的地址即可对应到当前程序发生问题的指令代码。