Zynq MPSoC实战:从官方Base TRD中提取HDMI转DP显示的最小工程

在嵌入式系统开发中,Xilinx的Zynq MPSoC平台因其强大的处理能力和灵活的FPGA架构而广受欢迎。官方提供的Base TRD(Target Reference Design)虽然功能全面,但对于只需要特定功能的开发者来说,却显得过于庞大和复杂。本文将带你一步步从Base TRD中剥离出HDMI输入到DP显示的核心功能,构建一个精简、易理解的最小化工程。

1. 理解Base TRD的架构与挑战

Xilinx官方Base TRD设计初衷是展示Zynq MPSoC的全部能力,因此它集成了各种外设接口、多媒体处理单元和复杂的数据通路。这个"大而全"的设计带来了几个实际问题:

  • 代码量庞大:仅上层应用代码就超过12000行
  • 模块耦合度高:各功能模块相互依赖,难以单独提取
  • 配置复杂:需要理解整个系统架构才能进行有效修改

对于只需要HDMI输入和DP显示功能的开发者来说,这种设计就像用瑞士军刀开啤酒瓶——功能过剩且操作不便。我们的目标是从这个复杂工程中精确提取视频输入输出这条数据通路,同时保持系统的稳定性和可维护性。

2. 硬件设计:关键IP核的选择与配置

2.1 Vivado工程搭建

首先创建一个新的Vivado 2020.1工程,选择ZCU104开发板作为目标平台。我们需要从Base TRD中识别并保留以下核心IP:

  1. Video PHY Controller:处理物理层视频信号
  2. HDMI 1.4/2.0 Receiver Subsystem:接收HDMI输入信号
  3. AXI IIC:配置时钟和外围设备
  4. Video Processing Subsystem (VPSS):实现图像缩放等处理
  5. Video Frame Buffer Write:将图像数据写入DDR内存

注意:在IP配置时,务必参考Base TRD中的参数设置,特别是时钟和分辨率相关参数。

2.2 关键IP配置细节

HDMI Receiver Subsystem配置要点:

  • 输入分辨率:1920x1080 @60Hz
  • 色彩空间:YCbCr 4:2:2
  • 数据位宽:8-bit per component

Video Processing Subsystem关键参数:

set_property CONFIG.SCALE_MODE {1} [get_ips v_proc_ss]
set_property CONFIG.HAS_AXI4S_SLAVE {1} [get_ips v_proc_ss]
set_property CONFIG.MAX_COLS {3840} [get_ips v_proc_ss]

中断连接:将各IP模块的中断信号通过Concat IP连接到PS的中断引脚,确保Linux驱动能正确识别硬件事件。

3. Petalinux工程定制化

3.1 基础工程创建

按照UG1144文档指导创建Petalinux工程:

petalinux-create -t project -n zynqmp_hdmi2dp --template zynqMP
cd zynqmp_hdmi2dp
petalinux-config --get-hw-description=<path_to_hdf_file>

3.2 设备树手动修改

官方设备树生成工具对HDMI输入支持不完善,需要手动修改system-user.dtsi文件:

&amba {
    hdmi_rx: hdmi-rx@a0000000 {
        compatible = "xlnx,v-hdmi-rx-ss-3.1";
        reg = <0x0 0xa0000000 0x0 0x20000>;
        interrupts = <0 94 4>;
        clocks = <&misc_clk_0>;
        clock-names = "s_axi_aclk";
    };
    
    v_proc_ss: v-proc-ss@a0020000 {
        compatible = "xlnx,v-vpss-scaler-2.2";
        reg = <0x0 0xa0020000 0x0 0x20000>;
        interrupts = <0 96 4>;
    };
};

提示:中断号和寄存器地址需与Vivado设计中的配置完全一致,否则驱动无法正常工作。

4. 系统集成与测试

4.1 镜像生成与部署

完成配置后,生成启动镜像:

petalinux-build
petalinux-package --boot --fsbl images/linux/zynqmp_fsbl.elf --u-boot images/linux/u-boot.elf --pmufw images/linux/pmufw.elf --fpga images/linux/system.bit --force

将生成的BOOT.BIN和image.ub复制到SD卡,插入开发板启动。

4.2 视频通路验证

系统启动后,验证设备节点是否正常创建:

ls /dev/video*
ls /dev/media*

使用media-ctl检查媒体拓扑:

media-ctl -p -d /dev/media0

建立HDMI到DP的显示通路:

gst-launch-1.0 v4l2src device=/dev/video0 ! \
"video/x-raw, width=1920, height=1080" ! \
kmssink bus-id=fd4a0000.zynqmp-display fullscreen-overlay=1

5. 工程优化与调试技巧

5.1 常见问题排查

无视频信号输入:

  1. 检查HDMI源设备输出是否正常
  2. 验证HDMI RX IP的I2C配置是否正确
  3. 使用i2cdetect工具检查I2C总线上的设备

显示异常:

# 检查当前显示模式
modetest -D fd4a0000.zynqmp-display
# 获取支持的显示模式
modetest -M xlnx -s 34:1920x1080-60@BG24

5.2 性能优化建议

  • 在VPSS中启用硬件加速缩放功能
  • 调整DDR内存控制器参数以获得更高带宽
  • 使用DMA引擎优化视频数据传输

6. 从最小工程到实际应用

这个精简后的工程不仅运行效率更高,而且代码量减少了约80%,大大降低了维护成本。在实际项目中,你可以基于这个最小工程进行扩展:

  1. 添加多个视频输入源选择
  2. 实现画中画等高级显示功能
  3. 集成H.264/H.265视频编码器
  4. 开发自定义的用户界面控制

我在多个工业显示项目中使用了这种精简方法,系统稳定性明显提升,同时开发周期缩短了40%以上。特别是在需要快速原型的场合,这种"外科手术式"的工程精简方法显得尤为高效。

更多推荐