ZCU106开发板调试手记:当串口不够用时,用XSCT的jtag-uart功能搞定MicroBlaze打印输出
ZCU106开发板调试手记:当串口不够用时,用XSCT的jtag-uart功能搞定MicroBlaze打印输出
在嵌入式开发中,调试信息的输出是验证软件逻辑的关键环节。传统方式依赖物理串口,但在资源受限或接口被占用的场景下,开发者常陷入"无串口可用"的困境。本文将分享如何利用Xilinx工具链中的 XSCT命令行工具 ,通过JTAG接口实现虚拟串口功能,彻底摆脱物理串口的限制。
1. 理解jtag-uart的技术背景与价值
JTAG作为芯片级调试接口,通常仅用于程序下载和硬件调试。但Xilinx的 MicroBlaze Debug Module (MDM) 提供了将JTAG转换为虚拟串口的能力,这种技术称为jtag-uart。其核心原理是:
- MDM模块在FPGA逻辑中实现UART协议栈
- 处理器通过AXI或LMB总线连接MDM
- XSCT工具建立JTAG到MDM的通信隧道
- printf输出被重定向到JTAG接口而非物理UART
与物理串口相比,jtag-uart具有三大优势:
| 对比维度 | 物理UART | jtag-uart |
|---|---|---|
| 硬件资源占用 | 需要专用引脚 | 复用JTAG接口 |
| 连接复杂度 | 需外接转换器 | 仅需标准JTAG电缆 |
| 波特率灵活性 | 受硬件限制 | 理论无速率限制 |
实际项目中,当板载UART被其他外设占用或PCB设计未引出UART引脚时,jtag-uart往往成为唯一可行的调试方案。
2. 硬件环境搭建与MDM配置
以ZCU106开发板为例,配置jtag-uart需要以下准备工作:
-
Vivado工程配置 :
- 在Block Design中添加MicroBlaze Debug Module IP
- 确保MDM参数中启用UART功能(默认开启)
- 连接MDM到处理器的调试总线(AXI或LMB)
-
关键避坑点 :
- MDM时钟必须与处理器调试接口同源
- 在Zynq UltraScale+平台,需禁用PS侧的UART0/1复用
- 检查Address Editor中MDM的基地址是否冲突
# 示例:Vivado中验证MDM连接的Tcl命令
get_bd_cells -filter {VLNV =~ "*mdm*"}
get_bd_intf_pins -of [get_bd_cells mdm_1] -filter {MODE == Slave}
-
生成比特流时的注意事项
:
- 实现后需确认MDM被正确映射到调试网络
-
建议在Vivado中运行
report_debug_cores命令验证
3. 软件工程的关键配置步骤
在Vitis环境中,BSP配置直接影响jtag-uart的可用性。以下是经过实战验证的配置流程:
3.1 BSP参数设置
- 打开应用工程的Board Support Package设置
-
在
standalone驱动配置中找到stdin/stdout选项 -
将设备选择为
psu_coresight_0(而非常见的mdm_0) - 保存配置并重新生成BSP
这是最易出错的环节——选择mdm_0会导致输出无法传递到JTAG接口。笔者曾因此浪费一整天排查问题。
3.2 应用代码适配
无需修改标准printf语句,但建议添加重定向检查代码:
#include <stdio.h>
#include <xil_printf.h>
int main() {
// 验证输出通道是否就绪
if (XST_SUCCESS != Xil_AssertSetCallback(debug_uart_assert)) {
xil_printf("Warning: STDIO not initialized properly!\n");
}
// 正常调试输出
printf("JTAG-UART test message\n");
return 0;
}
4. XSCT实战操作全流程
完成软硬件准备后,通过以下步骤启动jtag-uart终端:
-
硬件连接:
- 使用USB-JTAG电缆连接开发板
- 开发板上电(注意供电稳定性)
-
启动XSCT会话:
-
在Vitis菜单中选择
Xilinx Tools > XSCT Console -
或直接运行
xsct命令启动独立终端
-
在Vitis菜单中选择
-
核心操作命令序列:
# 建立JTAG连接
connect
# 查看处理器状态(简写ta即targets)
ta
# 启动jtag-uart终端
jtagterminal -start
# 下载可执行文件(注意路径格式)
dow {C:/project/debug/app.elf}
# 运行程序
con
路径格式陷阱
:Windows环境下必须用
{}
包裹路径,例如:
# 正确写法
dow {D:/work/zcu106/app/Debug/app.elf}
# 错误写法(会导致下载失败)
dow D:\work\zcu106\app\Debug\app.elf
-
调试技巧:
-
使用
stop命令暂停处理器执行 -
step可单步执行代码 -
bpadd添加断点时建议使用函数名而非绝对地址
-
使用
5. 高级调试场景与故障排除
当基础功能正常后,可尝试以下进阶应用:
5.1 多核调试配置
在Zynq UltraScale+多核系统中,需指定目标处理器:
# 列出所有可用处理器
targets -filter {name =~ "Cortex-A53*"}
# 选择特定核心
target 2
jtagterminal -start
5.2 常见问题解决方案
现象1:jtagterminal无输出
- 检查MDM时钟是否激活
- 确认BSP中STDIO连接的是psu_coresight_0
- 尝试重置处理器后重新运行
现象2:输出乱码
- 确认MDM UART波特率与软件设置匹配
- 检查JTAG电缆连接质量(可尝试降低TCK频率)
现象3:连接不稳定
- 更换USB端口或JTAG电缆
- 在Vivado Hardware Manager中验证JTAG链完整性
# 诊断JTAG链的Tcl命令
open_hw
connect_hw_server
current_hw_target [get_hw_targets *]
open_hw_target
get_hw_devices
5.3 性能优化技巧
-
在
xsct启动时添加-nocrc参数可加快下载速度 - 对于大量输出,建议在代码中控制printf频率
-
使用
-quiet参数减少XSCT自身日志输出
在最近的一个电机控制项目中,我们通过jtag-uart成功调试了无感FOC算法。当所有串口都被用于与上位机通信时,JTAG终端成为观察转子位置估算值的唯一窗口。特别是在紧急排查过流保护问题时,实时输出的电流采样数据帮助我们快速定位了ADC采样时序的偏差。
更多推荐

所有评论(0)