【工具使用】Keil5软件使用-进阶调试篇

这篇具有很好参考价值的文章主要介绍了【工具使用】Keil5软件使用-进阶调试篇。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、概述

    本文面向已经懂得软件基本操作的职业老手,如果是未使用过该软件的小鲜肉,请移步基础篇。这里以STM32芯片为例对工具进行讲解,其他品牌的芯片在调试方面上可能存在差异。

二、软件说明

    Keil提供了包括C编译器、宏汇编、链接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(μVision)将这些部分组合在一起。
    目前软件对中文的支持不友好,不建议安装网上的一些汉化包之类的。另外建立的工程文件路径也尽量不要存在中文,否则可能会出现一些异常。
演示版本:5.24a

三、软件使用

3.1 基本调试操作

    首先点击"Debug->Start/Stop Debug Session"或下图2位置,进入调试。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
    如果前面工程配置里选择了复位调试,则进入调试后,会停在main函数头部
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

    复位(Reset):对程序进行复位操作,根据烧录器不同的复位方式配置会触发不同的复位类型。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

    全速运行(Run):使当前程序开始正常全速运行,直到程序遇到断点时停止。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
    停止运行(Stop):当程序全速运行时,点击此按键可停止程序运行,停的是当前点击时的程序运行位置。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

    单步调试(Step):根据当前调试的窗口的语言,执行单条语句。如果遇到函数,则会进入函数内部。如果是在反汇编窗口中,则只执行一条汇编指令。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

    单步跳过调试(Step Over):如果是在C语言窗口中,则是按单条语句执行,与单步调试不同的是,遇到函数不会进入函数内部,而是直接全速运行函数,并跳到下一条语句。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

    单步返回调试(Step Out):如果是在C语言窗口中,则是直接全速运行当前函数后面所有内容,直到函数返回上一级。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

    插入/移除断点:如果当前光标所在行未有断点,则插入断点(前提是当前行可以插入,如果无法插入会显示一个感叹号),在有断点的情况下则是移除断点。插入断点后,当前行前面会有个红圆表示断点位置。也可以通过直接点击红圆位置进行插入/移除断点的操作。另一种断点方式,是通过指令来控制,当然也可以使用Keil提供的界面化操作,设置某个变量读或写时触发断点。不过目前貌似有部分芯片不支持这种操作。注:断点最多只能打7个。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

    使能/禁止断点:开启或禁止当前光标所在行的断点。禁止后红圆变成白圆。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

    禁止所有断点:禁止当前所有的断点。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

    删除所有断点:删除所有断点。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

3.1 调试窗口

  • 变量查看窗口——Watch1,Watch2

    通过"View->Watch Windows->Watch1、Watch2"可以选择打开Watch窗口,也可以在工具栏keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言这里打开。再点击一次则可以关闭。

keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

    通过选中一个变量,右键添加入对应的Watch窗口,可以追踪查看当前变量的变化状态。注意,只有全局变量可以全程监视,临时变量只有在进入当前函数中才可监视到其数据,用static关键词修饰的变量无法监视。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

    如果当前变量没有实时更新,则需要点击"View->Periodic Window Update"将其勾选上。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
    在"Watch"窗口中,可以查看当前变量名称、值、数据类型,如果当前变量类型为结构体,则可以以对应的结构形式进行展开查看。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

  • 内存查看窗口——Memory

    通过"View->Memory Windows->Memory1/2/3/4"打开Memory窗口,也可以通过工具栏keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
这个图标打开。打开的状态下再按一次则可关闭。

keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
    在Memory窗口中输入想要查看内存的起始地址,另外右上角的锁可以把当前界面锁定下来。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
    另外如果查看的是Ram的地址,那其中的数据也可以直接通过此窗口进行修改。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

  • 系统视窗——System Viewer Windows(这个根据不同芯片会有不同的展示)

    可以在"Peripherals"选项栏中选择"System Viewer"系统视窗中对应的外设,选择"Core Peripherals"则是内核调试窗口。另外系统视窗也可以通过工具栏中keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言这个位置可以打开。
    这个窗口用于查看当前单片机外设及内核寄存器的值,在调试外设底层时经常会使用到。
    在这个窗口中可以直接修改外设寄存器的值,当然部分只读寄存器是无法修改的,有些则是需要在特定条件下才可以设置生效,具体就得看对应的芯片手册里寄存器的说明了。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

  • 调度关系窗口——Call Stack Window

    可以在"View->Call Stack Window"打开此窗口,也可以在工具栏keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言这个位置打开 。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
    这个窗口用于查看当前程序调度关系,当出现有进入硬件错误异常调试时可以快速定位到是哪里触发的异常。这个窗口是的调度关系是从当前程序堆栈里获取的数据并将其图形化,所以如果当前堆栈数据被破坏,则此窗口也将无法查看调度关系。
    该窗口里显示的调度关系是从下至上调用的,最上面的表示当前程序所处的函数。展开对应的函数,可以查看各层调用函数跳转之前保存的一些临时变量等信息。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

  • 寄存器窗口——Register Window

    该窗口可在"View->Registers Window"处打开,也可以在工具栏keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言这个位置打开。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
    这个窗口用于查看当前内核的相关寄存器,如汇编里常说的15个通用寄存器。当然调试中比较常用的是其中的SP、LR、PC三个寄存器。SP为当前栈的地址位置,PC为当前程序地址,LR为函数跳转前的地址,即当前函数返回的地址。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
    另外"Banked"中的MSP为当前程序系统主栈,PSP则为操作系统的任务栈,这两者的区别是,如果使用了操作系统,则当前任务中的所有调度关系使用的是任务栈,而类似中断这种内核的操作使用的是主栈;如果未使用操作系统,则只会使用主栈,不会使用任务栈。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
    通过"Internal"可以查看当前是处在中断还是任务中,Mode为"Thread"表示是在线程/任务中,或者是函数中(非中断),为"Handle"表示是在中断中;Privilege为"Privelege"表示当前处于特权模式。Stack为"PSP"表示当前使用的是任务栈,为"MSP"则表示使用的是主栈。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

  • 反汇编调试窗口——Disassembly Window

    该窗口在"View->Disassembly Window"中可以打开,也可以在工具栏中keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言这个位置打开。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
    该窗口是通过bin文件反汇编出来的汇编文件(汇编跟二进制原本就是一一对应的关系)。当设置了优化等级后,部分C语言的调试会变得困难(汇编跟C语言不是一一对应,而程序运行又是完全根据汇编来走的),此时可能需要使用汇编窗口进行调试。

  • 命令窗口——Command Window

    该窗口在"View->Command Window"中可以打开,也可能在工具栏keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言这个位置打开。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
    这个窗口可用来输入一些控制命令,比如保存输出当前内存地址等。在命令窗口中输入如下导出指令,按下回车即可导出数据

save filename startAddr,endAddr

filename:导出数据的文件名,无论后缀是什么,导出的格式都是十六进制文件。没有输入路径时,文件自动保存在当前工程根目录下。
startAddr, endAddr:需要导出数据的起始地址和结束地址,也可以通过表达式写出来。

例如:

save ExportData.hex 0x08000000, 0x08000000+0x2000

  • 函数地址表——Symbols Window

    该窗口在"View->Symbols Window"中打开,也可能在工具栏keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言这个位置打开。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言

    可以查看当前所有程序的函数调用关系及其所在地址。

  • 串口调试窗口——Serial Windows

    该窗口在"View->Serial Windows"中打开,也可以在工具栏keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言这个位置打开。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
暂未使用过,后续再添加。

  • 逻辑分析窗口——Analysis Windows

    该窗口在"View->Analysis Windows"中打开,也可以在工具栏keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言这个位置打开。
keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言
    这个貌似只能在软件模拟仿真中使用,如果使用硬件调试,需要硬件支持。

  • 跟踪窗口——Trace Windows

    该窗口可以在"View->Trace Windows"中打开,也可以在工具栏keil5 软件使用 进阶调试篇,工具使用,# Keil,单片机,stm32,c语言这个位置打开。
暂时未使用过,后续再添加。

四、调试应用

  • HardFault(硬件错误)

    这个可以算是最常见的一个问题了,在开发过程中多多少少会遇到过程序死机的问题,而死机的大部分原因都是进入的HardFault中断,即常说的硬件错误中断。要想知道这个怎么调试,首先得清楚这是什么,怎么触发。
    触发原因:内存溢出,堆栈溢出,数组越界,中断错误,除0(在某些编译器下会有错误)等。前面三个,可以归结为都是内存异常操作导致,但因为其出现方式不一样,所以调试方式也不同。
    从现象反推,当出现这个错误时,第一时间查看函数的调度关系,看最后是死在哪个位置。如果不是堆栈溢出,一般来说是可以直接查到进入硬件错误前的最后执行的代码位置的。当然内存溢出跟数组越界也有可能导致无法查看调度关系,因为这个调度关系就是从程序运行栈里取出数据进行展示,所以当栈数据被破坏,则无法使用此方式进行调试。
    知道死机位置后(其实大概率就是因为某个异常指针的引用导致的问题),此时就去查找异常指针出现的原因。首先从逻辑层面看,异常指针是否是因为某个逻辑给指针赋了个错误值。
    其次是数据越界的角度来看,在Map文件中查找该指针的内存地址,查看其内存前后是否存在一些数组或结构体,然后去检查前后数组或结构体的操作是否存在下标溢出,指针偏移错误等问题。
    还有最后一种,就是直接从内存里获取数据作为指针地址进行引用,此类用法一般是在日志操作或GUI中比较常用,这种情况就要去内存数据来源是否存在问题。
    除以上三种可能性外,还有一种可能对一些人是涉及知识盲区的,就是引用地址没有地址对齐。这一部分是涉及内核的一些知识。这里简单讲下,对于M0内核,指针引用地址需要根据其引用的数据类型进行对齐。比如以下代码:

int main(void)
{
	uint32_t *p = 0x20000001;
	*p = 20;	/* 这句一执行就会导致异常 */
}

还有一种是操作指针本身的地址没有4字节对齐,也会出现问题。如下代码:

/* 实际这样子定义编译器会报错(在Keil中编译),这里只是为了直观表示 */
uint32_t *p __attribute__((at(0x20000001)));
int main(void)
{
	p = 0x20000010;	/* 这句一执行就会导致异常 */
}
  • 复位

    复位有几种类型,一是看门狗复位,二是软件复位,三是硬件复位。复位类型可以通过芯片自带的复位寄存器进行查看。不过查看前需要手动清除所有复位标志,不然其复位标志会一直保留着。
    先讲下看门狗复位,当单片机开启看门狗后,很多问题都会变成复位问题,比如上面说的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都合并成一行,导致运行调试时,无论当前程序进入了哪个分支,使用断点时都只会进其中一个。所以当开启代码优化等级后,需要注意断点调试将变得不可信。另外优化编译后,有部分代码也将无法打断点(被优化的代码)。

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本身的问题。

六、相关知识

    Keil5软件使用-基础使用篇、Keil5软件使用-进阶工程配置篇、Keil软件包-知识宝藏库文章来源地址https://www.toymoban.com/news/detail-777853.html

到了这里,关于【工具使用】Keil5软件使用-进阶调试篇的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Keil5点击编译正常,烧录和调试直接闪退

    我在WIN11的环境下,安装了目前ST官网上最新的MDK538,刚刚下载好的前两天一切正常! 但是就在刚刚出现了Keil编译正常,使用正点原子的STLink烧录器下载却直接给我闪退,想查看 魔术棒中的DuBug中的烧录器配置Seting时候,也闪退。上网查看,采纳网友的意见“查看注册表”“

    2024年02月11日
    浏览(51)
  • keil5自带“串口模拟器“调试打印(stm32)

     打开软件调试 代码编写串口程序 开始编译 view菜单-serial Windows - uart1 # - 全速运行  

    2024年02月19日
    浏览(48)
  • Keil5,ARM编译器 软件优化注意事项

    循环是大多数程序中的常见结构。由于大量的执行时间通常花费在循环中,因此值得关注时间关键循环。 如果不谨慎地编写,环路终止条件可能会导致大量开销。在可能的情况下: 使用简单的终止条件。 写入倒计时到零循环。 使用  unsigned int  类型的计数器。 测试与零的

    2024年02月03日
    浏览(52)
  • Keil5软件安装方法(兼容stm32与c51方法)

    目录 一、下载软件包 二、安装软件 1、安装C51v960a.exe (1)右键以管理员权限运行程序  (2)开始安装软件  (3)勾选协议 (4)选择安装路径  (5)填写名字与邮箱  (6)等待安装 (7)安装完毕  (8)以管理员打开软件 (9)打开注册机 (10)破解成功 2、安装mdk528.exe

    2023年04月24日
    浏览(45)
  • keil5软件安装&开发环境搭建教程(mdk,c51通用)

    这是我在csdn上写的第一篇文章,心情激动兴奋。因为之前都是看别人写的博客,从来没想过自己去写一篇,在学长的鼓励下,尝试完成人生第一篇博客。仍有不足,希望大佬多多指正! 写这篇的目的是因为keil5的安装是许多人入门嵌入式的第一步,而且以后遇到许多不知名的

    2024年02月05日
    浏览(56)
  • STM32——01-开发软件Keil5及STM32CubeMX的安装

    1.1开发环境的安装  编程语言:C语言 需要安装的软件有两个:Keil5和STM32CubeMX 安装         安装包(不需要太新,以 MDK324 为例,最新的 MDK327 有问题)         安装过程一路下一步即可(建议不要安装在 C 盘)         安装路径一定不要有中文或空格!!(重要

    2024年02月08日
    浏览(49)
  • Keil5安装和使用小记

    随着keil版本的更新,一些使用问题一随之产生。本文针对安装目前最新版本keil软件和使用问题做一些总结。 官网下载链接 下载指引-----以下载C51为例 -1- 选择 Download -2- 选择 Product Download -3- 选择需要下载的产品 -4- 下方填写自己的个人信息,可以随便填,不需要什么验证码。

    2023年04月09日
    浏览(53)
  • keil MDK 5.38版本 在Debug配置使用STlink调试时,软件闪退

    参考: keil5.38 debug配置STlink调试,软件闪退 使用 ST-Link 调试器时 MDK uVision 崩溃 问题情况如下: 下载下来,覆盖原来的文件就好了 CSDN资源下载链接在此 网盘链接在此

    2024年02月16日
    浏览(61)
  • 2023最新版本~KEIL5使用C++开发STM32

    ▬▬▬▬▬▶用C++开发Keil◀▬▬▬▬▬ 因为是第一次写这个配置教程 我会尽量详细些 打开一个Keil工程 移除本地core 添加在线core 第一次编译代码 不会有报错 修改main.c文件类型为C++ 点击魔术棒 把ARM编译器修改为V6 第二次编译会报错语法不兼容 我把汇编部分的这些代码做了

    2024年02月12日
    浏览(51)
  • keil5使用c++编写stm32控制程序

    想着搞个新奇的玩意玩一玩来着,想用c++编写代码来控制stm32,结果在keil5中,把踩给我踩闷了,这里简单记录一下。注意一定要按照如下流程进行操作,一步都不要跟丢了。 所需要的一些文件放在百度网盘了。 先把最新的库函数和CMSIS安装好。 我这里为了方便就直接安装在

    2023年04月25日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包