Keil常用的调试操作
一、软件调试使用1.1 基本调试操作 上文已经说过在线调试和模拟调试的配置过程,但无论是在线还是模拟调试,调试技巧工具的使用都是一样的。点击红色d,进入调试
https://i-blog.csdnimg.cn/blog_migrate/26f5348ae310e42c7e15cf501cd08e07.png
可以发现,多出了一个工具条,这就是 Debug 工具条,这个工具条在我们仿真的时候是非
常有用的,下面简单介绍一下 Debug 工具条相关按钮的功能。Debug 工具条部分按钮的功能如
图:
https://i-blog.csdnimg.cn/blog_migrate/0b04357acba526f3a90151cbca0e4222.png
复位(Reset):其功能等同于硬件上按复位按钮。相当于实现了一次硬复位。按下该按钮之后,代码会重新从头开始执行。
https://i-blog.csdnimg.cn/blog_migrate/5f2da685f831fadda05acf8ca682d63a.png
执行到断点处(Run):该按钮用来快速执行到断点处,有时候你并不需要观看每步是怎么执行的,而是想快速的执行到程序的某个地方看结果,这个按钮就可以实现这样的功能,前提是你在查
看的地方设置了断点。
https://i-blog.csdnimg.cn/blog_migrate/9e1cba87cf012fa5da779a8439662ea7.png
挂起(Stop):此按钮在程序一直执行的时候会变为有效,通过按该按钮,就可以使程序停止下来,进入到单步调试状态。
https://i-blog.csdnimg.cn/blog_migrate/7ab706c8831c672ec4d8632beba438ba.png
单步调试(Step):根据当前调试的窗口的语言,执行单条语句。如果遇到函数,则会进入函数内部。该按钮用来实现执行到某个函数里面去的功能,在没有函数的情况下,是等同于执行过去按钮的。
https://i-blog.csdnimg.cn/blog_migrate/505654f1add024df8636c1261b766a2d.png
单步跳过调试(Step Over):如果是在C语言窗口中,则是按单条语句执行,与单步调试不同的是,遇到函数不会进入函数内部,而是直接全速运行函数,并跳到下一条语句。在碰到有函数的地方,通过该按钮就可以单步执行过这个函数,而不进入这个函数单步执行。
https://i-blog.csdnimg.cn/blog_migrate/cf20286cc9947beb0a424fa9bef3445f.png
单步返回调试(Step Out):如果是在C语言窗口中,则是直接全速运行当前函数后面所有内容,直到函数返回上一级。该按钮是在进入了函数单步调试的时候,有时候你可能不必再执行该函数的剩余部分了,通过该按钮就直接一步执行完函数余下的部分,并跳出函数,回到函数被调用的置。
https://i-blog.csdnimg.cn/blog_migrate/57379d5dbd7270bce6db7faac4151b4c.png
执行到光标处(Step Run to Cursor Line):该按钮可以迅速的使程序运行到光标处,其实是挺像执行到断点处按钮功能,但是两者是有区别的,断点可以有多个,但是光标所在处只有一个。
https://i-blog.csdnimg.cn/blog_migrate/98a21510057fd26480560030f1fa1fb7.png
插入/移除断点:如果当前光标所在行未有断点,则插入断点(前提是当前行可以插入,如果无法插入会显示一个感叹号),在有断点的情况下则是移除断点。插入断点后,当前行前面会有个红圆表示断点位置。也可以通过直接点击红圆位置进行插入/移除断点的操作。另一种断点方式,是通过指令来控制,当然也可以使用Keil提供的界面化操作,设置某个变量读或写时触发断点。不过目前貌似有部分芯片不支持这种操作。注:断点最多只能打7个。
https://i-blog.csdnimg.cn/blog_migrate/dbfeab9f575c489ebe8f0f1604699505.png
使能/禁止断点:开启或禁止当前光标所在行的断点。禁止后红圆变成白圆。
https://i-blog.csdnimg.cn/blog_migrate/11a7be8c477155ecc9886e3725e6ea87.png
禁止所有断点:禁止当前所有的断点。
https://i-blog.csdnimg.cn/blog_migrate/9a7a4aacd5ab088fae3dc1294f7c5578.png
删除所有断点:删除所有断点。
https://i-blog.csdnimg.cn/blog_migrate/364727647a277c5296dc159f3df98cf0.png
1.2 调试窗口https://i-blog.csdnimg.cn/blog_migrate/38d6fdf8450cb9b4f508a4d8cc954bc9.png
汇编窗口:通过该按钮,就可以查看汇编代码,这对分析程序很有用。
观看变量/堆栈局部变量窗口:该按钮按下,会弹出一个显示变量的窗口,在里面可以查看各种你想要看的变量值,也是很常用的一个调试窗口。
观察窗口:watch窗口,可以看到你想看的变量。
内存查看窗口:该按钮按下,会弹出一个内存查看窗口,可以在里面输入你要查看的内存
地址,然后观察这一片内存的变化情况。是很常用的一个调试窗口。
串口打印窗口:该按钮按下,会弹出一个类似串口调试助手界面的窗口,用来显示从串口
打印出来的内容。
逻辑分析窗口:按下该按钮会弹出一个逻辑分析窗口,通过 SETUP 按钮新建一些 IO 口,
就可以观察这些 IO 口的电平变化情况,以多种形式显示出来,比较直观。
系统查看窗口:这个窗口用于查看当前单片机外设及内核寄存器的值,在调试外设底层时经常会使用到。
[*]变量查看窗口——watch1,watch2
https://i-blog.csdnimg.cn/blog_migrate/b9ac2e1dd29fe4b1d7168a6ea554c604.png
通过"View->Watch Windows->Watch1、Watch2"可以选择打开Watch窗口,也可以在工具栏
这里打开。再点击一次则可以关闭。
通过选中一个变量(一定要选中变量,而不是光变放在变量那里),右键添加入对应的Watch窗口,可以追踪查看当前变量的变化状态。注意,只有全局变量可以全程监视,临时变量只有在进入当前函数中才可监视到其数据,用static关键词修饰的变量无法监视。
如果当前变量没有实时更新,则需要点击"View->Periodic Window Update"将其勾选上。
https://i-blog.csdnimg.cn/blog_migrate/d805f03e82e00500d3fc79e91aaf070c.png
在 "Watch" 窗口中,可以查看当前变量名称、值、数据类型,如果当前变量类型为结构体,则可以以对应的结构形式进行展开查看。
https://i-blog.csdnimg.cn/blog_migrate/30e1f44ebaf4d6910c5f14679fd52a62.png
[*]内存查看窗口——Memory
https://i-blog.csdnimg.cn/blog_migrate/bcea0ad5dd08724f7562daf8ef654995.png
通过"View->Memory Windows->Memory1/2/3/4"打开Memory窗口,也可以通过工具栏这个图标打开。打开的状态下再按一次则可关闭。
在Memory窗口中输入想要查看内存的起始地址里的数据,另外右上角的锁可以把当前界面锁定下来。
https://i-blog.csdnimg.cn/blog_migrate/fcbe08eba30e80cc5c90177fcc022793.png
另外如果查看的是Ram的地址,那其中的数据也可以直接通过此窗口进行修改。
https://i-blog.csdnimg.cn/blog_migrate/a906cc79e1f1d576e4037feb9b51972f.png
[*] 系统视窗——System Viewer Windows(这个根据不同芯片会有不同的展示)
https://i-blog.csdnimg.cn/blog_migrate/a44d65ef53c35f7f2bf6de873b0edc45.png
可以在"Peripherals"选项栏中选择"System Viewer"系统视窗中对应的外设,选择"Core Peripherals"则是内核调试窗口。另外系统视窗也可以通过工具栏中,这个位置打开。
这个窗口用于查看当前单片机外设及内核寄存器的值,在调试外设底层时经常会使用到。
在这个窗口中可以直接修改外设寄存器的值,当然部分只读寄存器是无法修改的,有些则是需要在特定条件下才可以设置生效,具体就得看对应的芯片手册里寄存器的说明了。
但我的Keil软件中无法显示这个视图,并且通过修改系统试图,调试时,点击打开系统视图发生了闪退的现象,目前能想到的原因是:重新安装Keil,安装最新版本。
https://i-blog.csdnimg.cn/blog_migrate/b1a0b9fa1398f762ec5271f173096a0e.png
若Keil软件的System Viewer中没有,可以在这里点击 Use Custom File,添加SRF后缀的文件,这个文件在芯片包里。添加后,确实有了系统视图,但会出现闪退的现象。
https://i-blog.csdnimg.cn/blog_migrate/5e74b43ace7f3bfafd56ae27e5ed5d50.png
[*]调度关系窗口——Call Stack Window
[*]寄存器窗口——Register Window
[*]反汇编调试窗口——Disassembly Window
[*]命令窗口——Command Window
[*]函数地址表——Symbols Window
[*]跟踪窗口——Trace Windows
[*]以上不常用的窗口介绍,详情:不常用调试窗口介绍
[*]串口调试窗口——Serial Windows
https://i-blog.csdnimg.cn/blog_migrate/634170eda1c223b2cc8ea9abc4f7191a.png
该窗口在"View->Serial Windows"中打开,也可以在工具栏这个位置打开。
https://i-blog.csdnimg.cn/blog_migrate/1ea521d4d79fa0a754995148dd58bb64.png
[*] 逻辑分析窗口——Analysis Windows
https://i-blog.csdnimg.cn/blog_migrate/1015668f17be8fc1cb519ad6ca94485d.png
该窗口在"View->Analysis Windows"中打开,也可以在工具栏这个位置打开。
https://i-blog.csdnimg.cn/blog_migrate/aca5e0913a4ae880d19e8ab3e2280325.png
二、注意事项1、有时候在watch窗口中,变量值不会刷新,这时候就需要查看一下"View->Periodic Window Update"是否已勾选,如果没勾选,变量只有在第一次添加或停止调试时才会刷新。另外当窗口里一次性加载了一个很大的数组,当展开数组时,变量刷新也会变得很慢,并且软件会变卡顿。
2、当选择了非0级优化时,调试可能会变得困难,具体表现在断点调试。比如现在下面的代码,代码优化的关系,有可能把case0、1、2里的return 1都合并成一行,导致运行调试时,无论当前程序进入了哪个分支,使用断点时都只会进其中一个。所以当开启代码优化等级后,需要注意断点调试将变得不可信。另外优化编译后,有部分代码也将无法打断点(被优化的代码)。
switch (xx){ case 0: { do_something0(); return 1; } case 1: { do_something1(); return 1; } case 2: { do_something2(); return 1; } default: { return 0; }}此时应该去看汇编的实现,其执行顺序与汇编一致。
3、目前发现有部分工程在一些电脑上调试时,打断点后在删除断点之前退出调试,会导致Keil崩溃,只能结束进程重启,可能是你的工程中有中文名字。
4、当开启内部看门狗并且未打开调试关看门狗功能时,停止运行一段时间后会复位。
5、在全速运行时,有时打断点会无效,取消断点也无效,貌似是Keil本身的问题。
不错不错,keil要是把调试工具插件都用明白了也不容易
页:
[1]