调试与跟踪功能介绍
在嵌入式系统开发中,调试和跟踪功能对于软件故障分析、性能优化以及系统验证至关重要。下面将详细介绍一些关键的调试和跟踪组件及其使用方法。
1. 微跟踪缓冲区(MTB)
MTB 可用于软件故障分析,如 HardFault。当使用 MTB 进行此类分析时,调试器会利用向量捕获功能配置处理器,使处理器在发生 HardFault 时自动进入暂停状态。一旦处理器进入 HardFault,调试器会提取跟踪缓冲区中的信息并重建跟踪历史。
MTB 有两种常见的操作模式:
-
循环缓冲区模式
:这是最常用的模式。
-
单次触发模式
:MTB 从分配的跟踪缓冲区起始位置开始写入跟踪信息,当跟踪写入指针达到特定水印级别时自动停止跟踪。此外,MTB 还可以通过断言调试请求信号来停止处理器的执行。
MTB 操作对应用程序的影响可以忽略不计,因为处理器执行分支操作时不会对 SRAM 产生数据访问。不过,像 DMA 控制器这样的其他总线主设备可能会同时尝试访问 SRAM,为了处理这种情况,MTB 内置了总线仲裁器来解决访问冲突。
MTB 解决方案最初在 Arm Cortex - M0 + 处理器中引入,随后在 Cortex - M23 和 Cortex - M33 处理器中也可用。在 Cortex - M33 处理器中,MTB 可以与 ETM 共存;而在 Cortex - M23 处理器中,为了减少硅片面积,芯片设计人员只能实现 ETM 或 MTB 其中一种跟踪解决方案。
2. 跟踪端口接口单元(TPIU)
TPIU 模块用于将跟踪数据包输出到外部世界,以便跟踪捕获设备(如 Keil ULINKPro)能够捕获跟踪数据。Cortex - M 设备中使用的 TPIU 模块通常是为微控制器进行了面积优化的版本,它支持两种输出模式:
-
并行跟踪端口模式(时钟模式)
:提供最多 4 位的并行数据输出和一个跟踪时钟输出。
-
串行线输出(SWO)模式
:使用单比特串行输出,有两种不同的输出编码方式:
- 曼彻斯特编码
- 非归零(NRZ)编码
大多数支持 SWO 的调试探头使用 NRZ 编码。
在时钟模式下,跟踪接口上使用的实际跟踪数据位数可以进行编程配置,以适应不同的大小(即跟踪数据可以是 1/2/4 位,再加上跟踪时钟)。对于引脚数量较少的设备,使用 5 位进行跟踪输出可能不可行,特别是当应用程序已经使用了大量 I/O 引脚时。因此,能够使用更少的引脚是非常理想的。芯片设计人员可以使用配置输入端口限制最大端口大小,使设置在硬件寄存器中可见,这样调试工具就可以确定允许的最大跟踪端口宽度。
在 SWO 模式下,使用 1 位串行协议,这不仅将输出信号数量减少到 1 个,还降低了跟踪输出的最大带宽。此外,跟踪数据输出的速度可以使用预分频器进行编程配置。当将 SWO 与串行线调试协议结合使用时,通常用于 JTAG 协议的测试数据输出(TDO)引脚可以与 SWO 共享。
需要注意的是,SWO 模式下跟踪数据带宽的限制意味着它不适合与 ETM 指令跟踪一起使用。然而,SWO 对于“printf”消息输出和基本事件/性能分析跟踪是足够的。虽然跟踪端口的时钟可以以更高的频率运行以提供更多带宽,但由于 I/O 引脚的最大速度也有限制,所以只能在一定范围内提高。
TPIU 内部的跟踪总线接口(AMBA® ATB)与处理器的跟踪总线相连,它与跟踪端口接口的时钟异步运行。这使得跟踪端口能够以比处理器更高的时钟频率运行,从而提供更高的跟踪带宽。对于并行跟踪端口模式来说这没问题,因为跟踪时钟也会输出到跟踪捕获单元;但对于 SWO 跟踪来说没有参考时钟,因此需要在使用的调试工具中配置项目设置,以便以正确的速度捕获 SWO 跟踪。
由于可能有多个跟踪源连接到 TPIU,TPIU 包含一个格式化器,它将跟踪总线 ID 值封装到跟踪数据输出中,这使得跟踪流可以合并并由调试主机分离。当在没有 ETM 的情况下使用 SWO 模式进行跟踪时,只有一个活动的跟踪总线,此时可以关闭格式化器(即旁路模式)以实现更高的数据吞吐量,在旁路模式下,跟踪总线 ID 值不会封装在跟踪数据中。
要使用 Cortex - M TPIU,需要完成以下操作:
1. 将 DEMCR 中的 TRCENA 位设置为 1。
2. 启用 TPIU 跟踪接口端口的时钟信号(这是特定于设备的,在很多情况下,DEMCR 中的 TRCENA 位也用于启用该时钟信号)。
3. 由跟踪捕获软件对协议(模式)选择寄存器和跟踪端口大小控制寄存器进行编程。
TPIU 包含以下关键寄存器:
| 地址 | 名称 | 类型 |
| ---- | ---- | ---- |
| 0xE0040000 | TPIU 支持的并行端口大小寄存器(TPIU_SPPSR) | RO |
| 0xE0040004 | TPIU 当前并行端口大小寄存器(TPIU_CSPSR) | R/W |
| 0xE0040010 | TPIU 异步时钟预分频器寄存器(TPIU_ACPR) | R/W |
| 0xE00400F0 | TPIU 所选引脚协议寄存器(TPIU_SPPR) | R/W |
| 0xE0040300 | 格式化器和刷新状态寄存器(TPIU_FFSR) | RO |
| 0xE0040304 | 格式化器和刷新控制寄存器(TPIU_FFCR) | R/W |
| 0xE0040308 | 周期性同步控制寄存器(TPIU_PSCR) | R/W |
| 0xE0040FA0 | 声明标签设置 | R/W |
| 0xE0040FA4 | 声明标签清除 | R/W |
这些寄存器的具体功能和使用方法如下:
-
TPIU_SPPSR
:允许调试工具确定跟踪端口的最大宽度。
| 位 | 名称 | 类型 | 复位值 | 描述 |
| ---- | ---- | ---- | ---- | ---- |
| 31:0 | SWIDTH | RO | - | 跟踪端口的最大宽度
0x00000001 — 1 位宽度
0x00000003 — 2 位宽度
0x00000007 — 3 位宽度
0x0000000F — 4 位宽度 |
-
TPIU_CSPSR :允许调试工具设置跟踪端口的宽度。
| 位 | 名称 | 类型 | 复位值 | 描述 |
| ---- | ---- | ---- | ---- | ---- |
| 31:0 | CWIDTH | RO | - | 跟踪端口的当前宽度
0x00000001 — 1 位宽度
0x00000002 — 2 位宽度
0x00000004 — 3 位宽度
0x00000008 — 4 位宽度 | -
TPIU_ACPR :允许调试工具为异步 SWO 输出定义时钟预分频。
| 位 | 名称 | 类型 | 复位值 | 描述 |
| ---- | ---- | ---- | ---- | ---- |
| 31:12 | 保留 | - | - | 保留 |
| 11:0 | PRESCALER | RW | 0 | 跟踪时钟输入的除数为 PRESCALER + 1
注意:架构支持最多 16 位的预分频比,但在现有的 Cortex - M TPIU 中仅实现了 12 位。 | -
TPIU_SPPR :选择输出模式。
| 位 | 名称 | 类型 | 复位值 | 描述 |
| ---- | ---- | ---- | ---- | ---- |
| 31:2 | 保留 | - | - | 保留 |
| 1:0 | TXMODE | RW | 1 | 传输模式
00 — 并行跟踪端口模式
01 — 使用曼彻斯特编码的异步 SWO
10 — 使用 NRZ 编码的异步 SWO | -
TPIU_FFSR :显示格式化器和刷新逻辑的状态。
| 位 | 名称 | 类型 | 复位值 | 描述 |
| ---- | ---- | ---- | ---- | ---- |
| 31:4 | 保留 | - | - | 保留 |
| 3 | FtNonStop | RO | 1 | 格式化器不能停止。 |
| 2 | TCPresent | RO | 0 | 该位始终为 0。 |
| 1 | FtStopped | RO | 0 | 该位始终为 0。 |
| 0 | FlInProg | RO | 0 | 刷新进行中:
0 — 刷新完成或没有刷新正在进行。
1 — 已启动刷新。 | -
TPIU_FFCR :允许调试工具启动跟踪总线上跟踪数据的刷新。
| 位 | 名称 | 类型 | 复位值 | 描述 |
| ---- | ---- | ---- | ---- | ---- |
| 31:9 | 保留 | - | - | 保留 |
| 8 | TrigIn | RO | 1 | 该位读为 1,表示当检测到触发事件时,触发信号会插入到跟踪接口信号中。触发事件可能由 DWT 或 ETM 生成。 |
| 7 | 保留 | - | - | 保留 |
| 6 | FOnMan | RW | 0 | 手动刷新。写入 1 会生成跟踪总线刷新。当刷新完成或 TPIU 复位时,该位会清零。 |
| 5:2 | 保留 | - | - | 保留 |
| 1 | EnFCont | RW | 1 | 启用连续格式化。
0 — 连续格式化禁用(旁路模式)
1 — 连续格式化启用 |
| 0 | 保留 | - | - | 保留 | -
TPIU_PSCR :确定 TPIU 同步数据包的生成频率。
| 位 | 名称 | 类型 | 复位值 | 描述 |
| ---- | ---- | ---- | ---- | ---- |
| 31:5 | 保留 | - | - | 保留 |
| 4:0 | PSCount | RW | 0 | 周期性同步计数。当设置为非零值时,它确定 TPIU 跟踪数据输出在同步之间的近似字节数。
00000 — 同步禁用
00111 — 每 128 字节后生成同步数据包
01000 — 每 256 字节后生成同步数据包
…
11111 — 每 2^31 字节后生成同步数据包 | -
TPIU_CLAIMSET 和 TPIU_CLAIMCLR :允许调试代理软件组件决定哪个软件组件控制 TPIU,类似于硬件信号量。
| 寄存器 | 位 | 名称 | 类型 | 复位值 | 描述 |
| ---- | ---- | ---- | ---- | ---- | ---- |
| TPIU_CLAIMSET | 31:4 | 保留 | - | - | 保留 |
| | 3:0 | CLAIMSET | RW | 0xF | 读取时:
- 如果为 0,表示声明标签位未实现
- 如果为 1,表示声明标签位已实现
写入时:
- 写入 0 无效果
- 写入 1 设置声明标签位 |
| TPIU_CLAIMCLR | 31:4 | 保留 | - | - | 保留 |
| | 3:0 | CLAIMCLR | RW | 0 | 读取时:当前声明标签值
写入时:
- 写入 0 无效果
- 写入 1 清除声明标签位 |
在多处理器系统中使用的 TPIU 与单处理器微控制器中使用的不同。多处理器系统中的 TPIU 可能是 CoreSight TPIU,它支持更宽的跟踪数据端口宽度(最多 32 位)。在这样的系统中,需要额外的跟踪总线组件来合并从多个跟踪源接收到的跟踪数据。由于 SWO 输出可能无法为多个跟踪源提供足够的跟踪数据带宽,因此 CoreSight TPIU 没有 SWO 输出,但它的编程模型与 Cortex - M 的 TPIU 类似。
3. 交叉触发接口(CTI)
交叉触发接口是辅助多处理器调试处理的可选组件。在多处理器系统中,每个处理器都连接有一个 CTI 块,多个 CTI 通过由交叉触发矩阵(CTM)组件组成的调试事件传播网络连接在一起。
使用 CTI 和 CTM 组件,可以将不同处理器之间的调试活动关联起来,例如:
- 当一个处理器因调试事件进入暂停状态时,它可以同时暂停系统中的其他处理器。
- 当多个处理器暂停时,可以同时重启它们。
- 可以将跟踪触发事件发送到多个跟踪源,以便多个跟踪组件几乎同时生成跟踪触发数据包,从而轻松关联多个处理器在触发事件周围的活动。
- 一个处理器的调试事件可以触发另一个处理器的中断,例如在控制大功率电机的系统中,当一个处理器进入暂停状态时,它可以触发另一个处理器的中断并请求其管理可能仍在旋转的电机。
- 一个处理器的调试事件可以用于触发另一个处理器的调试/跟踪操作,例如,一个处理器上的 DWT/ETM 事件可以用于触发另一个处理器上 ETM 的跟踪启动/停止。
调试触发事件和调试通道之间的映射是可编程的,通常由调试工具管理。在单处理器系统中,CTI 组件不太可能存在。在早期的 Arm 处理器中,CTI 组件位于处理器外部,现在已集成作为可选组件,使系统设计更加容易。
4. 启动调试会话
当调试器连接到调试目标时,调试主机会执行以下步骤:
1. 首先尝试检测 JTAG 或串行线调试接口(调试端口模块)中的 ID 寄存器值。
2. 在调试端口中发出调试上电请求,并等待握手完成,以确保系统准备好进行调试连接。
3. 可选地,扫描调试访问端口(DAP)的内部调试总线,检查可用的访问端口(AP)类型。对于 Cortex - M 系统,ID 寄存器值将表明它是一个 AHB - AP 模块。
4. 调试器检查是否可以访问内存映射。
5. 可选地,从 AHB - AP 模块获取主 ROM 表的地址,并通过 ROM 表检测系统中的调试组件。
6. 可选地,根据项目设置将程序映像下载到设备。
7. 可选地,启用复位向量捕获功能,并使用 SCB->AIRCR (SYSRESETREQ) 复位系统。复位向量捕获功能会在执行任何代码之前暂停处理器。
如果执行了步骤 7,处理器将在程序执行开始时暂停,等待用户发出运行命令来执行软件。也可以通过跳过步骤 6 和 7 连接到正在运行的系统而不停止和重置应用程序。
如果系统没有有效的程序映像,处理器在复位后不久可能会进入 HardFault。即使进入了 HardFault,仍然可以连接到处理器,使用复位向量捕获功能将其复位并确保其在执行任何操作之前暂停。从这个位置开始,软件开发人员可以将程序映像下载到内存并执行它。
5. 闪存编程支持
虽然闪存编程不属于调试功能,但闪存编程操作通常依赖于 Cortex - M 处理器上的调试功能。闪存编程支持通常是工具链的一个集成部分,并且可以在调试会话开始时选择性地执行。
闪存通常被划分为多个页面(例如,范围可以从 512 字节到几千字节),因此闪存编程操作通常设计为逐页更新闪存。
使用调试器对 Cortex - M 微控制器进行闪存编程的步骤如下:
1. 使用调试连接并执行启动调试会话中的步骤 1 - 5。
2. 启用复位向量捕获功能,并使用 SCB->AIRCR (SYSRESETREQ) 复位系统,此操作会暂停处理器。
3. 使用调试器下载一小段闪存编程代码,并将第一页程序数据下载到 SRAM。为了使闪存编程能够停止并暂停处理器,在代码末尾插入断点指令。
4. 将程序计数器更改为 SRAM 中闪存编程代码的起始点,并解除处理器的暂停状态,开始执行闪存编程代码。
5. 检测闪存页面编程完成后,调试器更新 SRAM 中的下一个要编程的数据块,并重新启动闪存编程过程。在下载的闪存编程代码末尾使用断点指令,使处理器在执行完闪存编程代码后进入暂停状态。当调试器检测到暂停时,它会检查是否有错误,将程序映像的下一页下载到 SRAM,将 PC 设置回闪存编程代码的开头并重新运行。
6. 重复编程步骤,直到所有闪存页面都更新完毕。此时,调试器可以选择性地运行另一段代码,使用校验和算法验证编程的闪存页面内容是否正确。
7. 使用 SCB->AIRCR (SYSRESETREQ) 再次发出系统复位,处理器暂停并准备执行新的程序映像。
需要注意的是,闪存编程代码可能会首先初始化硬件资源,如时钟和电源管理,以确保闪存编程在正确的速度和条件下进行(例如,电压设置)。
总结
通过以上对 MTB、TPIU、CTI 等调试和跟踪组件的介绍,以及启动调试会话和闪存编程支持的步骤说明,我们可以看到在嵌入式系统开发中,这些功能和操作对于确保软件的正确性和系统的性能优化起着至关重要的作用。合理利用这些工具和技术,可以大大提高开发效率,减少调试时间。
下面是一个启动调试会话的 mermaid 流程图:
graph TD;
A[尝试检测 ID 寄存器值] --> B[发出调试上电请求并等待握手完成];
B --> C{是否扫描内部调试总线};
C -- 是 --> D[扫描并检查 AP 类型];
C -- 否 --> E[检查是否可访问内存映射];
D --> E;
E --> F{是否获取 ROM 表地址};
F -- 是 --> G[获取地址并检测调试组件];
F -- 否 --> H{是否下载程序映像};
G --> H;
H -- 是 --> I[下载程序映像];
H -- 否 --> J{是否启用复位向量捕获};
I --> J;
J -- 是 --> K[启用并复位系统];
J -- 否 --> L[完成调试会话准备];
K --> L;
这个流程图清晰地展示了启动调试会话的各个步骤以及它们之间的逻辑关系。希望这些信息对嵌入式系统开发人员有所帮助。
调试与跟踪功能介绍(续)
6. 各组件的综合应用与注意事项
在实际的嵌入式系统开发中,MTB、TPIU 和 CTI 等组件通常需要协同工作,以实现高效的调试和跟踪。例如,在多处理器系统中,CTI 负责协调各处理器之间的调试活动,TPIU 则将各个处理器产生的跟踪数据输出到外部进行捕获和分析,而 MTB 可以在软件出现故障(如 HardFault)时记录关键的执行信息。
在使用这些组件时,有一些注意事项需要特别关注:
-
MTB 方面
:虽然 MTB 操作对应用程序的影响较小,但要注意 DMA 控制器等其他总线主设备可能带来的 SRAM 访问冲突。同时,不同处理器型号对 MTB 和 ETM 的支持情况不同,在设计系统时需要根据实际需求进行选择。
-
TPIU 方面
:SWO 模式虽然引脚使用少,但带宽有限,不适合与 ETM 指令跟踪一起使用。在配置 TPIU 时,要确保正确设置相关寄存器,如将 DEMCR 中的 TRCENA 位设置为 1,启用跟踪接口端口的时钟信号等。此外,对于 SWO 跟踪,由于没有参考时钟,需要在调试工具中正确配置项目设置,以保证跟踪数据的正确捕获。
-
CTI 方面
:在多处理器系统中使用 CTI 时,要注意调试触发事件和调试通道之间的映射编程,这通常由调试工具完成。同时,单处理器系统中一般不需要使用 CTI 组件。
7. 常见问题及解决方案
在调试和跟踪过程中,可能会遇到一些常见问题,下面为大家列举并给出相应的解决方案:
| 问题描述 | 可能原因 | 解决方案 |
| ---- | ---- | ---- |
| 无法检测到调试目标的 ID 寄存器值 | 调试连接问题、硬件故障 | 检查调试连接是否正确,确保硬件正常工作。可以尝试重新插拔调试器,检查引脚连接是否松动。 |
| 跟踪数据捕获不完整或错误 | TPIU 配置错误、跟踪带宽不足 | 检查 TPIU 相关寄存器的配置,确保设置正确。如果是带宽问题,可以考虑调整跟踪端口模式或时钟频率,但要注意 I/O 引脚的最大速度限制。 |
| 处理器进入 HardFault 后无法恢复 | 程序存在严重错误、MTB 信息提取失败 | 检查程序代码,查找可能导致 HardFault 的原因。确保调试器能够正确提取 MTB 中的信息,重建跟踪历史,以便定位问题。 |
| 多处理器系统中调试活动无法同步 | CTI 配置错误、调试工具设置问题 | 检查 CTI 组件的连接和配置,确保调试触发事件和调试通道之间的映射正确。同时,检查调试工具的设置,确保其能够正确管理多处理器的调试活动。 |
8. 性能优化建议
为了提高调试和跟踪的性能,可以采取以下一些优化建议:
-
合理选择跟踪模式
:根据实际需求选择合适的 TPIU 输出模式。如果对引脚使用要求不高,且需要较高的带宽,可以选择并行跟踪端口模式;如果引脚资源有限,对于“printf”消息输出和基本事件/性能分析跟踪,SWO 模式是一个不错的选择。
-
优化时钟设置
:合理设置 TPIU 的时钟频率和预分频器,以平衡跟踪带宽和系统资源的使用。在满足跟踪需求的前提下,尽量降低时钟频率,减少功耗。
-
减少不必要的跟踪源
:在系统中,可能有多个跟踪源连接到 TPIU。可以根据实际需要,关闭一些不必要的跟踪源,以减少跟踪数据的产生,提高数据处理效率。
-
定期进行系统检查
:在调试过程中,定期检查系统的硬件状态和软件运行情况,及时发现并解决潜在的问题,避免问题积累导致调试效率下降。
9. 未来发展趋势
随着嵌入式系统的不断发展,调试和跟踪技术也在不断进步。未来可能会出现以下一些发展趋势:
-
更高的带宽和更低的功耗
:为了满足日益复杂的系统调试需求,跟踪数据的带宽将不断提高,同时降低功耗以适应移动设备等低功耗应用的要求。
-
更智能化的调试工具
:调试工具将具备更强大的分析和诊断能力,能够自动识别和定位问题,提供更详细的解决方案,减少开发人员的调试工作量。
-
多处理器调试的进一步优化
:随着多处理器系统的广泛应用,调试和跟踪技术将更加注重多处理器之间的协同工作,提高多处理器系统的调试效率和可靠性。
-
与新兴技术的融合
:如人工智能、机器学习等新兴技术可能会融入到调试和跟踪过程中,为开发人员提供更智能、更高效的调试手段。
总结
本文详细介绍了嵌入式系统中调试和跟踪功能的关键组件,包括 MTB、TPIU、CTI 等,以及启动调试会话和闪存编程支持的具体步骤。同时,还讨论了各组件的综合应用、常见问题及解决方案、性能优化建议和未来发展趋势。
通过合理利用这些调试和跟踪技术,可以提高嵌入式系统开发的效率和质量,确保软件的正确性和系统的性能优化。希望本文对嵌入式系统开发人员有所帮助,能够在实际开发中更好地应用这些技术。
下面是一个闪存编程支持的 mermaid 流程图:
graph TD;
A[执行启动调试会话步骤 1 - 5] --> B[启用复位向量捕获并复位系统];
B --> C[下载闪存编程代码和第一页程序数据到 SRAM];
C --> D[更改程序计数器并解除处理器暂停];
D --> E{闪存页面编程是否完成};
E -- 是 --> F[更新 SRAM 数据并重启编程过程];
E -- 否 --> D;
F --> G{所有闪存页面是否更新完毕};
G -- 否 --> D;
G -- 是 --> H{是否验证闪存页面内容};
H -- 是 --> I[运行校验代码验证内容];
H -- 否 --> J[发出系统复位];
I --> J;
J --> K[处理器准备执行新程序映像];
这个流程图清晰地展示了闪存编程支持的各个步骤以及它们之间的逻辑关系,有助于开发人员更好地理解和实施闪存编程操作。
超级会员免费看
2097

被折叠的 条评论
为什么被折叠?



