keil调试专题篇
通过"Internal"可以查看当前是处在中断还是任务中,Mode为"Thread"表示是在线程/任务中,或者是函数中(非中断),为"Handle"表示是在中断中;另外"Banked"中的MSP为当前程序系统主栈,PSP则为操作系统的任务栈,这两者的区别是,如果使用了操作系统,则当前任务中的所有调度关系使用的是任务栈,而类似中断这种内核的操作使用的是主栈;:如果是在C语言窗口中,则是按单条语句执行
调试的前提是需要连接调试器比如STLINK。
然后点击菜单或者快捷图标均可进入调试模式。
如果前面工程配置里选择了复位调试,则进入调试后,会停在main函数头部
示意:
相关指令
上面一行红框内,从左到右分别是:打断点(断点最多只能打7个)、失能单个断点、失能所有断点、取消所有断点。
下面一行红框内,从左到右:
复位(Reset):对程序进行复位操作,根据烧录器不同的复位方式配置会触发不同的复位类型。当想要重新debug时,debug可以复位,不需要关掉重新开始。
全速运行(Run):使当前程序开始正常全速运行,直到程序遇到断点时停止。
停止运行(Stop):当程序全速运行时,点击此按键可停止程序运行。点击停止时程序执行到哪了就停在哪。
单步调试(Step)F11:根据当前调试的窗口的语言,执行单条语句。如果遇到函数,则会进入函数内部。如果是在反汇编窗口中,则只执行一条汇编指令。单步调试时能大概感性体会到一个函数用的时间长短,尤其是用时较长的函数。
单步跳过调试(Step Over)F10:如果是在C语言窗口中,则是按单条语句执行,与单步调试不同的是,遇到函数不会进入函数内部,而是直接全速运行函数,并跳到下一条语句。
单步返回调试(Step Out):如果是在C语言窗口中,则是直接全速运行当前函数后面所有内容,直到函数返回上一级。
全速运行到光标所在行(Run to Cursor Line)
变量查看窗口——Watch1,Watch2
也可通过view菜单内对应子菜单选择。
Watch窗口如下:
通过选中一个变量,右键添加入对应的Watch窗口,可以追踪查看当前变量的变化状态。
注意
只有全局变量可以全程监视;
函数只要出去,局部变量就被释放了,临时变量只有在进入当前函数中才可监视到其数据;
用static关键词修饰的变量无法监视。
如果当前变量没有实时更新,则需要点击"View->Periodic Window Update"将其勾选上。
在"Watch"窗口中,可以查看当前变量名称、值、数据类型,如果当前变量类型为结构体,则可以以对应的结构形式进行展开查看。
变量值默认是以十六进制来显示的,可以在变量名上右键,取消十六进制显示,则会以十进制进行显示。
注意,看数组时不带方框
内存查看窗口——Memory
通过"View->Memory Windows->Memory1/2/3/4"打开Memory窗口,也可以通过工具栏打开
在Memory窗口中输入想要查看内存的起始地址,另外右上角的锁可以把当前界面锁定下来,也就不能上下滚动了。
另外如果查看的是Ram的地址,那其中的数据也可以直接通过此窗口进行修改。
同样,右键可以选择以什么数据形式来显示。
这个内存窗口怎么看呢?
你输入一个地址,它会显示从这个地址开始的所有地址内的数据。
这个窗口会根据窗口调节的大小,每次重新排布每一行显示的个数,但是不管怎么样,都是同样的含义。
含义如下:前面的地址表示该行首个数据的地址,后面每一个数据都对应一个字节的地址,地址也都是依次增加的。每个地址都是存储一个字节的数据。
在STM32上做了个简单的验证,确认其是小端存储。
地址0x200004B0的int类型数据是0x000000C8,也就是对应十进制的200;
地址0x200004B4的int类型数据是0x00000064,也就是对应十进制的100;
注意,如果这里更改显示方式,比如
则会按照正常的顺序给出显示
比如上面的第一个数据20010001
如果是字节显示,就会是01 00 01 20
关于STM32的内存情况,可结合下文深入学习:
系统视窗——System Viewer Windows
可以在"Peripherals"选项栏中选择"System Viewer"系统视窗中对应的外设,选择"Core Peripherals"则是内核调试窗口。另外系统视窗也可以通过工具栏打开。
这个根据不同芯片会有不同的展示。
这个窗口用于查看当前单片机外设及内核寄存器的值,在调试外设底层时经常会使用到。
以GPIOA为例:
在这个窗口中可以直接修改外设寄存器的值,当然部分只读寄存器是无法修改的,有些则是需要在特定条件下才可以设置生效,具体就得看对应的芯片手册里寄存器的说明了。
再比如,想看获取的ADC的值,但是直接加入到窗口内,显示无法计算
所以就想到直接看寄存器
不得不说,是个好工具。
调度关系窗口——Call Stack Window
可以在"View->Call Stack Window"打开此窗口,也可以在工具栏中打开。
这个窗口用于查看当前程序调度关系,当出现有进入硬件错误异常调试时可以快速定位到是哪里触发的异常。这个窗口的调度关系是从当前程序堆栈里获取的数据并将其图形化,所以如果当前堆栈数据被破坏,则此窗口也将无法查看调度关系。
该窗口里显示的调度关系是从下至上调用的,最上面的表示当前程序所处的函数。展开对应的函数,可以查看各层调用函数跳转之前保存的一些临时变量等信息。
寄存器窗口——Register Window
该窗口可在"View->Registers Window"处打开,也可以在工具栏打开。
这个窗口用于查看当前内核的相关寄存器,如汇编里常说的15个通用寄存器。当然调试中比较常用的是其中的SP、LR、PC三个寄存器。SP为当前栈的地址位置,PC为当前程序地址,LR为函数跳转前的地址,即当前函数返回的地址。
另外"Banked"中的MSP为当前程序系统主栈,PSP则为操作系统的任务栈,这两者的区别是,如果使用了操作系统,则当前任务中的所有调度关系使用的是任务栈,而类似中断这种内核的操作使用的是主栈;如果未使用操作系统,则只会使用主栈,不会使用任务栈。
通过"Internal"可以查看当前是处在中断还是任务中,Mode为"Thread"表示是在线程/任务中,或者是函数中(非中断),为"Handle"表示是在中断中;Privilege为"Privelege"表示当前处于特权模式。Stack为"PSP"表示当前使用的是任务栈,为"MSP"则表示使用的是主栈。
更多内容可结合下文学习:
反汇编调试窗口——Disassembly Window
该窗口在"View->Disassembly Window"中可以打开,也可以在工具栏中打开。
该窗口是通过bin文件(即二进制文件)反汇编出来的汇编文件(汇编跟二进制原本就是一一对应的关系)。当设置了优化等级后,部分C语言的调试会变得困难(汇编跟C语言不是一一对应,而程序运行又是完全根据汇编来走的),此时可能需要使用汇编窗口进行调试。
关于更多内容可结合下文学习:
上面截图中的反汇编代码都是啥意思呢?
默认是以混合的形式来显示的,红色的字是对应C语言的行号和语句,可在界面中右键选择只显示汇编语言;
汇编代码中,第一列是指令地址,第二列是指令对应的机器码,再后面就是C语句对应的汇编指令。
函数地址表——Symbols Window
该窗口在"View->Symbols Window"中打开,也可能在工具栏打开。
可以查看当前所有程序的函数调用关系及其所在地址。
其他窗口
命令窗口——Command Window
该窗口在"View->Command Window"中可以打开,也可能在工具栏中打开。
这个窗口可用来输入一些控制命令。
串口调试窗口——Serial Windows
该窗口在"View->Serial Windows"中打开,也可以在工具栏打开。
暂略。
逻辑分析窗口——Analysis Windows
这个貌似只能在软件模拟仿真中使用。
跟踪窗口——Trace Windows
暂略。
更多总结
直接参考:
注意事项
犯了个低级错误,就是修改了程序,还没编译呢,就打断点准备调试。
程序调试期间不支持编译程序,如果想要修改程序并使其生效,需要退出调试模式。
底层驱动调试时如果没什么好的办法,可以尝试在keil里看寄存器的值。
高级调试技法
1
指定断点的执行次数
Keil调试时设置断点的高级用法_keil 断点调试-CSDN博客
2
逻辑分析仪
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)