Keil5软件使用 您所在的位置:网站首页 72240怎样调试 Keil5软件使用

Keil5软件使用

2024-06-29 17:22| 来源: 网络整理| 查看: 265

一、概述

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

二、软件说明

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

三、软件使用 3.1 基本调试操作

    首先点击"Debug->Start/Stop Debug Session"或下图2位置,进入调试。 在这里插入图片描述     如果前面工程配置里选择了复位调试,则进入调试后,会停在main函数头部 在这里插入图片描述

    复位(Reset):对程序进行复位操作,根据烧录器不同的复位方式配置会触发不同的复位类型。 在这里插入图片描述

    全速运行(Run):使当前程序开始正常全速运行,直到程序遇到断点时停止。 在这里插入图片描述     停止运行(Stop):当程序全速运行时,点击此按键可停止程序运行,停的是当前点击时的程序运行位置。 在这里插入图片描述

    单步调试(Step):根据当前调试的窗口的语言,执行单条语句。如果遇到函数,则会进入函数内部。如果是在反汇编窗口中,则只执行一条汇编指令。 在这里插入图片描述

    单步跳过调试(Step Over):如果是在C语言窗口中,则是按单条语句执行,与单步调试不同的是,遇到函数不会进入函数内部,而是直接全速运行函数,并跳到下一条语句。 在这里插入图片描述

    单步返回调试(Step Out):如果是在C语言窗口中,则是直接全速运行当前函数后面所有内容,直到函数返回上一级。 在这里插入图片描述

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

    使能/禁止断点:开启或禁止当前光标所在行的断点。禁止后红圆变成白圆。 在这里插入图片描述

    禁止所有断点:禁止当前所有的断点。 在这里插入图片描述

    删除所有断点:删除所有断点。 在这里插入图片描述

3.1 调试窗口 变量查看窗口——Watch1,Watch2

    通过"View->Watch Windows->Watch1、Watch2"可以选择打开Watch窗口,也可以在工具栏在这里插入图片描述这里打开。再点击一次则可以关闭。

在这里插入图片描述

    通过选中一个变量,右键添加入对应的Watch窗口,可以追踪查看当前变量的变化状态。注意,只有全局变量可以全程监视,临时变量只有在进入当前函数中才可监视到其数据,用static关键词修饰的变量无法监视。 在这里插入图片描述

    如果当前变量没有实时更新,则需要点击"View->Periodic Window Update"将其勾选上。 在这里插入图片描述     在"Watch"窗口中,可以查看当前变量名称、值、数据类型,如果当前变量类型为结构体,则可以以对应的结构形式进行展开查看。 在这里插入图片描述

内存查看窗口——Memory

    通过"View->Memory Windows->Memory1/2/3/4"打开Memory窗口,也可以通过工具栏Memory窗口 这个图标打开。打开的状态下再按一次则可关闭。

在这里插入图片描述     在Memory窗口中输入想要查看内存的起始地址,另外右上角的锁可以把当前界面锁定下来。 在这里插入图片描述     另外如果查看的是Ram的地址,那其中的数据也可以直接通过此窗口进行修改。 在这里插入图片描述

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

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

调度关系窗口——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语言不是一一对应,而程序运行又是完全根据汇编来走的),此时可能需要使用汇编窗口进行调试。

命令窗口——Command Window

    该窗口在"View->Command Window"中可以打开,也可能在工具栏在这里插入图片描述这个位置打开。 在这里插入图片描述     这个窗口可用来输入一些控制命令,比如保存输出当前内存地址等。在命令窗口中输入如下导出指令,按下回车即可导出数据

save filename startAddr,endAddr

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

例如:

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

函数地址表——Symbols Window

    该窗口在"View->Symbols Window"中打开,也可能在工具栏在这里插入图片描述这个位置打开。 在这里插入图片描述

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

串口调试窗口——Serial Windows

    该窗口在"View->Serial Windows"中打开,也可以在工具栏在这里插入图片描述这个位置打开。 在这里插入图片描述 暂未使用过,后续再添加。

逻辑分析窗口——Analysis Windows

    该窗口在"View->Analysis Windows"中打开,也可以在工具栏在这里插入图片描述这个位置打开。 在这里插入图片描述     这个貌似只能在软件模拟仿真中使用,如果使用硬件调试,需要硬件支持。

跟踪窗口——Trace Windows

    该窗口可以在"View->Trace Windows"中打开,也可以在工具栏在这里插入图片描述这个位置打开。 暂时未使用过,后续再添加。

四、调试应用 HardFault(硬件错误)

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



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有