打印
[其他ST产品]

STM32 使用 Keil MDK 中的软件逻辑分析仪参与硬件调试

[复制链接]
楼主: 大鹏2365
手机看帖
扫描二维码
随时随地手机跟帖
21
大鹏2365|  楼主 | 2022-3-31 20:32 | 只看该作者 回帖奖励 |倒序浏览
11) Call Stack + Locals 窗口
局部变量
Call Stack + Locals 窗口被合并在一个集成窗口中,每当程序停止时会显示调用栈和当前函数的所有局部变量。

如果可能,局部变量的值会显示,否则显示 < not in scope >。菜单中的 View/Call Stack Window 用来切换 Call Stack + Locals 窗口显示或隐藏。

运行并停止 Blinky,点击 Call Stack + Locals 选项卡。

展示了Call Stack + Locals 窗口。
Call Stack + Locals
窗口中显示了当前活动函数的名称和局部变量列表。随同每个函数的名字会显示它被哪个函数或中断/异常调用。
当函数退出时,会从列表上移除。
最早调用的函数会出现在列表的底端。
这个列表只有在程序停止运行时有效。

点击 Step In 图标 Step In 或按 F11 键。

当单步运行到不同的函数时,观察它们在窗口上显示的变化。如果陷入到 Delay 函数的循环当中,可以用 Step Out Step Out 或 Ctrl+F11 键快速退出。

点击几次 Step In,观察其他函数。

使用特权

评论回复
22
大鹏2365|  楼主 | 2022-3-31 20:33 | 只看该作者
右键点击一个函数名,尝试 Show Callee Code 和 Show Caller Code 选项。
Right Click Function Name

点击 Step Out 图标 Step Out 退出所有函数,返回 main()。

使用特权

评论回复
23
大鹏2365|  楼主 | 2022-3-31 20:34 | 只看该作者
提示: 如果单步调试(Step In)不工作,点击 Disassembly 窗口使它成为焦点,可能需要点击一行反汇编代码来执行汇编级别的单步运行。如果焦点在源代码窗口上,则是执行 C 语言代码级别的单步运行。

使用特权

评论回复
24
大鹏2365|  楼主 | 2022-3-31 20:35 | 只看该作者
提示: 可以在程序停止运行时,通过 Call Stack + Locals 窗口来修改变量的值。

使用特权

评论回复
25
大鹏2365|  楼主 | 2022-3-31 20:35 | 只看该作者
提示: 上述是标准的“Stop and Go”调试过程。ARM Coresight 调试技术还可以做很多更强大的事情,比如在程序运行中显示并实时更新全局或静态变量,而不需要修改程序。由于局部变量通常存储在 CPU 寄存器中,不能在程序运行时实时显示,需要转换成全局或静态变量使得作用域不会消失。

如果借助 ULINK pro 和 ETM 跟踪,可以记录所有指令的执行情况。Disassambly 和 Source 窗口是按编写的顺序显示代码的,而 ETM 跟踪可以按执行的顺序显示。另外 ETM 还提供 Code Coverage、Performance Analysis 及 Execution Profiling 等功能。

把局部变量转换成全局或静态变量通常意味着把它从 CPU 寄存器移动到 RAM 上,CoreSight 在程序运行中可以观察 RAM,但不能观察 CPU 寄存器。

使用特权

评论回复
26
大鹏2365|  楼主 | 2022-3-31 20:38 | 只看该作者
调用栈
如上面可以看到的,当程序停止运行时,函数按栈的方式显示在列表中。当想要了解栈中有哪些函数被调用、存储的返回值是什么的时候,这个功能就很有用。

提示: 可以在程序停止运行时,通修改局部变量的值。

提示: 点击菜单 Debug/Breakpoints 或按 Ctrl+B 键可以查看 Hardware Breakpoint 列表,同时这也是配置 Watchpoint (观察点,也叫 Access Point)的地方。在这个列表里可以临时屏蔽某些项目。点击 Debug/Kill All Breakpoints 会删除断点,但不会删除观察点。

使用特权

评论回复
27
大鹏2365|  楼主 | 2022-3-31 20:38 | 只看该作者
12) Watch 和 Memory 窗口及其使用方法
Watch 和 Memory 窗口实时显示变量的值,这是通过 ARM CoreSight 调试技术实现的,这项技术是包含在 Cortex-M 处理器中的一部分。同时,也可以在这些存储器地址上实时地“put”或插入数值。这两个窗口都可以通过拖拽变量名,或者手动输入来添加变量。

使用特权

评论回复
28
大鹏2365|  楼主 | 2022-3-31 20:39 | 只看该作者
Watch 窗口
添加全局变量: 除非程序停止在局部变量所在的函数,否则 Watch 和 Memory 窗口不能观察局部变量。

停止运行处理器 STOP 并退出 Debug 模式 Debug。


Blinky.c
的第24行左右,声明一个全局变量(这里变量名叫做
value
):
unsigned int value = 0;


在第104行左右添加语句
value++;

if (value > 0x10) value = 0;
,如图:
value Codes

选择菜单 File/Save All 或点击 Save All 。

点击 Rebuild Rebuild ,点击 Load Load 下载到 flash。

进入 Debug 模式 Debug ,点击 RUN RUN ,提示:可以在程序运行中设置 Watch 和 Memory 窗口。

在 Blinky.c 中,右键点击变量
value
并选择 Add value to … 及 Watch 1,Watch 1 窗口会打开并显示
value
如下图。

value
会实时增加到
0x10

Watch 1

使用特权

评论回复
29
大鹏2365|  楼主 | 2022-3-31 20:40 | 只看该作者
提示: 也可以框选
value
,单击并拖拽到 Watch 或 Memory 窗口。

使用特权

评论回复
30
大鹏2365|  楼主 | 2022-3-31 20:40 | 只看该作者
提示: 请确认菜单 View/Periodic Window Update 在选中状态。

也可以在 Name 下面区域双击或按 F2,再手动输入或复制粘贴变量名。或是打开菜单 View/Symbols Window 来输入变量。

使用特权

评论回复
31
大鹏2365|  楼主 | 2022-3-31 20:41 | 只看该作者
提示: 如果要拖拽到一个非活动的选项卡,选中变量按住鼠标并移动至希望打开的选项卡名字上,等待其打开并拖拽鼠标到窗口内释放。

使用特权

评论回复
32
大鹏2365|  楼主 | 2022-3-31 20:45 | 只看该作者
Memory 窗口
右键点击
value
并选择添加到 Memory 1,或手动添加
value
到 Memory 1。如果需要的话,选择菜单 View/Memory 来打开 Memory 1 窗口。

注意
value
被当作了一个指针,其值做为地址显示在了 Memory 1 上。这个操作在想要看一个指针指向的地址的时候很有用,但不是我们现在想看到的。

在变量名前面加一个“&”符号并按回车键,改为显示变量的物理地址(0x2000000C)。

右键点击 Memory 1 窗口并选择 Unsigned/Int。

value
的值现在以32位的形式显示了。

Watch 和 Memory 窗口都是实时更新的。

在 Memory 窗口中,鼠标移动到数据区域右键点击,选择 Modify Memory,可以修改对应地址的值。

使用特权

评论回复
33
大鹏2365|  楼主 | 2022-3-31 20:49 | 只看该作者
提示: 这些操作通常不会占用 CPU 周期。关于 DAP 是如何运行的,详见下一章“原理”。

使用特权

评论回复
34
大鹏2365|  楼主 | 2022-3-31 20:49 | 只看该作者
提示: 在 Debug 模式中选择菜单 View/Symbol Window,可以打开 Symbol 窗口查看变量和各自的位置。

上面展示的 Memory 和 Watch 窗口的操作并不需要配置 Serial Wire Viewer (SWV),这些机制使用的是 SWV 之外的另一个 CoreSight 特性。CoreSight Debug Access Port (DAP)通过 Serial Wire Debug (SWD)或 JTAG 连接来处理读写操作,从而实现实时在线的存储器访问。

使用特权

评论回复
35
大鹏2365|  楼主 | 2022-3-31 20:50 | 只看该作者
13) 如何在 Watch 和 Memory 窗口中观察局部变量
(译者注:由于板卡的区别,这一部分和原文略有不同。)

运行
Blinky.c
程序。我们将使用
main()
中的局部变量
num



Blinky.c
的第87行附近,
main
函数的开头,找到声明这个局部变量的地方。

右键点击这个变量,把它输入到 Watch 1 窗口中。注意由于局部变量的值可能存放在 CPU 寄存器内,μVision 不能在程序运行时访问,因此会显示 < not in scope >。如果 μVision 显示无法添加变量,请尝试停止再开始 Blinky 程序。
Watch Local Variables


Blinky.c
的主循环里添加一个断点,会使程序停止,这时会出现当前变量的值。

删除这个断点。

局部变量或自动变量可能存放在 CPU 寄存器内,μVision 不能在程序运行时访问。局部变量
num
只有在
main
函数运行时才会存在,在其他函数或中断/异常处理程序中是不存在的,因此 μVision 无法确定这个变量的值。

停止运行处理器 STOP 并退出 Debug 模式 Debug 。

使用特权

评论回复
36
大鹏2365|  楼主 | 2022-3-31 20:51 | 只看该作者
如何实时更新局部变量:

只需把
num
改为全局变量定义在
Blinky.c
中。


num
的声明移动到
main()
的外面、
Blinky.c
的最前面,把它改为全局变量:
unsigned int value = 0;
int32_t num = 0;
1
2

使用特权

评论回复
37
大鹏2365|  楼主 | 2022-3-31 20:52 | 只看该作者
提示: 也可以定义成静态变量,如:
static int32_t num = 0;

使用特权

评论回复
38
大鹏2365|  楼主 | 2022-3-31 20:54 | 只看该作者
提示: 在编辑模式和 Debug 模式都可以编辑文件,但编译只能在编辑模式进行。

点击 Rebuild 按钮编译源文件,确认没有 error 和 warning。

点击 Load 按钮 Load 下载到 flash,窗口的左下角会显示进度条。

进入 Debug Debug 模式并点击 RUN RUN 。

这时
num
变量已经可以实时更新了。

可以读(写)全局或静态的变量、结构体,以及其他以变量形式放在函数与函数之间的东西,包括外设的读写。(译者注:这一句我没翻好:You can read (and write) global, static variables and structures. Anything that stays around in a variable from function to function. This include reads and writes to peripherals.)

停止运行处理器 STOP 并退出 Debug 模式 Debug ,准备下一个练习。

提示: 菜单中的 View/Periodic Window Update 需要选中,否则变量只在程序停止时更新。

使用特权

评论回复
39
大鹏2365|  楼主 | 2022-3-31 20:55 | 只看该作者
原理
μVision 使用 ARM CoreSight 技术实现不窃取 CPU 周期的情况下对存储器位置进行读写。这种操作几乎是完全非侵入的,不影响程序本身运行时序。我们知道 Cortex-M4 是哈弗架构的,具有分离的指令总线和数据总线。当 CPU 以最大速度取指令时,CoreSight 调试模块有大量的时间读写数值,并不影响 CPU 周期。

有一种罕见情况,当 CPU 和 μVision 恰好同时读写相同的内存地址时,CPU 会暂停一个时钟周期,表现出轻微的侵入性。实际上可以认为这种窃取周期的情况不会发生。

使用特权

评论回复
40
大鹏2365|  楼主 | 2022-3-31 20:55 | 只看该作者
14) 使用 Logic Analyzer 图形化观察变量
这一章将在 Logic Analyzer 中显示全局变量的值。这个功能使用 Serial Wire Viewer,因此不会窃取 CPU 周期,用户代码中也不需要加入任何代码片段。

配置 Serial Wire Viewer (SWV):

停止运行处理器 STOP 并退出 Debug 模式 Debug 。

点击 Target Options Target Options 或者按 ALT+F7,并选择 Debug 选项卡,点击窗口右侧的 Settings,确认选择的是 SW 模式。ST-Link中,SWV 强制使用 SW 模式。

选择 Trace 选项卡,选择 Trace Enable,取消选择 Periodic 和 EXCTRC,设置 Core Clock 为 48 MHz。其他选项如图所示。

译者注:CPU 时钟频率很重要,请务必按照实际值设置。Blinky 工程的时钟频率在
Abstract.txt
中可以找到。如果使用的是其他板卡,请自行检查时钟频率。

点击 OK 返回 Target Options。

再次点击 OK 返回主界面。
Trace Setup

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则