一、概述
二、软件说明
????Keil提供了包括C编译器、宏汇编、链接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(μVision)将这些部分组合在一起。
????目前软件对中文的支持不友好,不建议安装 上的一些汉化包之类的。另外建立的工程文件路径也尽量不要存在中文,否则可能会出现一些异常。
演示版本:5.24a
三、软件使用
3.1 基本调试操作
????首先点击”Debug->Start/Stop Debug Session”或下图2位置,进入调试。
????复位(Reset):对程序进行复位操作,根据烧录器不同的复位方式配置会触发不同的复位类型。
????单步跳过调试(Step Over):如果是在C语言窗口中,则是按单条语句执行,与单步调试不同的是,遇到函数不会进入函数内部,而是直接全速运行函数,并跳到下一条语句。
????插入/移除断点:如果当前光标所在行未有断点,则插入断点(前提是当前行可以插入,如果无法插入会显示一个感叹 ),在有断点的情况下则是移除断点。插入断点后,当前行前面会有个红圆表示断点位置。也可以通过直接点击红圆位置进行插入/移除断点的操作。另一种断点方式,是通过指令来控制,当然也可以使用Keil提供的界面化操作,设置某个变量读或写时触发断点。不过目前貌似有部分芯片不支持这种操作。注:断点最多只能打7个。
????禁止所有断点:禁止当前所有的断点。
3.1 调试窗口
- 变量查看窗口——Watch1,Watch2
????通过”View->Watch Windows->Watch1、Watch2″可以选择打开Watch窗口,也可以在工具栏
????通过选中一个变量,右键添加入对应的Watch窗口,可以追踪查看当前变量的变化状态。注意,只有全局变量可以全程监视,临时变量只有在进入当前函数中才可监视到其数据,用static关键词修饰的变量无法监视。
- 寄存器窗口——Register Window
????该窗口可在”View->Registers Window”处打开,也可以在工具栏
四、调试应用
- HardFault(硬件错误)
还有一种是操作指针本身的地址没有4字节对齐,也会出现问题。如下代码:
- 复位
????复位有几种类型,一是看门狗复位,二是软件复位,三是硬件复位。复位类型可以通过芯片自带的复位寄存器进行查看。不过查看前需要手动清除所有复位标志,不然其复位标志会一直保留着。
????先讲下看门狗复位,当单片机开启看门狗后,很多问题都会变成复位问题,比如上面说的HardFault,因为HardFault也是一个中断,只是默认中断里是一个While(1)的死循环,所以当进入中断后,一段时间没有喂狗操作,就会触发复位。或者一些操作陷入死循环的,均是同理。这里我们把这一类问题都归为死循环问题。处理方式,先把看门狗关掉,然后调试看停在哪个死循环中,如果是HardFault,那就看上面硬件错误的处理方式。如果是其他死循环,那就看是什么条件触发的。死循环的问题相对来说比较好找。
????另外一种比较难处理的看门狗复位问题,莫过于某些操作时间过长,导致喂狗不及时。比如读写Flash时,通常会关闭中断,当大量读写时,其操作时间不可小靓,未开看门狗的情况下会有肉眼可见的程序卡顿,开了看门狗的情况下则通常会触发程序复位。这种类型的问题,通过关闭看门狗可能也无法定位到具体位置,因为程序还可以正常执行,只是在某些程序段会变得比较卡顿。对于这种问题,最好的方式是通过代码对比,通过对比原本没出问题的代码和出问题代码的差异性,锁定问题大体出现的位置,再通过程序执行时间进行估算。也可以借助一个独立的定时器,在一些时间操作较长的可疑之处计时。比如程序调用了某个底层未开源函数,那可以在调用前后打印定时器的计数,来计算函数运行的时间。当然也可以通过Keil自带的调试计数值来计算运行时间。
????软件复位就比较好找了,一般是需要人为调试内核的复位接口进行复位,所以只要查看是哪些位置触发的调用复位函数的条件就可以锁定问题点。
????硬件复位就只能从外围电路进行切入了,考虑干扰、连锡等问题。当然有些硬件复位是通过一个硬件看门狗进行复位的,如果是这种应用,那参考内部看门狗的问题排查方式。
- 逻辑时序类调试
????时序类的用断点调试法就很难做到了,特别是那种时序要求很严格的。就比如Modbus通信,协议是规定了一帧数据中每两个字节间隔时间不能超过1.5字符。所以想要在一帧数据中,按一个字节一个字节断点调试从机是不可能的,主机不会给你休息的时间。这时候就必须得添加一些测试代码了,添加测试代码最重要的一个原则,是不能变更原本的功能。所以一般在数据流向的关键路径上添加一些监控变量,通过监控变量的变化来识别时序是否出现错误。
????另外也可以使用逻辑分析窗口,把对应的变量添加进窗口中,通过时间变化查看变量对应的变化关系,以此来判断逻辑时序是否正常。
- 内存调试
????如果有涉及boot或日志记录功能的编写,那肯定会涉及大量内存的对比及调试,这时候可以利用上面提到的小技巧,在命令窗口那里输入save filename.hex StartAddr, EndAddr把对应的内存数据打印出来。
- 底层外设调试
????这个打开对应外设的寄存器界面,对着芯片用户手册查看每个寄存器的功能进行调试,只有对寄存器功能熟悉了才有对应的调试手段。
五、注意事项
1、有时候在watch窗口中,变量值不会刷新,这时候就需要查看一下”View->Periodic Window Update”是否已勾选,如果没勾选,变量只有在第一次添加或停止调试时才会刷新。另外当窗口里一次性加载了一个很大的数组,当展开数组时,变量刷新也会变得很慢,并且软件会变卡顿。
2、当选择了非0级优化时,调试可能会变得困难,具体表现在断点调试。比如现在下面的代码,代码优化的关系,有可能把case0、1、2里的return 1都合并成一行,导致运行调试时,无论当前程序进入了哪个分支,使用断点时都只会进其中一个。所以当开启代码优化等级后,需要注意断点调试将变得不可信。另外优化编译后,有部分代码也将无法打断点(被优化的代码)。
此时应该去看汇编的实现,其执行顺序与汇编一致。
3、目前发现有部分工程在一些电脑上调试时,打断点后在删除断点之前退出调试,会导致Keil崩溃,只能结束进程重启。
4、当开启内部看门狗并且未打开调试关看门狗功能时,停止运行一段时间后会复位。
5、在全速运行时,有时打断点会无效,取消断点也无效,貌似是Keil本身的问题。
六、相关知识
????Keil5软件使用-基础使用篇、Keil5软件使用-进阶工程配置篇、Keil软件包-知识宝藏库
文章知识点与官方知识档案匹配,可进一步学习相关知识C技能树进阶任务C语言问答115969 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!