1. 前言和相关工作
时间敏感网络(TSN, Time-Sensitive Networking)作为新一代工业网络技术,凭借卓越的实时性、可靠性和灵活性,是工业自动化、智能交通及电力能源等领域数字化转型的重要支柱。本文以ZYNQ7020 FPGA 开发板(AX7021B)作为TSN交换机,国产处理器飞腾D2000和鲲鹏920作为TSN端系统,组合国产开源操作系统OpenHarmony和openEuler构建TSN平台。该平台功能涵盖时间同步、确定性实时通信等关键特性,确保关键数据流的传输延迟可控,在本平台下,稳定状态下时间同步精度偏移量只有几十纳秒甚至几纳秒。这一软硬结合的方案,为 TSN 技术在国产环境中的落地提供了坚实基础。
2. 平台架构和软硬件环境
平台整体架构如图1所示,我们采用ZYNQ7020 FPGA 开发板(AX7021B)作为TSN交换机硬件,飞腾D2000与鲲鹏920分别作为TSN端系统的端侧节点与云服务器,OpenHarmony(4.1 Release)和openEuler(22.03 LTS)作为TSN端系统的软件支撑。

图1:平台架构图
在了解整体平台架构后,下一部分会详细介绍使用的硬件以及部分软件。
2.1 TSN交换机
我们成功将TSN IP核及应用层协议移植至ZYNQ7020 FPGA开发板,如图2所示,此过程涵盖了硬件配置、软件环境搭建、设备树生成、内核编译以及系统启动等一系列关键环节,具体细节可参阅我们之前发表的公众号文章:TSN IP核移植实践。

图2:TSN交换机(基于ZYNQ7020 FPGA开发板)
(1)交换机说明
在ZYNQ7020 FPGA开发板TSN交换机上,它一共有4个网络接口,其中eth0为普通网络接口(不可进行TSN的协议编程),ep、eth2及eth3为FPGA可编程网络接口(ep为处理器内部网络接口用于转发控制其他网络接口,eth2、eth3可根据具体的开发环境进行个性化配置)。
(2)交换机配置
在TSN交换机上,需要注意的是普通网口eth0与FPGA的ep网口物理上并不连通,因此需要通过brctl命令搭建以太网桥,将eth0和ep网络接口形成一个逻辑上的单一网络,具体命令如下。
brctl addbr br0 # 创建一个新的网桥
brctl addif br0 eth0 # 将物理接口eth0加入
brctl addif br0 ep # 将物理接口ep加入
ip link set dev br0 up # 启用
2. 2 TSN端系统:飞腾D2000开发板+OpenHarmony
该部分介绍如何在飞腾D2000硬件平台上启动运行OpenHarmony,并外接支持硬件时间戳网卡及LinuxPTP等工具的移植,我们使用的飞腾D2000硬件如图3所示。

图3:飞腾D2000开发板
(1)OpenHarmony适配
通过repo+ssh下载源码
export WORK_SPACE=/home/xxx/workspace #替换成自己定义的workspace路径
export PROJ_ROOT=$WORK_SPACE/OpenHarmony
mkdir $WORK_SPACEmkdir $PROJ_ROOT
cd $PROJ_ROOT
repo init -u https://gitee.com/openharmony/manifest -b refs/tags/OpenHarmony-v4.1-Release --no-repo-verify
repo sync -c
repo forall -c 'git lfs pull'
使用安装包方式获取编译工具链。
sudo apt-get update && sudo apt-get install binutils git git-lfs gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 bc gnutls-bin python3.8 python3-pip ruby openjdk-11-jdk libtinfo5 npm dosfstools parted kpartx genext2fs libxt-dev libx11-dev xorg-dev mtools执行prebuilts
进入OpenHarmony源码根目录,执行脚本,安装编译器及二进制工具
cd $PROJ_ROOT
bash build/prebuilts_download.sh
export PHY_DEV=$WORK_SPACE/phytium_device
mkdir $PHY_DEV
cd $PHY_DEV
git clone git@gitee.com:phytium_embedded/phytium-openharmony-device.git
./phytium_env.sh $PROJ_ROOT 0
THE OHOS_PATH_ROOT: /home/xxx/workspace/OpenHarmony
THE DEVICE: tengrui_d(0)
#### sync phytium env start!####
#### sync device_soc_phytium ####
#### sync device_soc_phytium end ####
#### sync device_board_phytium ####
#### sync device_board_phytium end ####
#### sync vendor_phytium ####
#### sync vendor_phytium end ####
......
#### sync phytium end!####
SATA硬盘:
menuentry 'boot'{linux /Image LABEL=boot root=/dev/ram0 hardware=d2000 selinux=0 rootfstype=ext4 console=ttyAMA0,115200 cma=256M ohos.required_mount.system=/dev/block/sda2@/usr@ext4@ro,barrier=1@wait,required ohos.required_mount.vendor=/dev/block/sda3@/vendor@ext4@ro,barrier=1@wait,required ohos.required_mount.userdata=/dev/block/sda4@/data@ext4@nosuid,nodev,noatime,barrier=1,data=ordered,noauto_da_alloc@wait,reservedsize=104857600initrd /ramdisk.img}
NVME硬盘:
menuentry 'boot'{linux /Image LABEL=boot root=/dev/ram0 hardware=d2000 selinux=0 rootfstype=ext4 console=ttyAMA0,115200 cma=256M ohos.required_mount.system=/dev/block/nvme0n1p2@/usr@ext4@ro,barrier=1@wait,requiredohos.required_mount.vendor=/dev/block/nvme0n1p3@/vendor@ext4@ro,barrier=1@wait,required ohos.required_mount.userdata=/dev/block/nvme0n1p4@/data@ext4@nosuid,nodev,noatime,barrier=1,data=ordered,noauto_da_alloc@wait,reservedsize=104857600initrd /ramdisk.img }
# 编译镜像cd $PROJ_ROOT
./build.sh --product-name d2000 --ccache --target-cpu arm64
# 打包镜像,生成镜像文件
cd out/d2000/packages/phone/images/
sudo apt-get install kpartx
chmod a+x generate_image.sh
./generate_image.sh efi
Linux下烧录OpenHarmony镜像到飞腾D2000
将飞腾D2000硬盘取下放入对应尺寸的读卡器中,插入Linux系统。
使用lsblk确定对应设备,一般为/dev/sdX。
使用dd命令烧录镜像文件,命令如下所示。
sudo dd if=/path/to/iso of=/dev/sdX bs=4M status=progress && sync
Windows下烧录OpenHarmony镜像到飞腾D2000
将飞腾D2000硬盘取下放入读卡器中,插入Windows系统。
打开rufus软件,会自动识别到硬盘,选择OpenHarmony镜像文件开始烧录。
通过以上操作,进入系统后运行uname -r命令结果如下图所示:

图4:OpenHarmony在飞腾D2000上启动
(2)I210网卡及网卡驱动适配
主节点鲲鹏920和端节点飞腾D2000自带网卡只支持软件时间戳,若要支持硬件时间同步,必须外接PCIE网卡,我们采用I210系列网卡,如图5所示。并针对所选操作系统(OpenHarmony和openEuler),适配网卡驱动程序。确保了网络数据包能够被精确打上时间戳,为后续的时间同步和时延测量提供了关键支持。

图5:I210-T1网卡
通过以下步骤编译网卡驱动程序,实现OpenHarmony操作系统在飞腾D2000上识别到I210网卡:
(a)下载OpenHarmony内核源码并编译(见上一小节:OpenHarmony适配)
(b)下载对应的网卡驱动源码
在Inter官方下载I210网卡的驱动程序,链接如下:https://www.intel.cn/content/www/cn/zh/products/sku/71839/intel-ethernet-controller-i210as/downloads.html
(c)修改网卡驱动Makefile文件
下载解压后修改Makefile文件,指定OpenHarmony支持的编译器:
# 指定编译器
CC:=/home/zhaohang/workspace/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/aarch64-unknown-linux-ohos-clang
LD:=/home/zhaohang/workspace/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/ld.lld
交叉编译之后的OpenHarmony内核源码环境:
// 加载 Linux 内核编译环境
KDIR := /home/zhaohang/workspace/OpenHarmony/out/d2000/KERNEL_OBJ/kernel/src_tmp/linux-5.10
(d)编译并加载驱动
修改Makefile后,运行make命令,会生成.ko后缀的文件,拷贝到OpenHarmony机器上运行insmod命令加载驱动,等一会后执行ifconfig命令,如图6所示,新增网卡接口eth2。

图6:MobaXterm验证网卡
(3) LinuxPTP移植
openEuler上运行apt命令安装时间同步程序LinuxPTP,OpenHarmony没有对应的包管理工具,需要交叉编译后拷贝到飞腾D2000上运行。
以下命令是在openEuler上交叉编译LinuxPTP以运行在OpenHarmony操作系统上:
(a)安装交叉编译器,配置交叉编译环境。
# 交叉编译安装
# 手动编译并安装 musl-cross-make
sudo apt-get install build-essential gcc git
git clone https://github.com/richfelker/musl-cross-make.git
cd musl-cross-make
emacs config.mak.dist
# 写入
TARGET = aarch64-linux-musl
OUTPUT = /opt/cross
mv config.mak.dist config.mak
# 编译安装Make (时间很久)
sudo make install
# 添加环境变量
emacs ~/.bashrc
export PATH=/opt/cross/bin:$PATH
source ~/.bashrc
# 测试
aarch64-linux-musl-gcc --version
(b)将OpenHarmony操作系统中动态链接库文件拷贝到本机中,下载LinuxPTP源码,指定OpenHarmony的动态链接库文件交叉编译。
# 将OpenHarmony分区挂载到磁盘,将其中的/lib/ld-musl-aarch64.so.1拷贝到本机/lib目录下
cp ./lib/ld-musl-aarch64.so.1 /lib
# 下载linuxptp
git clone git://git.code.sf.net/p/linuxptp/code linuxptp
cd linuxptp
mkdir target
# 交叉编译,指定链接文件
make install CROSS_COMPILE=aarch64-linux-musl- LDFLAGS="-Wl,--dynamic-linker=/lib/ld-musl-aarch64.so.1" DESTDIR=target
# 交叉编译,静态链接
make install CROSS_COMPILE=aarch64-linux-musl- LDFLAGS="-static -Wl,--dynamic-linker=/lib/ld-musl-aarch64.so.1" DESTDIR=target
# 移除符号信息
aarch64-linux-musl-strip ./target/usr/local/sbin/*
file ./target/usr/local/sbin/*
# 拷贝到OpenHarmony的/system/bin目录下
cd target/usr/local/sbinsudo
cp * ~/Desktop/sdb/sdb2/system/bin
2.3 TSN端系统2:鲲鹏920服务器 + openEuler
欧拉操作系统在鲲鹏920硬件平台上启动运行见博客网址:https://blog.csdn.net/glf_mp5/article/details/133160741我们使用的鲲鹏920开发板硬件如下图所示。

图7:鲲鹏920主板
在鲲鹏920和飞腾D2000开发板上需要使用tsn_listener和tsn_talker工具进行TSN报文的收发,其工具适配工作流程如下:
(1)tsn-talker/tsn-listener工具移植
(a)github上(https://github.com/Xilinx/tsn-talker-listener)下载源代码,准备交叉编译
(b)进入tsn-talker目录,新建target目录存放编译后的文件
(I) 输入以下命令
make CC=aarch64-linux-musl-gcc LDFLAGS+=”-static -WL”,--dynamic-linker=/lib/ld-musl-aarch64.so.1” DESTDIR=target
# Ld-musl-aarch64.so.1为鸿蒙/lib下的动态库,需要拷贝到本机/lib目录下
(II) 输入以上命令报错,显示缺少argp.h头文件,如图8所示。

图8:错误信息
(c)musl自己不带argp头文件和库文件,可以从aarch64-linux-gnu-gcc的include中拿arpg.h头文件使用,需要一步一步补齐缺失的头文件,也可在使用argp-standalone来补充,我们通过argp-standalone补充arpg.h头文件(第一种方法也可以,不过补齐后重新编译会提示缺少库,还是需要通过argp-standalone补充该库文件),具体命令如下:
wget http://www.lysator.liu.se/~nisse/misc/argp-standalone-1.3.tar.gz
tar xf argp-standalone-1.3.tar.gz
pushd argp-standalone-1.3
CFLAGS="-fPIC -U__OPTIMIZE__" ./configure
Make CC=aarch64-linux-musl-gcc &&make install
install -D -m644 argp.h ${DEBUGROOT}/include/argp.h && install -D -m755 libargp.a ${DEBUGROOT}/lib/libargp.a
# 需要argp.h头文件和libargp.a静态库,安装到指定的目录下
(d)重新编译tsn-talker
修改makefile
INCFLAGS选项添加-I ${DEBUGROOT}/include
LDLIBS选项添加-l ${DEBUGROOT}/lib/libargp.a
输入命令
make CC=aarch64-linux-musl-gcc LDFLAGS+=”-static -WL”,--dynamic-linker=/lib/ld-musl-aarch64.so.1” DESTDIR=target
会在target目录下生成tsn-talker的aarch64架构,静态链接的可执行文件
(e) 将该可执行文件放到OpenHarmony系统的/system/bin目录下
(f)tsn-listener类似
3. 时间同步实现

图9:平台架构图
根据TSN平台架构图,上一部分已完成硬件平台的搭建,通过网线将各个硬件平台链接,之后的软件应用操作将在此平台上运行。
在运行时间同步之前需要对TSN交换机做一些配置(如交换机端口配置,不同网卡端口之间的网桥搭建等),通过串口工具MobaXterm进入TSN交换机的操作系统,配置交换机端口状态如图10所示,为了验证TSN交换机是否正常工作,我们在飞腾D2000端节点向鲲鹏920主节点发送TSN流量,在鲲鹏920上通过Wireshark抓包分析,其抓包结果如图11所示,成功抓到TSN流量,验证TSN交换机正常工作。

图10:xilinx交换机端口状态

图11:Wireshark抓包分析
根据平台架构图,将飞腾D2000端节点与主节点鲲鹏920进行时间同步,确保TSN网络实时通信平台时间基准一致。在以上命令的基础上,在Xilinx交换机增加ptp4l时间同步命令,如图12所示。同时在鲲鹏920和飞腾D2000上运行ptp4l时间同步命令,如图13和14所示,实现整个异构网络实时通信平台下的时间基准一致问题。

图12:TSN交换机命令

图13:鲲鹏920时间同步命令

图14:飞腾D2000时间同步命令
在之前的时间同步命令下,从节点ptp4l时间同步命令增加参数“-m”表示输出时间误差偏移量。如图15所示,在S2稳定状态下,偏移量只有几十纳秒甚至几纳秒。时钟设备初始状态为S0表示未锁定状态,之后逐渐进入到S1状态表示正在同步中,之后进入S2状态表示锁定状态表示从时钟已经成功与主时钟同步。在这个状态下,时钟将不会进行大幅度的时间调整,而是会进行微调,以保持与主时钟的同步。

图15:稳定状态下时间同步精度
4、总结
本文聚焦于TSN网络中的时间同步技术,基于ZYNQ7020 FPGA 开发板(AX7021B)、飞腾D2000及鲲鹏920等硬件,结合国产开源操作系统OpenHarmony和openEuler,成功实现了纳秒级别的高精度时间同步。通过适配I210网卡硬件时间戳功能并运行PTP协议,系统在主从节点间实现了稳定可靠的时间基准同步,为TSN网络的实时通信提供了关键支持,展现了国产技术在时间敏感网络领域的应用潜力。