| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> Keil 调试汇总 -> 正文阅读 |
|
[嵌入式]Keil 调试汇总 |
ARM- MDK 调试汇总
特别注意:本文档可能并不完善,欢迎各位进行补充。 👇相关代码、资料、本文档源文件已放入GitHub。需要修改的可以,自行下载源文件。 ?? 目录文章目录?? 前言接下来的调试介绍大概分成以下几个部分:
测试环境
1?? 基础调试本节的介绍都是比较基础的,写给22级或是一些刚接触MDK的; 你们会了的自己跳到后面部分去 👇 👇 1.1 keil5 进入调试1.1.1 选择调试器点击魔术棒 -> Debug ? 这里我是用的J-Link所以选J-Link 1.1.2 配置调试器点击setting进入调速器的设置界面 大致介绍一下SW 和 JTAG的区别:
1.1.3 配置flash点击flash Download 1.1.4 进入debug1.2 调试窗口介绍初始化后的默认调试窗口布局如下: 1??调试操作栏
2??主界面窗口设置 [命令行|反汇编窗口|符号窗口|内核寄存器|回调栈及局部变量|变量显示|内存窗口|虚拟串口|系统分析窗口|TRACE窗口|外设寄存器]
3??在线调试启动/关闭 4??断点设置 设置、取消、关闭、删除所有断点等操作。 7?? C/C++代码窗口 🔟 用于查看单片机中某个变量的值,一般多用于查看全局变量以及外设寄存器数值、表达式显示变量,也可直接操作变量值。 (相当于直接改变内存) (👇更多的可以参考一下这篇文章) 1.3 基本调试操作1.3.1 全速运行、打断点、查看变量
1.3.2 复位、停止程序
1.3.3 单行/单步运行
2?? 具体调试
2.1 寄存器直接操作2.1.1 中断控制器嵌套向量中断控制器 (NVIC) 对话框(适用于 Cortex-M3、Cortex-M4 和 Cortex-M7 内核)显示所有异常的状态。对于每个异常,对话框都会显示编号、来源、名称、状态和优先级。 2.1.1.1 官方文档官方文档指出我们可以选定指定中断,并控制改变异常的状态 (👇感兴趣的可以看一下官方文档) 2.1.1.3 中断控制器介绍你的中断设置的优先级是多少,是否开启了,是否挂起了,是否处于活动状态,在这里一目了然。 假如你想要让程序尽快进入中断程序运行,只要勾选挂起选项,这样程序运行后马上就能到中断处理函数中执行了。 当然这里只是简单介绍,具体内容可以自己去看文档 (👇感兴趣的可以看一下官方文档) 2.1.1.2 开启方法
2.1.2 外设寄存器查看2.1.2.1 开启方法在 2.1.2.2 外设寄存器查看图中示例了串口1的寄存器查看,同样的中断设置/时钟分频/定时器均可通过此查看。甚至可以通过数据的变动与否判断外设是否正常打开。 2.1.2.3 直接修改寄存器值可通过在外设寄存器窗口,直接修改寄存器的值,以控制寄存器 视频中,可以看到,通过控制TIM8的CCR寄存器,来改变PWM的占空比。 2.1.2.4 输出IO控制
可以通过控制GPIO的ODR寄存器
2.1.2.5 输入IO检测当某个单片机IO口设置为输入时,可直接通过输入寄存器查看电平状态即使代码处于断点停止状态也可以查看(断点停止有时需要手动点击toolbox中的更新窗口按钮),在项目中可用来检测外部开关信号等省去了万用表测电压。
2.1.2.6 直接控制串口输出通过直接修改串口的数据寄存器来进行操作 类似直接通过寄存器来进行调试还有很多示例,这里仅演示其中几种,有其他比较有用的也欢迎补充。 2.2 测量某段代码运行时间方法比较多, 如利用系统内核计算(dwt)、利用其它工具如Systemview 、利用断点等 2.2.1 利用内核计数(dwt)原理如:
运行结果可以看到基本能实现US级的 测量 2.2.2 利用断点时间测量该方法也是基于基于内核时钟,进行计数测量的,经过笔者的测试,在大部分情况下,精度都是非常高的 2.2.2.1 前置步骤要用到断点,也即是keil本身来获取准确时间,需要先进行Trace功能的配置 (👇具体配置见下文) 2.2.2.2 测量前置
为什么要打开寄存器窗口: 有的时候,右下角时间窗口 2.2.2.3 测试原理在寄存器窗口显示的时间是从单片机运行的第一条代码 开始的时间,这个时间是累计的。 而右下角时间窗口 可以重置(Reset)时间,比如现在用t1显示的时间(t0 和 寄存器窗口显示的时间一样,不信你可以看看),只要先重置一下这个t1(最上面那个),然后运行代码后暂停,t1显示的就是这段代码的运行时间了。 2.2.2.4 实际操作2.2.2.4.1 关闭固定窗口刷新(代码运行同时刷新变量窗口数据,会影响测量时间的准确性)
2.2.2.4.2 进行测量设置断点后,开启代码运行,下一次测量时应复位测量计时器T1/T2. 2.2.2.4.3 测量结果可以看到测量结果和之前用DWT进行测量基本是一致的 2.3 高级断点调试2.3.1 简介Keil5软件帮助文档中指明了断点有三种类型:存取断点,执行断点,条件断点。
? 图为官方文档介绍 2.3.2 开启方法
2.3.3 窗口介绍
图中官方示例的各断点的定义的意义: 注意:
2.3.4 断点操作2.3.4.1 存取断点2.3.4.1.1 存取断点定义可以在Watch中右键添加断点。 如果想知道某个变量在什么地方被访问,假定有一个变量a,可以按以下进行配置: 因为 Count 值设置为 1,所以每一次读取a的值,程序都会停止。 2.3.4.1.2 运行结果在对变量a 进行读取的时候,程序自动停止运行
如果是写操作(Write)访问时,会发现从复位程序开始运行后,程序会停止在某个地方。 因为全局变量会在进入 main 函数之前被初始化。 还可以更改 2.3.4.2 结构体断点实际结构体断点也是属于存取断点的一种,因为要写的比较多,单独列出来 注意:这部分我测试的时候感觉有点问题,没完全解决 2.3.4.2.1 设置结构断点1?? 出现的问题 试了一下,直接在
? 试着解决了一下 ,没解决 2?? 简单的解决方法 可以采用更加通用的方法: 可以看到结构体变量各个成员的地址是不同的,比如我们 个来看出一个结构体变量的地址是多少),所以设置后的结果如下:
注意:经测试好像是不支持指针操作,不太确定 比如有这样三个结构体:
如果要调用pitch轴的电机数据:
会导致报错: 2.3.4.3 条件断点有些时候,我们并不关注地址访问情况,而对变量的数据内容感兴趣,比如变量 运行结果:
2.3.4.4 添加命令可以在命令行增加命令,例如,程序运行100次后,将flag置1,以达到控制程序运行的目的
通过Command命令还能做到很多事情,比如打印信息什么的 例如:写入变量a 50次后打印信息: (👇详见下文) 2.4 watch变量查2.4.1 常规操作右键添加到变量观察窗口,或者直接选中后拖拉变量到窗口。 观察的对象比较广泛: 全局/局部变量、寄存器、函数地址、数组结构体等,对于局部变量只能在变量的有效局部内才能显示具体数值。 2.4.2 表达式操作表达式可进行简单的数学运算,甚至可以当做一个简单的进制转换、计算器来使用。如下所示,动态显示random的值减去70000,0xf777转换为十进制。
在这里插入图片描述 2.4.3 直接修改变量的值可以直接在变量窗口修改变量的值,相当于直接在修改内存。 在调pid的时候比较有用, 直接修改,不用退出编译。 (当然这只是临时的,不重新编译的话,下次进入debug还会是原来的值) 2.5 (Call Stack + Locals)回调栈局部变量窗口2.5.1 常规用法打断点后,通过回调栈窗口可以看到当前函数的调用情况以及内部变量的值。 当程序封装太多层时可参照如下方式进行一层一层跳转分析。 2.5.2 查看进入Hardfault函数的位置当存在Hardfault等错误以及程序死循环时,可以通过断点或停止按钮停止程序运行,在回调栈窗口查看调用 hardfault的位置,位置不是很准确,但是能反应大概位置,然后通过局部变量的值进行判断异常位置。下边演示 了数组越界引起了异常,大概定位到了前后的位置,其它的错误定位可以再研究一下。
2.6 Command 窗口操作
keil的命令调试功能很强大,用的好能解决很多问题 比如,通过执行命令函数或表达式直接实现查看与修改变量、对象、寄存器及内存。 (👇详见官方文档) 这里贴几张官方文档的图: 2.6.1 断点命令2.6.2 一般命令在这里插入图片描述 2.6.3 内存命令和程序命令2.6.4 使用示例注意:当退出调试模式之后,KEIL 将自动保存 Command 数据到文件中(也就是说在此之前你是看不到这些调试数据的) 2.6.5 自定义TOOLBOX按键有些时候我们并不满足监控数据,还想定义一些自己的按键,比如当我按下按钮时,系统电源关闭,再按下按钮时系统电源开启等。 这个功能其实使用前面所说的外设窗口 也是完成能完成要求的,麻烦的是,如果使用外设窗口,要控制 IO 口,那你每次都得找到对应的 IO 口才行,很是麻烦,但是使用按键就会简单许多。 2.6.5.1 定义按键2.6.5.1.1 可以通过建立ini文件(👇ini文件详见)
保存后导入 之后进入 Debug 模式即可,在这里你可以看到你定义的按键: 2.6.5.1.2 通过命令窗口之前说过**.ini 文件**和手工在 Command 窗口输入命令没啥区别,只是使用文件的话可以将常用命令保存下来。 所以直接在命令窗口写入命令也行 2.6.5.1.3 按键删除
2.6.5.1.4 运行结果 可以看到通过自定义按键 控制io口输出,控制灯的亮灭。 注意:命令调试也存在缺点
调试器可以说是第三方监视器,虽然几乎没有侵入性(事实上对 CPU 还是有影响的),但是它还是会窃取 CPU 时钟的,而且在执行断点的时候,虽然由 ini 文件定义的函数由 KEIL 执行了,实际上上执行这些函数也是需要时间的,那这个时间怎么来,就是通过暂停 CPU 后去执行这些代码,这个你可以通过 DWT 计数器看出来,因为只有 CPU 执行了 DWT 才会计数,但是你会发现在执行这些代码时,DWT 是没有进行计数的(在 KEIL 函数的前后获取 DWT 计数,可以发现计数值不变) 也就是说 CPU 和 KEI 是在交替使用系统时钟的。平常来看,由于 KEIL 执行速度很快,看不出来问题,但到中断的时候却会出现问题。 3?? ITM程序跟踪
3.1 ITM简介**ITM:**Instrumentation Trace Macrocell,指令跟踪宏单元 ITM是一应用驱动的跟踪源,它支持printf类的调试手段来跟踪操作系统(OS)和应用事件,并发布判定的系统信息。ITM以包的形式发布跟踪信息,它由以下部分组成: 使用ITM能做到,在keil上显示各个中断的运行时间,进入时间;打印变量波形;打印虚拟串口数据等; 简单添加几张效果图: 1??中断时间戳: 2?? 打印变量波形: 3?? 打印虚拟串口: 3.2 Trace配置
3.2.1 硬件准备3.2.1.1 仿真器准备一个J-Link仿真器或是ST-LINK、有J-Trace更好,直接一步到位。 不管是什么仿真器,只要能引出VCC、GND、TMS/SWDIO、TCK/SWCLK、JTDO这5根线的话就可以尝试一下。
这里我用的是J-Link: 通过平常的SWD四线接口,再加上一根SWO的飞线 3.2.1.2 开发板准备准备一个有引出**PB3**引脚的板子 ? 图为数据手册 我看了周围我能用的板子汇总如下: 1??
2??
最终我是选择了用F4的板子,飞线进行测试,之后可以让硬件在设计的时候就引出来PB3 3??
4??
3.2.2 软件配置3.2.2.1 CUBEMX配置选择异步跟踪模式,此时PB3将会自动定义为SWO端口。 3.2.2.2 KEIL软件设置在debug 的Trace窗口进行配置: 确保用的是SW模式 : 3.3 keil调试的ini文件用法
通过ini文件,可以动态的分析调试,也可以还原bug发生的情景。 (感觉很有用,但我自己只是简单测试,就不乱说了,后面附上文章自己看) 3.3.1 ini 文件使用ini文件可解释为一个配置文件,相当于一个**.C文件**,这个文件的执行本质与仿真时的命令行执行一致(如果觉得不麻烦可以在命令行中敲所有的命令而不用加载ini文件). ini文件的加载主要在两个地方: 1?? 点击调试时会加载图片所示的ini文件: 2?? 调试时使用专用管理器调用 调用ini主要用来生成一些配置,如打开itm端口、生成log、设置断点等功能,下边介绍一下小功能。 3.3.2 新建按钮使用任何编辑器新建后缀为.ini的文件,内容如下:
这样即可实现按钮的多个定义。 3.3.3 功能函数命令行不能直接调用函数,与之前讲过的一样,这里的功能函数仅用来调试使用,可以定义一些打印输出,修改变量、外设寄存器值等操作。 使用任何编辑器新建后缀为.ini的文件,内容如下:
以上内容为定义了两个函数清除变量clearValue和打开LED灯LEDON,然后将两个函数做成toolbox按钮。 3.3.4 不复位在线调试3.3.4.1 使用SWD4线连接目标板(Jtag接口会产生复位)3.3.4.2 外部工程目录下创建一个noresetDBG.ini配置文件,内容为:
没有这个也可以不复位调试,但打不了断点 3.3.4.3 取消勾选
|
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/28 17:24:08- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |