时间敏感网络(TSN)技术在工业自动化、车联网和智能制造等领域展现出巨大的潜力,但目前实际落地的解决方案仍然有限。Xilinx 提供的 TSN IP 核解决方案,支持多种 IEEE 802.1 标准,能够实现确定性通信,确保关键数据流的传输延迟在可控范围内。然而,在将 TSN 技术移植到具体硬件平台(如 Xilinx ZYNQ7020 FPGA 开发板)时,开发者需要应对复杂的协议栈、硬件资源优化以及软硬件协同等多层次的技术挑战。
本文以 Xilinx ZYNQ7020 FPGA 开发板(AX7021B)为例,详细介绍了 TSN IP 核的移植与开发过程,包括硬件配置、软件环境搭建、设备树生成、内核编译和系统启动等关键环节。这一工作不仅为 FPGA 开发者和嵌入式系统工程师提供了清晰的技术指导,也为 TSN 技术在工业和嵌入式领域的实际应用奠定了坚实的基础。
一、Xilinx TSN IP核概述
TSN IP 核支持 IEEE 1588 精确时间协议(PTP),能够实现纳秒级的时间同步。它还支持基于时间片的流量调度机制,确保高优先级数据流的实时传输。通过帧抢占功能,TSN IP 核允许高优先级帧中断低优先级帧的传输,从而减少关键数据的延迟。此外,TSN IP 核通过流量整形算法,确保网络流量的平稳传输,避免拥塞。
如图1所示,Xilinx TSN IP 核包含三个主要组件:Endpoint(端口 0)、MAC1(端口 1)和 MAC2(端口 2)。Endpoint 连接到 DMA(直接内存访问),负责处理不同类型的数据流,如 Best Effort、Scheduled Traffic 和 Reserved。MAC1 通过 PHY1 连接到外部网络,而 MAC2 通过 PHY2 连接到外部网络。这种架构设计使得 TSN IP 核能够高效地处理多种类型的网络流量,满足不同应用场景的需求。

图1:TSN IP
二、开发环境
在了解了 Xilinx TSN IP 核的基本架构和功能之后,下一步是搭建开发环境,以便进行 TSN IP 核的移植、配置和优化。Xilinx 提供了完整的开发工具链和软件支持,帮助开发者快速上手 TSN IP 核的开发工作。本章将详细介绍开发环境的搭建步骤,包括硬件平台的选择、软件工具的安装以及开发流程的概述。
1.硬件平台

图2:Xilinx ZYNQ7020 FPGA开发板
本文使用的硬件平台为 Xilinx ZYNQ7020 FPGA 开发板(AX7021B),其核心板主要由以下组件构成:
ZYNQ7020:芯片型号为 XC7Z020-2CLG484I
内存:2片 DDR3 内存
存储:8GB eMMC Flash 和 256Mb QSPI Flash
外围接口:5路千兆以太网接口(1PS+4PL)、4路 USB 2.0 HOST 接口、1路 HDMI 输出接口、1路 SD 卡接口、1路 UART USB 接口以及2路40针扩展口
2.软件环境
Windows 开发环境:Vivado v2019.1,用于 FPGA 设计和综合。用于 FPGA 设计和综合。Vivado 是 Xilinx 提供的集成开发环境(IDE),支持从硬件设计到比特流生成的全流程开发。开发者可以通过 Vivado 配置 TSN IP 核,生成硬件描述文件(HDF)和比特流文件(BIT)。
Linux 开发环境:Ubuntu 16.04,用于 Petalinux 和内核编译。
在 Ubuntu 16.04 上,首先需要安装一些必要的库和工具,以确保后续的开发工具能够正常运行。执行以下命令安装所需的库:
sudo apt-get install tofrodos gawk xvfb git libncurses5-dev tftpd zlib1g-dev
zlib1g-dev:i386 libssl-dev flex bison chrpath socat autoconf libtool texinfo
gcc-multilib libsdl1.2-dev libglib2.0-dev screen pax
Petalinux v2019.1安装,官网下载,Petalinux 是 Xilinx 提供的嵌入式 Linux 开发工具,用于构建和定制 Linux 系统。以下是 Petalinux 的安装步骤:
创建 Petalinux 安装目录并设置权限
sudo -s
mkdir -p /opt/pkg/petalinux
chown zjwang /opt/pkg/
chgrp zjwang /opt/pkg/
chgrp zjwang /opt/pkg/petalinux/
chown zjwang /opt/pkg/petalinx/
下载 Petalinux 安装包并赋予执行权限
sudo chmod +x petalinux-v2019.1-final-installer.run
运行安装程序,将 Petalinux 安装到指定目录
./petalinux-v2019.1-final-installer.run /opt/pkg/petalinux/
在完成硬件平台和软件环境的搭建后,开发者可以按照以下步骤进行 TSN IP 核的开发:
使用 Vivado 配置 TSN IP 核,生成硬件描述文件(HDF)和比特流文件(BIT),完成硬件设计
使用 Petalinux 创建嵌入式 Linux 项目,导入硬件描述文件,生成设备树文件,并编译内核,完成嵌入式 Linux 系统开发
通过 U-Boot 配置启动参数,制作启动镜像(BOOT.BIN),并将其烧录到 SD 卡中;启动系统后,使用 Xilinx 提供的工具(如 switch_cam、qbv_sched 等)对 TSN IP 核进行配置和测试,完成软件配置与调试
下面对以上步骤进行详细介绍。
三、TSN IP核开发流程与实现步骤
1. 硬件设计
根据目标平台的特性,修改 TSN IP 核的引脚配置和接口设置,并通过 Vivado 生成比特流文件(BIT)和硬件描述文件(HDF)。以下是详细的硬件设计步骤。
在 Vivado 中打开 ZYNQ 7000 IP 核,对SD,PS等引脚进行如下配置。

图3:SD配置
Zynq7000配置SD引脚:将SD0、CD(Card Detect)分别设置为MIO 40-45、MIO 10。

图4:以太网复位配置
Zynq7000配置PS网口:ZYNQ 7000中有两个以太网接口,但是开发板上只有一个PS网口,因此,将PS的ENET0连接网口1,并将复位信号设置为FIXED MIO。将ENET1通过EMIO引出为GMII接口,将其与 GMII to RGMII IP 核连接后转换成 RGMII 接口,然后与网口2连接。

图5:以太网接口配置
配置ETH0和ETH1:按照上图配置ETH0和ETH1,将ETH1及其MDIO通过EMIO引出。

图6:时钟频率配置
设置时钟:将FCLK_CLK1设置为200M,作为GMII to RGMII IP核内部的参考时钟

图7:gmii_to_rgmii IP核配置
添加gmii_to_rgmii IP核,并按照上图进行配置
在HR BANK中,IP核中RGMII接口的接收数据信号和控制信号需要通过IDELAYE2来调整信号输入延时,使其时序满足建立和保持时间约束。因此需要在IP核包含与IDELAYE2相关的IDELAYCTRL,用来校准IDELAYE2每个延时tap的延时值。
将本IP核的PHY address 设置为14,该值可任意设置,但不能与现有的 PHY address相同,否则将产生冲突使 IP 核工作异常)。
选择shared logic包含在IP核内部。

图8:Utility Vector Logic配置
添加Utility Vector Logic,并将其配置为非门,将FCLK_RESET1_N通过后作为GMII to RGMII IP核的复位信号。
添加如下约束:
set_property SLEW FAST [get_ports ps_phy1_rgmii_txc]
set_property SLEW FAST [get_ports ps_phy1_rgmii_tx_ctl]
set_property SLEW FAST [get_ports {ps_phy1_rgmii_txd[*]}]create_clock -period 8.000 -name rgmii_rx_clk [get_ports ps_phy1_rgmii_rxc]
set_input_delay -clock [get_clocks rgmii_rx_clk] -max -1.5 [get_ports {{ps_phy1_rgmii_rxd[*]} ps_phy1_rgmii_rx_ctl}]
set_input_delay -clock [get_clocks rgmii_rx_clk] -min -2.8 [get_ports {{ps_phy1_rgmii_rxd[*]} ps_phy1_rgmii_rx_ctl}]
set_input_delay -clock [get_clocks rgmii_rx_clk] -clock_fall -max -add_delay -1.5 [get_ports {{ps_phy1_rgmii_rxd[*]} ps_phy1_rgmii_rx_ctl}]
set_input_delay -clock [get_clocks rgmii_rx_clk] -clock_fall -min -add_delay -2.8 [get_ports {{ps_phy1_rgmii_rxd[*]} ps_phy1_rgmii_rx_ctl}]
PL 侧是 TSN IP 核导出的两个 RGMII 接口,开发者需要根据产品手册分配管脚并进行约束。以下是 PL 网口的管脚配置示例:
set_property -dict {PACKAGE_PIN N17 IOSTANDARD LVCMOS18} [get_ports {pl_phy0_rgmii_txd[0]}]
set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVCMOS18} [get_ports {pl_phy0_rgmii_txd[1]}]
set_property -dict {PACKAGE_PIN N19 IOSTANDARD LVCMOS18} [get_ports {pl_phy0_rgmii_txd[2]}]
set_property -dict {PACKAGE_PIN N20 IOSTANDARD LVCMOS18} [get_ports {pl_phy0_rgmii_txd[3]}]
set_property -dict {PACKAGE_PIN R20 IOSTANDARD LVCMOS18} [get_ports pl_phy0_rgmii_tx_ctl]
set_property -dict {PACKAGE_PIN R21 IOSTANDARD LVCMOS18} [get_ports pl_phy0_rgmii_txc]
set_property -dict {PACKAGE_PIN J18 IOSTANDARD LVCMOS18} [get_ports {pl_phy0_rgmii_rxd[0]}]
set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS18} [get_ports {pl_phy0_rgmii_rxd[1]}]
set_property -dict {PACKAGE_PIN J15 IOSTANDARD LVCMOS18} [get_ports {pl_phy0_rgmii_rxd[2]}]
set_property -dict {PACKAGE_PIN K15 IOSTANDARD LVCMOS18} [get_ports {pl_phy0_rgmii_rxd[3]}]
set_property -dict {PACKAGE_PIN K20 IOSTANDARD LVCMOS18} [get_ports pl_phy0_rgmii_rx_ctl]
set_property -dict {PACKAGE_PIN K19 IOSTANDARD LVCMOS18} [get_ports pl_phy0_rgmii_rxc]
set_property -dict {PACKAGE_PIN J17 IOSTANDARD LVCMOS18} [get_ports pl_phy0_mdc]
set_property -dict {PACKAGE_PIN J16 IOSTANDARD LVCMOS18} [get_ports pl_phy0_mdio]
set_property -dict {PACKAGE_PIN L19 IOSTANDARD LVCMOS18} [get_ports pl_phy0_nrst_o]
通过以上步骤,完成 TSN IP 核的硬件设计,生成比特流文件(BIT)和硬件描述文件(HDF),为后续的嵌入式 Linux 系统开发和软件配置奠定基础。
2. 嵌入式Linux系统开发
这一阶段的主要任务是根据HDF硬件描述文件生成设备树文件,并编译内核。以下是详细的步骤。
在Xilinx Github(https://github.com/Xilinx/device-tree-xlnx/)上下载Device Tree Generator(设备树生成器)的BSP。使用git checkout xilinx-v2019.2切换版本。
git clone https://github.com/Xilinx/device-tree-xlnx.git
cd device-tree-xlnxgit
checkout xilinx-v2019.2
配置SDK

图9:SDK设备树配置
1.打开SDK
2.选择Xilinx-> Repositories
3.在Local Repositories中点击New,将在github中下载的文件夹路径添加进去
4.点击OK,等待编译完成,大概需要2分钟

图10:生成Device Tree
1.新建BSP:File->New->Board Support Package
2.在Board Support Package OS中选择device_tree,点击Finish
3.在BSP弹出的设置中,填写内核启动参数,填写完后点击OK
4.在SDK目录下会看到生成的设备树文件夹
5.在linux中使用dtc -I dts -O dtb -o system.dtb system-top.dts生成system.dtb设备树文件
内核编译是嵌入式 Linux 系统开发的核心步骤之一。以下是编译内核和根文件系统的详细流程。
- 使用官方 linux-xlnx-xilinx-v2019.2 版本的内核源码
- 配置内核
运行以下命令生成默认的内核配置
make ARCH=arm xilinx_zynq_defconfig
- 配置内核选项
运行以下命令进入内核配置界面
make ARCH=arm menuconfig
在配置界面中,确保开启以下内核选项
CONFIG_IRQCHIP=y
CONFIG_XILINX_INTC=y
CONFIG_NET_SWITCHDEV=y
CONFIG_NETFILTER=y
CONFIG_XILINX_TSN=y
CONFIG_AXIENET_HAS_TADMA=y
CONFIG_XILINX_TSN_PTP=y
CONFIG_XILINX_TSN_QBV=y
CONFIG_XILINX_TSN_SWITCH=y
CONFIG_XILINX_TSN_QCI=y
CONFIG_XILINX_TSN_CB=y
CONFIG_XILINX_TSN_QBR=y
CONFIG_STP=y
CONFIG_XILINX_GMII2RGMII=y
- 编译内核
运行以下命令编译内核:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage -j10
编译完成后,生成的内核镜像(zImage)位于 arch/arm/boot/ 目录下。
对于ZYNQ硬件平台,启动嵌入式Linux系统需要这些文件:FSBL镜像文件、bitstream文件、U-Boot、内核镜像(kernel)、设备树(device tree)、根文件系统(rootfs)。由于开发过程中设备树、内核和根文件系统等部分改动较为频繁,因此我们将这些要素独立配置,使其灵活调整。此外,为简化系统更新和维护,将 bit 文件从原先的 BOOT.BIN 文件中剥离出来,单独管理。同时将内核镜像(zImage)和设备树(system.dtb)分别存储在 SD 卡分区中,并将根文件系统放入 SD 卡的 EXT4 分区。
1.新建 Petalinux 工程并导入硬件文件(HDF)
mkdir peta_prj
mv top.hdf peta_prj/ cd peta_prj/ source /opt/pkg/petalinux/settings.sh petalinux-create --type project --template zynq --name tsn_peta cd tsn_peta/petalinux-config --get-hw-description ../linux.sdk
2.剥离出bitStream文件

图11:Petalinux工程配置
进入“Subsystem AUTO Hardware Settings”子菜单下的“Advanced bootable imagesstorage Settings”菜单中,移动到“dtb image settings”选项,并将image storage media设置为primary sd

图12:Petalinux工程配置2
进入到“Image Packaging Configuration”菜单下的“Root filesystem type(INITRAMFS)”子菜单下,设置为SD card
3.配置完成后,编译u-boot,以及生成BOOT.BIN文件
petalinux-build -c u-boot
petalinux-package --boot --fsbl --u-boot --force

图13:生成BOOT.BIN
将前面过程中的zImage(内核镜像,内核源码目录 arch/arm/boot/zImage)、system.dtb(内核设备树 dtb 文件)、system.bit(pl 端 bitstream 文件,Petalinux工程目录下的 images/linux/system.bit)、BOOT.BIN(包含FSBL、u-boot)拷贝到FAT分区。将根文件系统解压到EXT4。
配置 U-Boot 加载和启动流程
# 设置比特流加载地址和文件名
setenv bitstream_load_address 0x100000
setenv bitstream_image system.bit
setenv bitstream_size 0x300000
# 设置内核加载地址和文件名
setenv kernel_load_address 0x2080000
setenv kernel_image zImage
# 设置设备树加载地址和文件名
setenv dtb_load_address 0x2000000
setenv dtb_image system.dtb
# 设置加载 FPGA 比特流的命令
setenv load_bitstream 'load mmc 0 ${bitstream_load_address} ${bitstream_image} && fpga loadb 0 ${bitstream_load_address} ${bitstream_size}' # 设置加载内核的命令
setenv load_kernel 'load mmc 0 ${kernel_load_address} ${kernel_image}'
# 设置加载设备树的命令
setenv load_dtb 'load mmc 0 ${dtb_load_address} ${dtb_image}'
# 设置启动命令
setenv bootcmd 'run load_bitstream && run load_kernel && run load_dtb && bootz ${kernel_load_address} - ${dtb_load_address}'
完成以上步骤后,系统即可从 SD 卡启动,进入嵌入式 Linux 环境。
四、总结
本文详细介绍了基于 Xilinx ZYNQ7020 FPGA 开发板的 TSN IP 核移植与开发过程。从硬件配置到嵌入式 Linux 系统开发,再到系统启动的全流程,每一步都提供了清晰的操作指南和配置细节。通过对 TSN IP 核的深入分析与实践,展示了如何利用 Xilinx 提供的工具链和解决方案,实现时间敏感网络的高性能和高可靠性应用。
通过本文的指导,开发者不仅能够掌握 TSN IP 核的基本使用方法,还能在实际项目中灵活调整配置,优化系统性能。这为 TSN 技术在工业和嵌入式领域的进一步推广奠定了坚实基础。未来的工作可围绕 TSN IP 核的扩展功能进行深度挖掘,例如多节点网络的同步优化、复杂流量场景的动态调度等,从而充分发挥 TSN 的技术潜力。