0. 简介(Introduction)
概述
Holoscan Sensor Bridge 提供了一个基于 FPGA 的接口,用于利用 GPU 进行低延迟的传感器数据处理。外设数据由 Holoscan Sensor Bridge 设备的 FPGA 采集,并通过以太网以 UDP 方式发送至主机系统。在 IGX Devkit 或 DGX Spark 等系统中,ConnectX SmartNIC 接口可以将 UDP 数据直接写入 GPU 显存,从而大幅降低延迟。Holoscan Sensor Bridge 的主机端软件支持将接收到的传感器数据集成到 Holoscan 流水线中;官方提供了基于 Sony IMX274 相机的视频处理与推理示例。该配置可以连接 IGX、Jetson AGX Orin、Jetson AGX Thor 或 DGX Spark 计算系统。此外:
- Holoscan Sensor Bridge 支持带有或不带 RDMA 加速网卡的主机。对于非加速配置(如 Jetson AGX Orin Devkit),则通过基于 Linux socket 的以太网连接提供支持。
- 适当配置的主机系统可以支持高精度 PTP 时间戳;这些时间戳可用于记录数据接收的时间、测量数据与流水线的延迟,以及同步传感器行为。IGX 和 AGX Orin 系统的板载网络接口均具备硬件 PTP 支持。
软件(Software)
Holoscan 应用通过组合一系列算子(operator)来编写。将一个算子的输出连接到另一个算子的输入(通过 add_flow API),即可配置 Holoscan 的流水线,并规定各个算子何时可以运行。
Holoscan Sensor Bridge 的主机端软件借助 Holoscan 框架,提供了用于接收 Holoscan Sensor Bridge 设备所生成网络数据的算子。例如,RoceReceiverOp 提供了从 Holoscan Sensor Bridge 数据源接收 UDP 报文并将数据存入 GPU 显存的能力。当与视频相机源配合使用时,接收到的数据呈现为一块包含 CSI-2 Bayer 图像数据的内存。Holoscan 内置了开箱即用的算子,用于:
- 从 Bayer 视频构建 RGBA 图像
- 图像信号处理(ISP)
- 推理
- 可视化,以及
- 数据完整性测试
这些工具都旨在简化视频数据的实时处理。更多细节请参见 IMX274 demo。
不同应用对接收数据有不同的用途。例如,高速模拟信号(如 5G 蜂窝天线)的需求与视频相机不同。一般而言,应用代码通过传感器对象上的 API 为该设备提供合适的配置与控制;传感器对象知道如何按需配置网络接收算子。如果某个应用或设备的需求超出了当前实现的能力,Holoscan 算子是以源代码形式提供的:用户可以修改这些代码以满足自身需求,并且如果愿意,还可以将这些修改发回给 NVIDIA,以便纳入传感器桥接主机软件的未来版本。
应用(Applications)
Holoscan 应用的工作方式是:创建一个 HoloscanApplication 子类,重写其 configure 方法,并用它来构建适合该应用的流水线。Holoscan Sensor Bridge 的应用流水线通常专注于:从传感器设备采集数据、对数据进行处理、生成合适的输出,并将输出数据发送到合适的目标。
传感器对象(Sensor objects)
用于配置和监控特定传感器的 API 呈现在传感器对象 上。例如,Imx274Cam 就是一个传感器对象,提供初始化时配置、运行时参数更新(如曝光)以及设备健康监控等方法。Holoscan 应用使用这些 API 来影响设备行为:例如,一个"自动曝光算子"可以接收视频帧作为输入,并据此确定发送给相机 set_exposure 方法的数值。传感器对象是针对特定设备的用户态驱动:它们提供对设备功能的访问,但不包含任何特定于应用的行为。
主机要求(Host requirements)
Holoscan Sensor Bridge 软件可以运行在任何受 NVIDIA Holoscan 支持的系统上。为获得最佳性能,推荐使用配备 ConnectX SmartNIC 的 IGX 系统。在没有 ConnectX 网卡的系统中(如 Jetson AGX Orin),性能会受限于主机操作系统的网络协议栈。
本页是 Getting Started 的引言部分,核心要点是:Sensor Bridge 的数据通路为「传感器 → FPGA → UDP/以太网 → (可选 ConnectX RDMA 直写 GPU 显存)→ Holoscan 算子流水线」,并且软硬件都支持在有/无 RDMA 网卡两种主机形态下工作。
1. 硬件设置(Hardware Setup)
本页介绍 Holoscan Sensor Bridge 官方内置支持的开发套件的设备设置方法。完整的合作伙伴产品列表,请访问 Holoscan Sensor Bridge 主页。许多厂商维护自己的 FPGA、MCU 与传感器模组的 Holoscan Sensor Bridge 移植版本,使用其产品时请直接联系相应厂商获取说明。
目前覆盖以下四种设备:
- Lattice CPNX100-ETH-SENSOR-BRIDGE
- Microchip MPF200-ETH-SENSOR-BRIDGE
- Leopard imaging VB1940 Eagle 相机
- TauroTech DA326
1.1 Lattice CPNX100-ETH-SENSOR-BRIDGE
Holoscan Sensor Bridge 板卡
【图:Holoscan sensor bridge 板卡(Lattice Bajoran Board 正面)】
Lattice CPNX100-ETH-SENSOR-BRIDGE 具有如下连接器:
- SFP+ 端口 ------ 两个 10Gbps 以太网端口,用于连接主机系统。
- 相机连接器 ------ 用于连接相机(例如 IMX274)。
- 电源端口 ------ 传感器桥设备通过 USB-C 电源供电,输入电压范围为 5V 至 20V。由于传感器经由传感器桥板供电,建议使用专用电源同时为板卡和传感器供电。
- GPIO 引脚 ------ 传感器桥设备支持 16 个 GPIO 引脚(0...15)和 4 个接地引脚(上图中标记为 "G")。
注意:传感器桥设备不提供 USB 主机接口------USB-C 接口仅用于供电。与主机的所有交互均通过以太网端口进行。
Holoscan sensor bridge 的参考应用目前使用 IMX274 双摄像头模组:
【图:IMX274 双摄像头模组】
摄像头模组按下图所示方式安装到传感器桥设备上:
【图:传感器桥设备与相机的安装方式】
将 Holoscan sensor bridge 连接到主机
- 确保 Holoscan sensor bridge 板卡处于断电状态。
- 按上图所示,将摄像头模组装入相机连接器。
- 将下图中标记为 "SFP+ 0" 的 SFP+ 端口连接到主机系统。这是访问立体相机对中第一路相机的正确连接方式,该端口提供对图中 "Camera 0" 所示相机数据的访问。
【图:传感器桥相机配置(SFP+ 0 位置)】
- 对于 IGX Devkit,连接到下图中红色箭头标注的 QSFP 端口。
【图:IGX 背板】
对于使用立体相机对中第二路相机的配置,将标记为 "SFP+ 1" 的 SFP 端口连接到 IGX 背面尚未使用的另一个 QSFP 端口。
- 对于 DGX Spark,将 HSB 上的 "SFP+ 0" 端口连接到下图所示的 "CX7 QSFP port 0"。使用立体相机对中第二路相机的配置,则将 HSB 上的 "SFP+ 1" 端口连接到 "CX7 QSFP port 1"。
【图:DGX Spark CX7 QSFP 端口】
- 对于 AGX Orin Devkit,连接到 10G 以太网端口(下图中标记为 "H")。
【图:Jetson AGX Orin 端口】
- 将最低规格为 12V/2A 的 USB-C 电源接到传感器桥设备的 USB-C 电源连接器上,等待传感器桥板上的绿色 LED 亮起。
- 更多细节请参阅 Lattice CPNX100-ETH-SENSOR-BRIDGE 官方页面。
随后请按照「主机设置」一章的说明配置你的主机系统。
1.2 Microchip MPF200-ETH-SENSOR-BRIDGE
以下说明介绍如何设置 Microchip MPF200-ETH-SENSOR-BRIDGE 设备,并将其连接到 IGX 与 Jetson AGX Orin 开发套件。
Holoscan Sensor Bridge 板卡
【图:Microchip 传感器桥板卡】
Microchip MPF200-ETH-SENSOR-BRIDGE 具有如下连接器:
- SFP+ 端口 ------ 两个 10Gbps 以太网端口,用于连接主机系统。
- 相机连接器 ------ 用于连接相机(例如 IMX477)。
- 电源开关 ------ 传感器桥设备通过连接到该端口的 12V 电源供电,电源最低规格为 12V/2A。
Microchip MPF200-ETH-SENSOR-BRIDGE 的参考应用目前使用 IMX477 相机模组:
【图:IMX477 相机模组】
摄像头模组按下图所示方式安装到传感器桥设备上:
【图:传感器桥设备与 IMX477 的连接方式】
将 Holoscan sensor bridge 连接到主机
- 如上图所示,将 SFP+ 端口连接到主机系统。
- 对于 AGX Orin Devkit,连接到 10G 以太网端口(下图中标记为 "H")。
【图:Jetson AGX Orin 端口】
- 使用电源开关给板卡上电。
- 更多细节请参阅 Microchip MPF200-ETH-SENSOR-BRIDGE 官方页面。
随后请按照「主机设置」一章的说明配置你的主机系统。
1.3 Leopard imaging VB1940 Eagle 相机
以下说明介绍如何设置 VB1940 Eagle 相机,并将其直接连接到 IGX 与 Jetson AGX Orin 开发套件。
Leopard imaging VB1940 Eagle 相机
Leopard imaging VB1940 Eagle 相机是一款以太网供电(POE)相机,无需传感器桥设备即可直接连接开发套件。其特点包括:
- 直连以太网 ------ 使用 CAT-6 网线直接连接主机系统
- 工业级设计 ------ 面向工业、机器人与医疗应用
- 紧凑设计 ------ 不需要额外的桥接硬件
【图:LI VB1940 Eagle 相机】
将 VB1940 Eagle 相机连接到主机
请确保你的 VB1940 已刷写最新固件,详见「Holoscan Sensor Bridge FPGA 固件更新」页面。
- 用以太网线将 VB1940 Eagle 相机连接到开发套件上一个可用的以太网端口。
- 对于 IGX Devkit,使用 QSFP 转接器连接到背板上红色箭头标注的 QSFP 以太网端口。
【图:IGX 背板】
- 对于 AGX Orin Devkit,连接到 10G 以太网端口(下图中标记为 "H")。
【图:Jetson AGX Orin 端口】
- 确保 VB1940 Eagle 相机已上电。
- 运行
ping 192.168.0.2验证连通性。 - 更多细节请参阅 Leopard imaging Eagle 相机文档。
随后请按照「主机设置」一章的说明配置你的主机系统。
1.4 TauroTech DA326
【图:TauroTech DA326 传感器桥板卡】
与 Lattice、Microchip 的传感器桥板卡(相机传感器直接接在 MIPI CSI-2 连接器上)不同,TauroTech DA326 桥接的是 GMSL 相机模组:传感器模组通过 GMSL 链路连接到板卡,板载的 MAX96716A 解串器(deserializer)将 GMSL 流转换为 MIPI CSI-2 信号送给 FPGA。
TauroTech DA326 具有如下连接器:
- SFP+ 端口 ------ 一个 10Gbps 以太网端口,用于连接主机系统。
- GMSL 相机连接器 ------ 用于相机输入的 GMSL 接口。
- 电源端口 ------ 传感器桥设备由专用电源供电;板卡还通过同轴连接器为所连接的相机模组供电。
DA326 上的 Holoscan sensor bridge 参考应用使用 Hawk 相机模组:
【图:Hawk 相机模组】
一个 Hawk 模组由两个传感器(AR0234)和一个串行器(MAX9295D)组成。
将 TauroTech DA326 连接到主机
-
确保 DA326 板卡处于断电状态。
-
使用同轴线缆将 Hawk 相机模组接到 DA326 的 GMSL 连接器上。
-
将 DA326 的 SFP+ 端口连接到主机系统。
-
对于 IGX Devkit,使用 QSFP 转接器连接到背板上红色箭头标注的 QSFP 以太网端口。
【图:IGX 背板】
-
对于 AGX Orin Devkit,在 Tauro Tech DA326 的 SFP 笼中安装一个 10GBASE-T SFP PHY,以连接到 10G 以太网端口(下图中标记为 "H")。
【图:Jetson AGX Orin 端口】
-
对于 AGX Thor Devkit,使用 QSFP 转接器连接到 QSFP 端口(下图中标记为 "6")。
【图:Jetson AGX Thor 端口】
-
给 DA326 板卡上电,等待板卡状态 LED 指示就绪。
-
运行
ping 192.168.0.2验证连通性。
关于参考传感器模组的更多细节,请参阅 Leopard imaging Hawk 相机文档;关于上述串行器与解串器的更多细节,请参阅 Analog Devices 文档;关于 TauroTech DA326 板卡的更多细节,请参阅 Tauro Technologies 文档。
随后请按照「主机设置」一章的说明配置你的主机系统。
2. 主机设置(Host Setup)
Holoscan sensor bridge 支持以下配置:
- 配置有 IGX OS 1.1.2+ 并配备 CX7 SmartNIC 设备的 IGX 系统。
- 运行 JP6.2.1+ 的 AGX Orin 系统。该配置下,板载以太网控制器配合 Linux 内核网络协议栈进行数据 I/O;所有网络 I/O 均由 CPU 完成,没有网络加速。
- 运行 JP7.2、配备 MGBE SmartNIC 设备并使用 CoE 传输的 AGX Thor 系统。
- 运行 DGX OS 7.2.3+ 并配备 CX7 SmartNIC 设备的 DGX Spark 系统。
- 配备 NVIDIA 独立显卡的 x86 Linux 工作站。支持两条主机接收路径:非加速的基于 Linux socket 的接收器(主要用于开发或测试),以及加速的 RoCE 路径(要求通往传感器桥的链路上有 ConnectX 网卡)。注意:该配置不属于主要参考平台;即使 GPU 与驱动显示 GPUDirect RDMA 可用,主机的 PCIe 路径也可能并不真正支持它------此时必须在构建时禁用 GPU VRAM 帧缓冲(见下文 x86 Linux 一节)。
在 Holoscan sensor bridge 板卡设置完成之后,需要在主机系统中配置若干前提条件。虽然 holoscan sensor bridge 的演示应用通常在容器中运行,但以下命令全部要在容器之外、直接在主机系统上执行。这些配置在重启后依然保留,因此只需设置一次。
-
安装 git-lfs
Holoscan sensor bridge 源码仓库中的部分数据文件使用 GIT LFS。
bashsudo apt-get update sudo apt-get install -y git-lfs -
授予你的用户访问 docker 子系统的权限:
bashsudo usermod -aG docker $USER重启计算机以使该设置生效。
接下来,根据你的主机类型,按照下面相应小节的指引进行配置。
2.1 IGX
-
运行以下命令,将 GPU 驱动更新到 535.309.01 并安装 IGX 1.1.3:
bashsudo tee /etc/apt/preferences.d/nvidia-driver-pin >/dev/null <<'EOF' Package: nvidia-* libnvidia-* Pin: version 535.309.01* Pin-Priority: 1001 EOF sudo apt-get purge "nvidia-kernel-*" sudo apt-get update && sudo apt-get install -y nvidia-driver-535-open=535.309.01-0ubuntu0.22.04.1 sudo apt dist-upgrade重启机器以加载新驱动:
bashsudo reboot重启后,确认新驱动已生效:
none➜ nvidia-smi +---------------------------------------------------------------------------------------+ | NVIDIA-SMI 535.309.01 Driver Version: 535.309.01 CUDA Version: 12.2 | |-----------------------------------------+----------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 NVIDIA RTX 6000 Ada Gene... Off | 00000005:09:00.0 Off | Off | | 30% 34C P8 20W / 300W | 189MiB / 49140MiB | 0% Default | | | | N/A | +---------------------------------------------------------------------------------------+ -
确定与第一个 CX7 端口关联的网络设备名称。从 IGX 机箱背面看,这是最右侧的 QSFP 端口。
【图:IGX QSFP0】
bashls /sys/class/infinibandnoneroceP5p3s0f0 roceP5p3s0f1该命令会列出所有 CX7 端口;你的设备名称可能不同。编号最小的一个(本例中为
roceP5p3s0f0)就是第一个 CX7 端口。使用上面命令输出的、你机器上实际出现的设备名之一,检查 CX7 固件版本:
bashcat /sys/class/infiniband/roceP5p3s0f0/fw_vernone28.39.3004如果版本低于或等于 28.38.1026,请从 IGX 下载页面下载相应的 "ConnectX-7 Firmware" ISO 并升级 CX7 固件。升级后务必重启机器,并重新检查确认固件已加载为新版本。
将第一个 CX7 端口的名称赋给变量
$IN0:bashLC_COLLATE=C IN=(/sys/class/infiniband/*) IN0=`basename ${IN[0]}` echo $IN0noneroceP5p3s0f0接下来,确定与该设备关联的主机以太网端口,并将其赋给变量
$EN0,稍后的网络配置会用到它:bashEN0=`basename /sys/class/infiniband/$IN0/device/net/*` echo $EN0noneenP5p3s0f0np0小结:与
$IN0(roceP5p3s0f0)关联的主机网络接口是$EN0(enP5p3s0f0np0);你的具体设备名称可能不同。 -
IGX OS 使用 NetworkManager 配置网络接口。默认情况下,传感器桥设备的第一个端口使用地址 192.168.0.2。将第一个以太网设备(
$EN0)配置为使用地址 192.168.0.101,并添加到 192.168.0.2 的永久路由,MTU 使用 RoCE 推荐值(如果你的系统无法以这种方式使用 192.168.0.0/24 网段,请参阅文档 support/notes 中的 IP 地址配置说明):bashsudo nmcli con add con-name hololink-$EN0 ifname $EN0 type ethernet ip4 192.168.0.101/24 sudo nmcli connection modify hololink-$EN0 +ipv4.routes 192.168.0.2/32 sudo nmcli connection modify hololink-$EN0 ethtool.ring-rx 4096 sudo nmcli connection modify hololink-$EN0 802-3-ethernet.mtu 4200 sudo nmcli connection up hololink-$EN0给传感器桥设备上电,确认其连接正确,然后执行
ping 192.168.0.2检查连通性:noneping 192.168.0.2 PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data. 64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.225 ms 64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.081 ms 64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.088 ms 64 bytes from 192.168.0.2: icmp_seq=4 ttl=64 time=0.132 ms ^C --- 192.168.0.2 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3057ms rtt min/avg/max/mdev = 0.081/0.131/0.225/0.057 ms -
传感器桥设备上的第二个 SFP+ 连接器用于传输立体相机模组(如 IMX274)第二路相机采集的数据。默认情况下,传感器桥设备的第二个端口使用地址 192.168.0.3。将第二个 IGX QSFP 端口(下图中红色箭头所示)连接到传感器桥设备的第二个 SFP+ 端口。
【图:IGX QSFP1】
我们将它们记作
$IN1和$EN1。沿用前面赋值$IN0和$EN0的命令:bashIN1=`basename ${IN[1]}` echo $IN1 EN1=`basename /sys/class/infiniband/$IN1/device/net/*` echo $EN1noneroceP5p3s0f1 enP5p3s0f1np1同上,你的设备名称可能不同。为第二个 QSFP 网络端口配置合适的地址和永久路由:
bashsudo nmcli con add con-name hololink-$EN1 ifname $EN1 type ethernet ip4 192.168.0.102/24 sudo nmcli connection modify hololink-$EN1 +ipv4.routes 192.168.0.3/32 sudo nmcli connection modify hololink-$EN1 ethtool.ring-rx 4096 sudo nmcli connection modify hololink-$EN1 802-3-ethernet.mtu 4200 sudo nmcli connection up hololink-$EN1现在用
ping 192.168.0.3测试第二条连接:noneping 192.168.0.3 PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data. 64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.210 ms 64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.271 ms 64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.181 ms 64 bytes from 192.168.0.3: icmp_seq=4 ttl=64 time=0.310 ms 64 bytes from 192.168.0.3: icmp_seq=5 ttl=64 time=0.258 ms ^C --- 192.168.0.3 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4102ms rtt min/avg/max/mdev = 0.181/0.246/0.310/0.045 ms第二个端口配置完成后,第一个端口应仍能正常响应 ping。
2.2 AGX Orin
本软件包中的演示与示例假定传感器桥设备连接到 eno1,即 AGX Orin 上的 RJ45 连接器。
-
在板载网络端口上配置静态 IP 地址 192.168.0.101。
L4T 使用 NetworkManager 配置接口;默认情况下接口被配置为 DHCP 客户端。使用以下命令将 IP 地址更新为 192.168.0.101。(如果你的系统无法以这种方式使用 192.168.0.0/24 网段,请参阅文档 support/notes 中的 IP 地址配置说明。)
注意:运行 JP6.2.1 的 AGX 上,板载以太网设备为
eno1;JP7.2 上则为end0。如果你运行的是其他配置,请为变量 EN0 使用相应的名称:bashEN0=end0 sudo nmcli con add con-name hololink-$EN0 ifname $EN0 type ethernet ip4 192.168.0.101/24 sudo nmcli connection up hololink-$EN0给传感器桥设备上电,确认其连接正确,然后执行
ping 192.168.0.2检查连通性。 -
对于基于 Linux socket 的示例,建议将一个处理器核心从 Linux 内核调度中隔离出来。对于高带宽应用(例如 4K 视频采集),隔离网络接收核心是必需的。当示例程序以处理器亲和性绑定到该隔离核心运行时,性能会提升、延迟会降低。默认情况下,sensor bridge 软件将时间关键的后台网络接收进程运行在第三个处理器核心上。如果该核心被从 Linux 调度中隔离,那么除非用户显式请求,否则不会有任何进程被调度到该核心上,可靠性与性能都会大幅提升。
隔离该核心的方法是编辑
/boot/extlinux/extlinux.conf:在以APPEND开头的那一行末尾添加isolcpus=2。修改后文件大致如下:noneTIMEOUT 30 DEFAULT primary MENU TITLE L4T boot options LABEL primary MENU LABEL primary kernel LINUX /boot/Image ... APPEND ${cbootargs} ...<other-settings>... isolcpus=2Sensor bridge 应用也可以通过将环境变量
HOLOLINK_AFFINITY设置为某个核心号,让网络接收进程运行在其他核心上。例如,运行在第一个处理器核心上:bashHOLOLINK_AFFINITY=0 python3 examples/linux_imx274_player.py将
HOLOLINK_AFFINITY设置为空则会跳过 sensor bridge 代码中的所有核心亲和性设置。 -
在开机时运行 "jetson_clocks" 工具,将各核心时钟设为最大值:
bashJETSON_CLOCKS_SERVICE=/etc/systemd/system/jetson_clocks.service cat <<EOF | sudo tee $JETSON_CLOCKS_SERVICE >/dev/null [Unit] Description=Jetson Clocks Startup After=nvpmodel.service [Service] Type=oneshot ExecStart=/usr/bin/jetson_clocks [Install] WantedBy=multi-user.target EOF sudo chmod u+x $JETSON_CLOCKS_SERVICE sudo systemctl enable jetson_clocks.service -
将 AGX Orin 的电源模式设置为 "MAXN" 以获得最佳性能。该设置可通过屏幕左上角的 L4T 电源下拉菜单更改:
【图:AGX Orin MAXN】
-
重启 AGX Orin,使核心隔离与性能设置生效。如果配置 "MAXN" 性能模式时没有提示你重启设备,请手动执行重启命令:
bashreboot
2.3 DGX Spark
-
首先检查是否存在 OTA 的 ConnectX-7 热插拔(hotplug)特性,如果存在则将其禁用并重启。该特性会在未检测到链路时关闭网卡,可能干扰本指南的操作与 HSB 的正常工作。注意:如果你的网卡在未接任何设备时断电,但下列文件并不存在,说明你可能没有禁用它的能力,应当更新 OTA。
bashif [ -f /etc/nvidia/cx7-hotplug-enabled ] ; then sudo mv /etc/nvidia/cx7-hotplug-enabled /etc/nvidia/cx7-hotplug-disabled sudo reboot fi -
确定与第一个 CX7 端口关联的网络设备名称。从 DGX Spark 机箱背面看,这是最左侧的 QSFP 端口(下图中的 "port 0")。注意:下面
echo输出的具体设备名称可能因不同系统的驱动配置而不同或发生变化。【图:DGX Spark CX7 QSFP 端口】
bashls /sys/class/infinibandnoneroceP2p1s0f0 roceP2p1s0f1 rocep1s0f0 rocep1s0f1该命令会列出连接到 CX7 端口的 InfiniBand 设备;你的设备名称可能不同。编号最小的一个(本例中为
roceP2p1s0f0)就是第一个 CX7 端口。将该名称赋给变量$IN0:bashLC_COLLATE=C IN=(/sys/class/infiniband/*) IN0=`basename ${IN[0]}` echo $IN0noneroceP2p1s0f0接下来,确定与该设备关联的主机以太网端口,并将其赋给变量
$EN0,稍后的网络配置会用到它:bashEN0=`basename /sys/class/infiniband/$IN0/device/net/*` echo $EN0noneenP2p1s0f0np0小结:与
$IN0(roceP2p1s0f0)关联的主机网络接口是$EN0(enP2p1s0f0np0);你的具体设备名称可能不同。 -
DGX OS 使用 NetworkManager 配置网络接口。默认情况下,传感器桥设备的第一个端口使用地址 192.168.0.2。将第一个以太网设备(
$EN0)配置为使用地址 192.168.0.101,并添加到 192.168.0.2 的永久路由,MTU 使用 RoCE 推荐值:bashsudo nmcli con add con-name hololink-$EN0 ifname $EN0 type ethernet ip4 192.168.0.101/24 sudo nmcli connection modify hololink-$EN0 +ipv4.routes 192.168.0.2/32 sudo nmcli connection modify hololink-$EN0 ethtool.ring-rx 4096 sudo nmcli connection modify hololink-$EN0 802-3-ethernet.mtu 4200 sudo nmcli connection up hololink-$EN0给传感器桥设备上电,确认其连接正确,然后执行
ping 192.168.0.2检查连通性:noneping 192.168.0.2 PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data. 64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.225 ms 64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.081 ms 64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.088 ms 64 bytes from 192.168.0.2: icmp_seq=4 ttl=64 time=0.132 ms ^C --- 192.168.0.2 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3057ms rtt min/avg/max/mdev = 0.081/0.131/0.225/0.057 ms -
传感器桥设备上的第二个 SFP+ 连接器用于传输立体相机模组(如 IMX274)第二路相机采集的数据。默认情况下,传感器桥设备的第二个端口使用地址 192.168.0.3。将第二个 DGX Spark QSFP 端口(上图中的 "port 1")连接到传感器桥设备的第二个 SFP+ 端口。
我们将它们记作
$IN1和$EN1。沿用前面赋值$IN0和$EN0的命令:bashIN1=`basename ${IN[1]}` echo $IN1 EN1=`basename /sys/class/infiniband/$IN1/device/net/*` echo $EN1noneroceP2p1s0f1 enP2p1s0f1np1同上,你的设备名称可能不同。为第二个 QSFP 网络端口配置合适的地址和永久路由:
bashsudo nmcli con add con-name hololink-$EN1 ifname $EN1 type ethernet ip4 192.168.0.102/24 sudo nmcli connection modify hololink-$EN1 +ipv4.routes 192.168.0.3/32 sudo nmcli connection modify hololink-$EN1 ethtool.ring-rx 4096 sudo nmcli connection modify hololink-$EN1 802-3-ethernet.mtu 4200 sudo nmcli connection up hololink-$EN1现在用
ping 192.168.0.3测试第二条连接:noneping 192.168.0.3 PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data. 64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.210 ms 64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.271 ms 64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.181 ms 64 bytes from 192.168.0.3: icmp_seq=4 ttl=64 time=0.310 ms 64 bytes from 192.168.0.3: icmp_seq=5 ttl=64 time=0.258 ms ^C --- 192.168.0.3 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4102ms rtt min/avg/max/mdev = 0.181/0.246/0.310/0.045 ms第二个端口配置完成后,第一个端口应仍能正常响应 ping。
2.4 AGX Thor
-
在 Thor Devkit 上安装 JP 7.2 之后,完成以下步骤。
如果是使用 ISO 方式安装的,请安装 CUDA Toolkit 13.2 并执行:
bashexport PATH=/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH wget https://developer.nvidia.com/downloads/embedded/L4T/r39_Release_v2.0/release/Jetson_SIPL_API_R39.2.0_aarch64.tbz2 wget https://developer.nvidia.com/downloads/embedded/L4T/r39_Release_v2.0/release/Jetson_Multimedia_API_R39.2.0_aarch64.tbz2 sudo tar xjf Jetson_SIPL_API_R39.2.0_aarch64.tbz2 -C / sudo tar xjf Jetson_Multimedia_API_R39.2.0_aarch64.tbz2 -C / -
对于基于 Linux socket 的示例,建议将一个处理器核心从 Linux 内核调度中隔离出来。对于高带宽应用(例如 4K 视频采集),隔离网络接收核心是必需的。当示例程序以处理器亲和性绑定到该隔离核心运行时,性能会提升、延迟会降低。默认情况下,sensor bridge 软件将时间关键的后台网络接收进程运行在第三个处理器核心上。如果该核心被从 Linux 调度中隔离,那么除非用户显式请求,否则不会有任何进程被调度到该核心上,可靠性与性能都会大幅提升。
隔离该核心的方法是编辑
/boot/extlinux/extlinux.conf:在以APPEND开头的那一行末尾添加isolcpus=2。修改后文件大致如下:noneTIMEOUT 30 DEFAULT primary MENU TITLE L4T boot options LABEL primary MENU LABEL primary kernel LINUX /boot/Image ... APPEND ${cbootargs} ...<other-settings>... isolcpus=2Sensor bridge 应用也可以通过将环境变量
HOLOLINK_AFFINITY设置为某个核心号,让网络接收进程运行在其他核心上。例如,运行在第一个处理器核心上:bashHOLOLINK_AFFINITY=0 python3 examples/linux_imx274_player.py将
HOLOLINK_AFFINITY设置为空则会跳过 sensor bridge 代码中的所有核心亲和性设置。此步骤需要重启系统才能生效。
-
安装 Holoscan SDK v4.4.0:
bashsudo apt update sudo apt install holoscan-cuda-13=4.4* -
安装其他 Holoscan sensor bridge 依赖:
bash. /etc/os-release UBUNTU_VERSION="`echo ${VERSION_ID} | sed 's/\.//g'`" sudo apt-get install ca-certificates gpg wget wget https://developer.download.nvidia.com/compute/nvcomp/5.2.0/local_installers/nvcomp-local-repo-ubuntu${UBUNTU_VERSION}-5.2.0_5.2.0-1_arm64.deb sudo dpkg -i nvcomp-local-repo-ubuntu${UBUNTU_VERSION}-5.2.0_5.2.0-1_arm64.deb sudo cp /var/nvcomp-local-repo-ubuntu${UBUNTU_VERSION}-5.2.0/nvcomp-*-keyring.gpg /usr/share/keyrings/ rm nvcomp-local-repo-ubuntu${UBUNTU_VERSION}-5.2.0_5.2.0-1_arm64.deb test -f /usr/share/doc/kitware-archive-keyring/copyright || wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null echo "deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ ${VERSION_CODENAME} main" | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null sudo apt-get update test -f /usr/share/doc/kitware-archive-keyring/copyright || sudo rm /usr/share/keyrings/kitware-archive-keyring.gpg sudo apt-get install kitware-archive-keyring sudo apt-get update sudo apt install -y cmake=3.31.11* cmake-data=3.31.11* libfmt-dev libssl-dev libcurlpp-dev libyaml-cpp-dev python3-dev nvcomp-cuda-13 -
启用网络接口并确保相机可被枚举到(假定相机 IP 地址为 192.168.0.2):
bashEN0=mgbe0_0 sudo nmcli con add con-name hololink-$EN0 ifname $EN0 type ethernet ip4 192.168.0.101/24 sudo nmcli connection modify hololink-$EN0 +ipv4.routes 192.168.0.2/32 sudo nmcli connection up hololink-$EN0 -
获取并构建 holoscan sensor bridge:
holoscan sensor bridge v2.6 版本支持在终端命令行直接运行基于 C++ Li VB1940 加速网络的示例,也支持在 holoscan sensor bridge 容器内运行 Li VB1940 与 IMX274 的 Python 示例。
第一步,克隆 holoscan sensor bridge 仓库:
bashgit clone https://github.com/nvidia-holoscan/holoscan-sensor-bridge.git要在终端命令行运行基于 SIPL 的 C++ Li VB1940 加速网络示例,使用以下命令:
bashcd holoscan-sensor-bridge mkdir build && cd build cmake -DHOLOLINK_BUILD_SIPL=1 -DHOLOLINK_BUILD_FUSA=1 -DHOLOLINK_BUILD_ROCE=0 .. make -j
运行 CoE 加速示例
Holoscan Sensor Bridge 可以通过下面列出的两条不同路径之一,利用 Thor 的硬件加速 CoE 能力。
SIPL
SIPL 是一个模块化、可扩展的图像传感器控制与图像处理框架,它开放了 Thor 的全部硬件能力,包括 CoE 与 ISP 硬件加速。支持 SIPL 的传感器驱动使用统一设备驱动框架(UDDF)编写,JetPack 7.2 已附带 VB1940 的参考 UDDF 驱动。
按以下步骤运行基于 SIPL 的 VB1940 传感器 CoE 示例应用:
-
获取你相机的 MAC ID:
bash./tools/enumerate/hololink-enumerate示例输出:
nonemac_id=8C:1F:64:6D:70:03 hsb_ip_version=0x2510 fpga_crc=0xffff ip_address=192.168.0.2 fpga_uuid=f1627640-b4dc-48af-a360-c55b09b3d230 serial_number=ffffffffffffff interface=mgbe0_0 board=Leopard Eagle -
更新下列配置文件中的
ip_address与mac_address字段(每个文件中有多处):注意: 随附的 JSON
sipl_config文件与 JP7.2 兼容。对于 JP7.1,请从 HSB 2.5.0 发布版本中拉取源文件并做必要修改。none../examples/sipl_config/vb1940_single.json ../examples/sipl_config/vb1940_dual.json -
允许 root 访问 X 显示(如果使用 SSH,请确保已设置
DISPLAY):bashxhost + -
运行
sipl_player应用(硬件 ISP 采集模式):bash./examples/sipl_player --json-config ../examples/sipl_config/vb1940_single.json ./examples/sipl_player --json-config ../examples/sipl_config/vb1940_dual.json -
RAW 采集模式(未经适当 ISP 处理时图像质量较差):
bash./examples/sipl_player --json-config ../examples/sipl_config/vb1940_single.json --raw ./examples/sipl_player --json-config ../examples/sipl_config/vb1940_dual.json --raw
FuSa
FuSa 是 JetPack 7.1+ 引入的新 API,它开放了对 Thor CoE 数据捕获路径的访问,但不提供 SIPL 所具备的额外相机控制与 ISP 访问能力。这使得应用可以在 CoE 加速环境中直接控制 Holoscan Sensor Bridge 及其连接的传感器,绕开对 SIPL 及其 UDDF 驱动实现的需求。这样应用就可以遵循更传统的 Holoscan Sensor Bridge 实现方式------传感器控制由应用直接管理,而不是由外部驱动管理。正因如此,基于 Holoscan Sensor Bridge 提供的现有参考驱动,IMX274、VB1940 与 TauroTech DA326 Hawk 传感器都有相应的 FuSa 示例应用。
针对 IMX274、VB1940 与 TauroTech DA326 Hawk,随附了若干以 fusa_coe_ 为前缀的 FuSa 示例应用(Hawk 变体:fusa_coe_max96716a_player、fusa_coe_hawk_single_link_player、fusa_coe_hawk_dual_link_player、fusa_coe_single_network_stereo_hawk_player)。C++ 示例应用可以原生运行(不使用容器),由上面的主机设置步骤完成构建;Python 变体则必须在 Holoscan Sensor Bridge 容器中运行。
注意: 默认情况下,python/setup.py 不会启用所需的 FuSa 或 SIPL 组件,除非它检测到必需的 /dev/coe* 设备,或设置了 COE_OFFLOAD 环境变量。在官方提供的 docker 容器中,或在受支持平台上的原生 Python 绑定构建中,均无需额外操作。
例如,运行 C++ VB1940 播放器示例时,执行以下命令(将 IP 地址替换为你的设备地址):
bash
./examples/fusa_coe_vb1940_player --hololink 192.168.0.2
- 在 holoscan sensor bridge 容器内构建并运行 Li VB1940、IMX274 与 TauroTech DA326 Hawk 的 Python 示例,将在用户指南后续页面中讲解。
2.5 x86 Linux
当主机是运行 Linux、配备 NVIDIA 独立显卡的 x86 PC 时,使用本节内容。
x86 上的捕获路径
-
基于 socket 的接收器 ------ 名称以
linux_开头的示例(例如linux_imx274_player)使用的标准 Linux 网络协议栈路径。它不需要 ConnectX 网卡;使用任何能到达传感器桥的以太网接口即可,IP 与 PTP 配置指引与其他主机相同。注意:此路径没有加速,往往无法跟上典型传感器(如相机)数据流所需的数据速率,会导致间歇性数据丢失。该路径主要用于开发目的。 -
RoCE 加速接收器 ------ 使用 RDMA over Converged Ethernet 连接传感器桥,要求该链路上有 Mellanox/NVIDIA ConnectX 网卡。接口设置要求(地址、路由、环形缓冲区、MTU)与 IGX 或 DGX Spark 一致:传感器桥必须能通过其分配的地址(如
192.168.0.2)到达,配置方案与上面 IGX 或 DGX Spark 小节相同(请将$IN0、$EN0等设备名适配到你的系统)。
RoCE 路径上的 GPUDirect RDMA
使用 RoCE 并通过 GPUDirect RDMA 写入 GPU 显存需要满足以下条件:
- 工作站级 NVIDIA GPU(消费级与移动版 GPU 不支持 GPUDirect RDMA)。
- 主机上安装 NVIDIA 开放内核驱动包(例如
nvidia-driver-open)。 - ConnectX 网卡与 GPU 在 PCIe 拓扑中互为对等体(peer),使网卡能够直接对 GPU 执行 RDMA(平台固件、root port 布局与 IOMMU 设置必须允许端到端完成此操作)。
满足这些要求后,帧缓冲可以驻留在 GPU 显存中,从传感器桥接收的数据可以通过 RDMA 直接写入 GPU 显存。当 GPU 与驱动支持 GPUDirect 注册、但主机 PCIe 系统路径实际上无法将 RDMA 写操作送达该显存时,从传感器桥接收的数据实际上不会写入 GPU 显存,通常会导致数据错误(例如黑屏/空白图像帧)和/或元数据不匹配错误。如果是这种情况,必须将构建配置为强制使用锁页(pinned)主机内存(见下一节)。
x86 上的演示容器
在主机上安装 Docker、Docker Buildx 与 NVIDIA Container Toolkit。使用 dGPU 选项构建演示镜像(见「构建」一章):
bash
sh docker/build.sh --dgpu
当 GPUDirect RDMA 无法端到端工作时
可能出现 RoCE RDMA 看似正常、但对已注册 GPU 显存的 RDMA 写操作实际并未成功的情况------例如 GPU 支持 GPUDirect,但 PCIe 配置不允许 ConnectX 网卡作为 RDMA 对等体到达 GPU。其症状包括黑屏或空白图像,以及应用日志中出现类似如下的行:
none
ERROR 6.6634 roce_receiver.cpp:826 get_next_frame tid=0x61 -- Metadata psn=0 but received_psn=483318.
这是需要禁用 GPU VRAM 重新构建的强信号,重建后 RoCE 接收器将改用锁页主机内存:
-
演示容器: 向
docker/build.sh传入--disable-roce-gpu-vram(与往常一样同时带上--dgpu)来构建镜像。例如:bashsh docker/build.sh --dgpu --disable-roce-gpu-vram -
原生 CMake 构建: 配置时加上:
bash-DHOLOLINK_ROCE_USE_GPU_VRAM=OFF
使用锁页主机内存代替 GPU VRAM 可启用部分加速路径:网卡仍会通过 RoCE 直接 RDMA 到系统内存,绕过 Linux 网络子系统;但之后 GPU 读取这些数据时仍需经过 PCIe 传输。
当你的机器满足上述 GPUDirect RDMA 要求时,默认构建保持 HOLOLINK_ROCE_USE_GPU_VRAM 开启,即可使用完全加速的 GPUDirect RDMA 路径。该路径已在内部完成验证,验证平台为基于 AMD Threadripper 的 Lenovo ThinkStation 工作站,配备 ConnectX-6 Dx 网卡与 Quadro RTX 6000 GPU。
2.6 所有配置的通用步骤
现在,对所有配置执行:
-
为运行非加速网络示例配置网络接收缓冲区:Holoscan sensor bridge 支持使用非加速的 Linux socket 网络运行 Li VB1940、IMX274 与 TauroTech DA326 Hawk。为了让这些示例获得最佳性能,请增大 Linux socket 的网络接收缓冲区:
bashecho 'net.core.rmem_max = 31326208' | sudo tee /etc/sysctl.d/52-hololink-rmem_max.conf sudo sysctl -p /etc/sysctl.d/52-hololink-rmem_max.conf -
确保
$EN0被设置为连接到 HSB 的以太网控制器名称。某些安装步骤需要重启,重启会清除该变量,因此请按照上文说明针对你的配置重新正确设置。 -
在
$EN0上启用 PTP。这会使接收数据所携带的时间戳与主机时间同步。在开机时运行
phc2sys工具,将$EN0中的时钟与系统时钟同步。首先安装linuxptp工具:bashsudo apt update && sudo apt install -y linuxptp接下来,创建一个用于运行
phc2sys的 systemd 服务文件:bashPHC2SYS_SERVICE=/etc/systemd/system/phc2sys-$EN0.service cat <<EOF | sudo tee $PHC2SYS_SERVICE >/dev/null [Unit] Description=Copy system time to $EN0 Requires=NetworkManager.service After=NetworkManager.service After=timemaster.service [Service] Type=simple ExecStartPre=timeout 3m bash -c "until [ \"\$(nmcli -g GENERAL.STATE device show $EN0)\" = \"100 (connected)\" ]; do sleep 1; done" ExecStart=/usr/sbin/phc2sys -c $EN0 -s CLOCK_REALTIME -O 0 -S 0.0001 [Install] WantedBy=multi-user.target EOF将其配置为开机自启,并立即启动:
bashsudo chmod u+x $PHC2SYS_SERVICE sudo systemctl enable phc2sys-$EN0.service sudo systemctl start phc2sys-$EN0.service接下来,运行
ptp4l向$EN0发送 PTP SYNC 报文:bashcat <<EOF | sudo tee /etc/linuxptp/hsb-ptp.conf >/dev/null # This configuration is appropriate for NVIDIA Holoscan sensor bridge # applications, where PTP messages are sent over L2 and a 1/2 second interval. [global] logSyncInterval -1 logMinDelayReqInterval -1 network_transport L2 EOF为它创建一个 systemd 服务文件:
bashPTP4L_SERVICE=/etc/systemd/system/ptp4l-$EN0.service cat <<EOF | sudo tee $PTP4L_SERVICE >/dev/null [Unit] Description=Send PTP SYNC messages to $EN0 After=phc2sys-$EN0.service [Service] Type=simple ExecStart=/usr/sbin/ptp4l -i $EN0 -f /etc/linuxptp/hsb-ptp.conf [Install] WantedBy=multi-user.target EOF最后,运行它:
bashsudo chmod u+x $PTP4L_SERVICE sudo systemctl enable ptp4l-$EN0.service sudo systemctl start ptp4l-$EN0.service -
仅针对使用 CUDA 12 的 Orin iGPU 配置(Jetpack 6 与 IGX 1.X):安装 NVIDIA DLA 编译器。使用推理的应用在初始化时需要它;部分 iGPU 的 OS 镜像未包含该组件。
bashsudo apt update && sudo apt install -y nvidia-l4t-dla-compiler -
使用你的开发者账号登录 NVIDIA GPU Cloud(NGC):
- 如果还没有 NGC 开发者账号,请在 https://catalog.ngc.nvidia.com/ 注册。
- 为你的账号创建 API key:https://ngc.nvidia.com/setup/api-key
- 使用你的 API key 登录 nvcr.io:
bashdocker login nvcr.io Username: $oauthtoken Password: <Your token key to NGC> WARNING! Your password will be stored unencrypted in /home/<user>/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
现在请继续阅读「构建」一章,构建并测试 Holoscan Sensor Bridge 容器。
3. 构建(Build)
3.1 构建 Holoscan Sensor Bridge 容器
Holoscan sensor bridge 主机软件包含构建演示容器的说明。该容器用于运行所有 holoscan 测试与示例。
-
如果还没有获取源码,请从 GitHub 拉取 sensor bridge 源代码:
bashgit clone https://github.com/nvidia-holoscan/holoscan-sensor-bridge -
构建 sensor bridge 演示容器。对于配备独立 GPU 且 OS 配置为 dGPU 的 IGX Orin,以及配备 NVIDIA 独立显卡的 x86_64 Linux 主机(见「主机设置」中的 x86 Linux 小节),使用 dGPU 选项;对于这里列出的其余平台,使用下面的 iGPU 选项。
iGPU:
bashcd holoscan-sensor-bridge sh docker/build.sh --igpudGPU:
bashcd holoscan-sensor-bridge sh docker/build.sh --dgpu
3.2 在演示容器中运行测试
要运行 sensor bridge 演示容器,请在 GUI 中的终端里执行:
bash
xhost +
sh docker/demo.sh
这将带你进入 Holoscan sensor bridge 演示容器内的 shell 提示符。(注意:iGPU 配置在启动演示容器时会显示 "Failed to detect NVIDIA driver version" 的消息,可以忽略。)现在你已经可以运行 sensor bridge 应用了。
3.3 Holoscan sensor bridge 软件回环测试
Sensor bridge 主机软件包含一个以回环(loopback)模式运行的测试套件,无需任何 sensor bridge 硬件。该测试通过生成 UDP 报文并经由 Linux 回环接口发送来工作。
在演示容器内的 shell 中执行:
bash
pytest
注意:该测试套件会有意向软件栈中注入错误。只要 pytest 显示所有测试均已通过,单个测试输出的任何错误消息都可以忽略。如果 pytest 本身报告失败,请参阅故障排查(troubleshooting)页面。
对于配备 sensor bridge 设备与 IMX274 的系统,测试套件还可以执行额外的测试,以证明设备与网络连接工作正常。
首先,确保 sensor bridge 固件是最新的。
对于 IGX 配置,将传感器桥设备上的两个 SFP+ 接口分别连接到两个 QSFP 连接器,然后执行:
bash
sh ./test-igx-cpnx100-imx274.sh
对于 AGX Orin,只支持一路相机,因此只连接 SFP+ 0。在 AGX 上以如下方式运行设备测试:
bash
sh ./test-agx-cpnx100-imx274.sh
如果工作不正常,请查看故障排查页面。
4. 示例(Examples)
Holoscan sensor bridge 的 Python 示例应用位于 examples 目录下。
以下是在 AGX Thor、DGX Spark、IGX 与 Jetson AGX Orin 平台上运行这些应用的说明。
4.1 选择适合平台的示例
Holoscan Sensor Bridge 支持多种硬件加速传输策略,兼容范围广泛的主机。每个示例都硬编码到特定的接收器类型;示例通过文件名前缀来标识所使用的接收算子。
RoceReceiver(ConnectX 主机)
- 文件名中没有任何前缀的示例使用 RoCEv2 加速网络接收算子,需要配备 ConnectX 的平台,如 IGX Orin、IGX T7000 或 DGX Spark。在这些系统上,传感器模组必须连接到 ConnectX 对应的端口,而不是 RJ45 连接器。 AGX Orin、AGX Thor 与 IGX T5000 系统无法运行这些示例。
- 对于 IGX T7000 上的加速网络示例,必须将
CUDA_VISIBLE_DEVICES环境变量设置为与图形 GPU 配置相匹配的值,其默认为 iGPU。例如,如果配置为 dGPU 图形,imx274_player必须将CUDA_VISIBLE_DEVICES设为0,以便 RDMA 与图形都使用 dGPU。 - 只要容器是用相应的 iGPU 或 dGPU 设置构建的,这些示例在 iGPU 与 dGPU 配置下都可以工作。
LinuxReceiver(非加速)
- 以
linux开头的示例使用非加速的 Linux Sockets API 网络接收算子。这些示例可在所有系统上运行。
FusaCoeCapture(仅限 Thor MGBE)
- 以
fusa_coe开头的示例使用 Thor 的 MGBE 接口上的硬件加速 CoE 能力,需要 AGX Thor 或 IGX T5000。传感器模组必须连接到主机的 QSFP MGBE 端口,而不是 RJ45 端口。
SiplCameraOutput(仅限 Thor MGBE)
- 以
sipl_开头的示例使用 SIPL 相机处理栈,需要 AGX Thor 或 IGX T5000。传感器模组必须具有 UDDF 驱动,并连接到主机的 QSFP MGBE 端口,而不是 RJ45 端口。
4.2 IMX274 播放器示例
要在配备 ConnectX 的主机上运行 IMX274 视频播放器示例,在演示容器中执行:
Python:
bash
python3 examples/imx274_player.py
C++(需先构建,见下文 C++ 示例构建说明):
bash
./examples/imx274_player
对于非加速主机:
bash
python3 examples/linux_imx274_player.py
关于 IMX274 播放器应用源码的逐行解析文档可在用户指南中找到;该示例展示了架构文档中描述的基本 sensor bridge 工作流程。按 Control/C 停止视频播放器。
4.3 Leopard imaging VB1940 Eagle 播放器示例
此示例与上面的 IMX274 播放器示例类似,只是使用 LI VB1940 Eagle 相机替代 IMX274。要在 ConnectX 加速主机上运行 LI VB1940 Eagle 高速视频播放器,在演示容器中执行:
bash
python3 examples/vb1940_player.py
对于非加速主机:
bash
python3 examples/linux_vb1940_player.py
最后,在 AGX Thor 或 IGX T5000 上运行 SIPL 加速网络 Python 示例:
bash
python3 ./examples/sipl_player.py --json-config ./examples/sipl_config/vb1940_single.json
4.4 MAX96716A 解串器播放器示例
TauroTech DA326 传感器桥板载有一颗 Analog Devices MAX96716A GMSL 解串器,其中内置了视频图案生成器(VPG,Video Pattern Generator)。
max96716a_player 示例驱动 VPG 从解串器的 MIPI CSI-2 输出发出合成数据流,无需任何额外硬件。
Python:
对于 ConnectX 主机:
bash
python3 examples/max96716a_player.py
对于非加速配置:
bash
python3 examples/linux_max96716a_player.py
对于 AGX Thor 与 T5000,使用 MGBE 与 FuSa CoE 加速接收器:
bash
python3 examples/fusa_coe_max96716a_player.py
C++:
C++ 示例需要先构建。从仓库根目录执行:
bash
mkdir -p build && cd build
cmake ..
make -j
生成的可执行文件位于 build/examples/。从 build/ 目录即可运行 max96716a_player 的各个变体。
对于 ConnectX 加速主机:
bash
./examples/max96716a_player
对于非加速配置:
bash
./examples/linux_max96716a_player
对于 AGX Thor 或 IGX T5000,使用 FuSa CoE 加速接收器:
bash
./examples/fusa_coe_max96716a_player
4.5 Hawk 相机 + Tauro Tech DA326 播放器示例
此示例与上面的 IMX274、VB1940 播放器示例类似,使用 TauroTech DA326 传感器桥板并连接一个或多个 Hawk 相机模组。
请注意以下必需参数:
- 单链路(single-link)应用:
--channel A|B用于选择要使用的 GMSL 链路;--sensor left|right|both用于选择启用哪个(些)传感器的接收。 - 双链路(dual-link)应用:
--sensor left|right用于选择启用哪一侧传感器的接收(两条 GMSL 链路都会被使用)。
运行时使用 --help 可查看完整选项列表。
Python:
对于 ConnectX 加速平台:
bash
python3 examples/hawk_single_link_player.py
对于非加速配置:
bash
python3 examples/linux_hawk_single_link_player.py
对于 AGX Thor 或 T5000 MGBE,使用 FuSa CoE 加速接收器:
bash
python3 examples/fusa_coe_hawk_single_link_player.py
对于通过 DA326 的两个 GMSL 连接器接入两个 Hawk 模组的情况,还提供双链路变体。
对于 ConnectX 加速平台:
bash
python3 examples/hawk_dual_link_player.py
对于非加速配置:
bash
python3 examples/linux_hawk_dual_link_player.py
对于 AGX Thor 或 IGX T5000,使用 FuSa CoE 加速接收器:
bash
python3 examples/fusa_coe_hawk_dual_link_player.py
C++:
C++ 示例需要先构建。从仓库根目录执行:
bash
mkdir -p build && cd build
cmake ..
make -j
生成的可执行文件位于 build/examples/。从 build/ 目录即可运行 Hawk 播放器的各个变体。
对于 ConnectX 加速平台:
bash
./examples/hawk_single_link_player
对于非加速主机:
bash
./examples/linux_hawk_single_link_player
对于 AGX Thor 或 T5000,使用 FuSa CoE 加速接收器:
bash
./examples/fusa_coe_hawk_single_link_player
对于通过 DA326 的两个 GMSL 连接器接入两个 Hawk 模组的情况,双链路变体:
对于 ConnectX 加速平台:
bash
./examples/hawk_dual_link_player
对于非加速主机:
bash
./examples/linux_hawk_dual_link_player
对于 AGX Thor / T5000,使用 FuSa CoE 加速接收器:
bash
./examples/fusa_coe_hawk_dual_link_player
4.6 运行 TAO PeopleNet 示例
tao-peoplenet 示例演示了对实时视频流运行推理。TAO PeopleNet 提供的模型可以在给定图像中检测行人、包和人脸。在此示例中,当检测到这些目标时,会在实时视频上叠加显示边界框。
注意:元数据传递在与 InferenceOp 一起使用时存在一个未解决问题,因此这些示例的应用中显式禁用了它。
前提条件:从 NGC 网站下载 PeopleNet ONNX 模型:
bash
wget --content-disposition 'https://api.ngc.nvidia.com/v2/models/org/nvidia/team/tao/peoplenet/pruned_quantized_decrypted_v2.3.3/files?redirect=true&path=resnet34_peoplenet_int8.onnx' -O examples/resnet34_peoplenet_int8.onnx
对于配备 ConnectX 加速网络控制器接口、使用 IMX274 相机的系统:
bash
python3 examples/tao_peoplenet.py
对于使用 IMX274 相机的非加速配置:
bash
python3 examples/linux_tao_peoplenet.py
最后,在 AGX Thor 上使用 LI VB1940 相机运行 SIPL 加速网络 Python 示例:
bash
python3 ./examples/sipl_tao_peoplenet.py --json-config ./examples/sipl_config/vb1940_single.json
这将在 GUI 中启动 Holoscan 可视化器,显示来自 IMX274/Li VB1940 设备的实时视频流;当捕获到人物图像时,会叠加显示红/绿边界框。按 Ctrl/C 退出。关于此应用的更多信息请参阅用户指南相应页面。
4.7 运行人体姿态(body pose)示例
前提条件:从 YOLOv8 网站下载 YOLOv8 ONNX 模型并生成人体姿态 ONNX 模型。在 Holoscan sensor bridge 演示容器内执行:
注意: 运行 Jetpack 7.2 的原厂 AGX Orin 开发套件可能没有足够磁盘空间安装依赖。在安装下面的 Python 依赖之前,请通过清理未使用的软件包或 docker builder 缓存来确保有充足的磁盘空间。
从仓库根目录 holoscan-sensor-bridge 执行:
bash
apt-get update && apt-get install -y ffmpeg
pip3 install ultralytics onnx
cd examples
yolo export model=yolov8n-pose.pt format=onnx
trtexec --onnx=yolov8n-pose.onnx --saveEngine=yolov8n-pose.engine.fp32
cd -
注意,此转换步骤只需执行一次:yolov8n-pose.engine.fp32 文件包含转换后的模型,是运行演示所需的全部内容。已安装的组件会在容器退出后被遗忘;之后再次运行演示时不需要这些组件。
对于 ConnectX 加速主机,在 sensor bridge 演示容器内启动使用 IMX274 相机的人体姿态估计:
bash
python3 examples/body_pose_estimation.py
对于非加速主机,在演示容器内以如下方式启动人体姿态估计示例:
bash
python3 examples/linux_body_pose_estimation.py
最后,在 AGX Thor 上使用 Li VB1940 相机运行 SIPL 加速网络 Python 示例:
bash
python3 ./examples/sipl_body_pose_estimation.py --json-config ./examples/sipl_config/vb1940_single.json
这将在 GUI 中启动 Holoscan 可视化器,显示来自 IMX274/Li VB1940 设备的实时视频流,并以绿色叠加层显示人体姿态网络模型找到的关键点。关于此应用的更多信息请参阅用户指南相应页面。
按 Ctrl/C 退出。
4.8 运行立体 IMX274、Leopard imaging Li VB1940 Eagle 与 TauroTech DA326 Hawk 示例
stereo_imx274_player.py 示例展示了两条独立的流水线,分别对应双摄像头模组上的每一路相机。请确保主机与 Holoscan sensor bridge 设备之间的两个网络端口都已连接。
bash
python3 examples/stereo_imx274_player.py
这将启动一个包含两帧画面的可视化器显示,一帧为左通道,另一帧为右通道。
为了汇聚较低带宽的数据流,你可以参考以下将两路相机汇聚到单个网络端口的示例:
ConnectX 加速主机 + IMX274:
bash
python3 examples/single_network_stereo_imx274_player.py
非加速主机 + IMX274:
bash
python3 examples/linux_single_network_stereo_imx274_player.py
ConnectX 加速主机 + Li VB1940 Eagle:
bash
python3 examples/single_network_stereo_vb1940_player.py
非加速主机 + Li VB1940 Eagle:
bash
python3 examples/linux_single_network_stereo_vb1940_player.py
AGX Thor 或 IGX T5000 上使用 Li VB1940 相机的 SIPL Python 示例:
bash
python3 ./examples/sipl_player.py --json-config ./examples/sipl_config/vb1940_dual.json
使用 TauroTech DA326 传感器桥与 Hawk 相机模组时,Hawk 上的两个 AR0234 传感器共用一条通往 DA326 板载解串器的 GMSL 链路;single_network_stereo_hawk_player 示例将它们汇聚到 DA326 的 SFP+ 端口:
ConnectX 加速主机 + TauroTech DA326 Hawk:
bash
python3 examples/single_network_stereo_hawk_player.py --channel A|B
非加速主机 + TauroTech DA326 Hawk:
bash
python3 examples/linux_single_network_stereo_hawk_player.py --channel A|B
AGX Thor + TauroTech DA326 Hawk,使用 FuSa CoE 加速接收器:
bash
python3 examples/fusa_coe_single_network_stereo_hawk_player.py --channel A|B
希望将传感器映射到特定数据通道的应用,可以使用 use_sensor API,这些示例中对此做了演示。许多主机将网络带宽限制为 10Gbps,因此仅支持以 1080p 模式观察立体视频。
4.9 TSN IMX274 播放器示例
examples/linux_tsn_imx274_player.py 在 Linux IMX274 播放器的基础上扩展了时间敏感网络(TSN,Time-Sensitive Networking)支持。它在传感器虚拟端口与 EVT 通道上配置 802.1Q VLAN 标记,并在启动流水线之前对 FPGA 的 PTP 引擎进行编程。此示例可在所有支持 Linux Receiver 的平台上运行(AGX Orin、AGX Thor、DGX Spark 与 IGX)。
主机网络前提条件
在运行播放器之前,主机网卡上必须已存在 VLAN 子接口,并且传感器桥 IP 必须分配到该子接口上,以便内核将带 VLAN 标记的帧递交给 UDP socket:
bash
# 创建 VLAN 子接口(将 <iface> 与 <vlan-id> 替换为与你设置相匹配的值)
sudo ip link add link <iface> name <iface>.<vlan-id> type vlan id <vlan-id>
sudo ip link set <iface>.<vlan-id> up
# 将传感器桥 IP 分配到该子接口
sudo ip addr add 192.168.0.101/32 dev <iface>.<vlan-id>
这些命令在重启后不会保留。请将它们加入启动脚本或网络管理器配置中以使其永久生效。
主机 PTP 服务
--ptp-profile 参数控制 FPGA 被编程为使用哪种 PTP 规范(profile)。主机 PTP 守护进程必须与之匹配。一共使用两个 systemd 服务------同一时间只应运行其中一个:
--ptp-profile |
Profile | 需运行的主机服务 |
|---|---|---|
1(默认) |
gPTP (IEEE 802.1AS) | gptp4l-<iface>.service |
0 |
IEEE 1588 E2E | ptp4l-<iface>.service |
默认的主机设置会创建并启动 ptp4l-<iface>.service(IEEE 1588 E2E)。如需使用 gPTP,请按如下方式一次性创建该服务(将 <iface> 替换为你的网卡名,例如 enP5p3s0f0np0):
bash
# 创建 gPTP 配置文件
cat <<EOF | sudo tee /etc/linuxptp/gptp.conf >/dev/null
[global]
gmCapable 1
priority1 100
priority2 100
domainNumber 0
logAnnounceInterval 0
logSyncInterval -3
syncReceiptTimeout 3
assume_two_step 1
path_trace_enabled 1
follow_up_info 1
transportSpecific 0x1
ptp_dst_mac 01:80:C2:00:00:0E
network_transport L2
delay_mechanism P2P
EOF
# 创建 systemd 服务单元
GPTP4L_SERVICE=/etc/systemd/system/gptp4l-<iface>.service
cat <<EOF | sudo tee $GPTP4L_SERVICE >/dev/null
[Unit]
Description=Send gPTP (802.1AS) on <iface>
After=phc2sys-<iface>.service
[Service]
Type=simple
ExecStart=/usr/sbin/ptp4l -i <iface> -f /etc/linuxptp/gptp.conf
[Install]
WantedBy=multi-user.target
EOF
sudo chmod u+x $GPTP4L_SERVICE
sudo systemctl daemon-reload
sudo systemctl enable gptp4l-<iface>.service
切换到 gPTP:
bash
sudo systemctl stop ptp4l-<iface>.service
sudo systemctl start gptp4l-<iface>.service
journalctl -u gptp4l-<iface>.service -f # 等待出现 LOCKED
切换到 IEEE 1588 E2E:
bash
sudo systemctl stop gptp4l-<iface>.service
sudo systemctl start ptp4l-<iface>.service
journalctl -u ptp4l-<iface>.service -f # 等待出现 grandmaster 或 LOCKED
注意:按照 802.1AS 规范,gPTP 报文不带 VLAN 标记,因此无论 VLAN 如何配置,gPTP 服务都运行在物理接口上。
运行示例
bash
python3 examples/linux_tsn_imx274_player.py
默认情况下,播放器使用 gPTP(IEEE 802.1AS,profile 1)、VLAN ID 2、传感器 PCP 6、EVT PCP 4。所有这些都可以在命令行覆盖:
bash
# 使用 IEEE 1588 E2E profile 代替 gPTP
python3 examples/linux_tsn_imx274_player.py --ptp-profile 0
# 覆盖 VLAN ID 与 PCP 值
python3 examples/linux_tsn_imx274_player.py --vlan-id 10 --sensor-pcp 5 --evt-pcp 3
# 覆盖 PTP 域编号
python3 examples/linux_tsn_imx274_player.py --ptp-domain 1
完整选项参考:
| 选项 | 默认值 | 说明 |
|---|---|---|
--ptp-profile |
1 |
PTP profile:0 = IEEE 1588 E2E,1 = gPTP (IEEE 802.1AS),2 = IEEE 1588 P2P |
--ptp-domain |
0 |
与主机 PTP 守护进程匹配的 PTP 域编号 |
--vlan-id |
2 |
与交换机和主机子接口匹配的 12 位 VLAN ID |
--sensor-pcp |
6 |
传感器数据流量的优先级码点(PCP) |
--evt-pcp |
4 |
FPGA 事件通知的优先级码点(PCP) |
--camera-mode |
0 |
IMX274 传感器模式 |
--headless |
关 | 无显示运行 |
--frame-limit |
无 | 收到 N 帧后退出 |
关于源码的详细解析,请参阅用户指南中的 TSN IMX274 播放器应用章节。
4.10 RoCE TSN IMX274 播放器示例
examples/tsn_imx274_player.py 是 TSN IMX274 播放器的 RoCE 变体。它使用相同的 VLAN 与 PTP 配置,但数据经由 RoCE v2 而非 Linux socket 发送。由于 ConnectX 网卡会在硬件中剥离 VLAN 标记,因此无需主机 VLAN 子接口--------vlan-id、--sensor-pcp、--evt-pcp、--ptp-profile 与 --ptp-domain 选项的用法与 Linux TSN 播放器相同。
bash
python3 examples/tsn_imx274_player.py
4.11 运行 GPIO 示例
examples/gpio_example_app.py 是一个使用传感器桥 GPIO 接口的简单示例,演示如何设置 GPIO 方向、读取 GPIO 引脚输入值以及向 GPIO 引脚写入输出值。运行该应用:
bash
python3 examples/gpio_example_app.py
这会启动一个文本显示界面,循环切换不同的预设引脚配置,并在不同引脚设置之间留出时间,以便测量或回读引脚值。关于 GPIO 示例应用的更多信息,请参阅用户指南中的应用结构章节。
4.12 使用 Jetson 硬件 ISP 的示例
examples/linux_hwisp_player.py 展示了用 Jetson 硬件 ISP 单元处理由 IMX274 实时采集的 Bayer 帧的示例。此示例支持 iGPU 配置下的 Jetson Orin AGX 与 IGX Orin 700。此示例不支持 AGX Thor;关于硬件 ISP 的用法请参考 SIPL 示例。
在启动 docker 运行之前,先以 enableRawReprocessing=1 和 rawReprocessModulePartName="A6V26" 标志设置 nvargus-daemon。这使我们能够用 ISP 处理由 Holoscan sensor bridge 设备采集的 imx274 Bayer 帧,且该更改在重启后依然保持。在主机系统中执行:
bash
sudo su
pkill nvargus-daemon
export enableRawReprocessing=1
export rawReprocessModulePartName="A6V26"
nvargus-daemon
exit
要运行该示例,在演示容器内执行:
bash
python3 examples/linux_hwisp_player.py
这将运行带可视化显示的应用,展示实时采集画面。注意,自 Jetpack 6 起默认相机模式已更改,现在默认为 4K 帧。此示例兼容 Jetpack 7.2+。
注意:如果用户希望撤销以 enableRawReprocessing=1 标志运行 nvargus-daemon 的设置,请执行以下命令:
bash
sudo su
pkill nvargus-daemon
unset enableRawReprocessing
unset rawReprocessModulePartName
nvargus-daemon
exit
4.13 运行 IMX274 延迟(Latency)应用示例
对于 IGX 系统,examples/imx274_latency.py 展示了如何使用时间戳对硬件与软件流水线进行性能剖析。此示例演示了记录 FPGA 在数据采集时发出的时间戳,以及在帧接收与流水线执行的各个点上于主机侧测量的时间戳。运行结束时,应用将输出一份包含平均值、最小值与最大值的时长与延迟报告。
在运行该应用之前,请确保已在你的设置上启用 PTP 同步,然后使用以下命令运行示例:
bash
python3 examples/imx274_latency.py
在非加速主机上运行延迟示例应用:
bash
python3 examples/linux_imx274_latency.py
此示例无法在 AGX Thor 上运行。
4.14 运行 ECam0M30ToF 播放器应用
ecam0m30tof_player.py 应用演示了如何采集并显示来自 ECam0M30ToF 飞行时间(ToF)相机的深度和/或红外(IR)数据,使用 RoCE(RDMA over Converged Ethernet)实现高性能数据传输,并利用 Holoviz 算子的 DEPTH_MAP 渲染增强深度可视化效果。通过将接收算子从 RoceReceiverOp 改为 LinuxReceiverOperator,可以修改此应用使其在 Jetson AGX 上运行。
前提条件:ECam0M30ToF 相机已连接到 Hololink 设备。
运行该应用使用以下命令:
bash
python3 examples/ecam0m30tof_player.py --hololink 192.168.0.2 --camera-mode=<0|1|2>
相机配置:
--camera-mode:选择相机模式(0:DEPTH_IR,1:DEPTH,2:IR)
此示例无法在 AGX Thor 上运行。
4.15 运行 CPU 与 GPU 帧校验示例
帧校验示例演示了如何访问帧元数据,以检测丢帧、帧时间戳错位和帧 CRC 错误。这些示例记录 FPGA 在数据采集时发出的时间戳、帧号与 CRC32 数据。运行期间,丢帧、时间戳错位与 CRC32 错误会被检测并报告。运行结束时,应用会输出一份包含平均值、最小值与最大值的时长与延迟报告。这些数值在应用运行期间收集,用于评估各种检测机制对流水线延迟的影响。
IMX274
Linux 接收器
对于非加速配置,examples/linux_imx274_frame_validation.py 使用标准 Linux socket 进行网络通信,并采用基于 CPU 的 CRC 校验。
在运行该应用之前,请在你的设置上启用 PTP 同步,然后使用以下命令运行示例。在 AGX Orin 系统上运行帧校验示例:
bash
python3 examples/linux_imx274_frame_validation.py
由于此示例中的 CRC32 计算由 CPU 完成,按原样使用该示例检测 CRC32 错误会引发丢帧错误。因此 CRC32 错误检测默认未启用。要每 N 帧启用一次 CRC32 检测,使用 --crc-frame-check 选项:
bash
python3 examples/linux_imx274_frame_validation.py --crc-frame-check 50
在此示例中,应用将每 50 帧检查一次 CRC32 帧错误。
RoCE 接收器
对于 ConnectX 加速平台,examples/imx274_frame_validation.py 提供高性能帧校验,使用 nvCOMP 5.0 实现 GPU 加速 CRC 检查。此示例使用加速网络接收算子,需要 ConnectX SmartNIC 控制器。
在运行该应用之前,请在你的设置上启用 PTP 同步,然后使用以下命令:
bash
python3 examples/imx274_frame_validation.py
与 Linux 版本中基于 CPU 的 CRC 校验不同,使用 nvCOMP 5.0 的 GPU 加速 CRC 速度足够快,默认即可校验每一帧。CRC 校验默认以 --crc-frame-check 1 启用。要完全禁用 CRC 校验,使用 --crc-frame-check 0。
执行结束时,应用会输出一份 CRC 校验报告,显示已处理的总帧数、检测到的 CRC 错误数与成功率,随后是包括帧时间、传输延迟、算子延迟与处理时间在内的详细性能指标。
要校验立体相机配置:
bash
python3 examples/stereo_imx274_frame_validation.py
性能
在 IGX-dGPU 上、单相机 4K 分辨率配置下,nvCOMP CRC 计算性能(基于 1000 帧测量):
none
Minimum: 275 us
Maximum: 390 us
Average: 295 us
关于启动性能的说明: HSDK 流水线在启动时的运行时性能可能不稳定,通常是由于 GPU 内核初始化。这很可能导致 CRC 校验失败:当流水线慢于相机帧率时,接收缓冲可能被新数据覆盖,从而触发 CRC 检查所要发现的那种失败。一旦流水线完全初始化并能跟上接收数据的速度,就不应再出现这些错误。我们主要在立体相机场景中观察到该问题。因此,我们的测试(见 tests/test_module_imx274_pattern.py)在开始时跳过 CRC 检查,例如仅在收到 15 帧之后才开始检查。用户应用很可能也会采用类似的启动阶段处理,以避免因这一已知情况产生误导性错误。
此示例无法在 AGX Thor 上运行。
Li VB1940 Eagle
FUSA CoE 接收器(nvCOMP)
对于 AGX Thor 与 T5000,examples/vb1940_fusa_nvcomp_crc_validation.py 提供高性能帧校验,使用 nvCOMP 5.0 实现 GPU 加速 CRC 检查。此示例使用 FUSA CoE 捕获算子实现加速网络数据传输。
在运行该应用之前,请在你的设置上启用 PTP 同步,然后使用以下命令:
bash
python3 examples/vb1940_fusa_nvcomp_crc_validation.py
使用 nvCOMP 5.0 的 GPU 加速 CRC 速度足够快,默认即可校验每一帧。应用在完整 CSI 帧(包括 CSI 头与尾部字节)上计算 CRC,以匹配相机 FPGA 的 CRC 计算方式。
执行结束时,应用会输出一份 CRC 校验报告,显示已处理的总帧数、检测到的 CRC 错误数与成功率,随后是包括帧时间、FUSA 捕获延迟、算子延迟与处理时间在内的详细性能指标。
性能
在 AGX Thor 上、Li VB1940 Eagle 相机配置下,nvCOMP CRC 计算性能(基于 1000 帧测量):
none
Minimum: 554.4 us
Maximum: 631.0 us
Average: 614.3 us
4.16 运行 PVA 帧校验示例
PVA CRC 校验示例演示了使用 NVIDIA PVA(可编程视觉加速器,Programmable Vision Accelerator)进行硬件加速 CRC 计算来校验相机帧。这些示例将 PVA 计算出的 CRC 值与相机 FPGA 内嵌的 CRC 值进行比对,以检测数据损坏。
关于要求与构建说明,请参阅 PVA CRC README。
要运行 PVA CRC 校验示例,首先设置 LD_LIBRARY_PATH 环境变量(运行任何应用之前都必须设置)。在演示容器内执行:
bash
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/aarch64-linux-gnu/tegra/:/opt/nvidia/pva-sdk-2.9/lib/aarch64-linux-gnu/:/usr/lib/aarch64-linux-gnu/nvidia
在 ConnectX 加速系统上运行 IMX274 PVA CRC 校验示例:
bash
python3 examples/imx274_pva_crc_validation.py --frame-limit 100
在 AGX Thor 或 IGX T5000 上运行 Li VB1940 Eagle PVA CRC 校验示例:
bash
python3 examples/vb1940_fusa_pva_crc_validation.py --frame-limit 100
性能
IMX274
在 IGX-dGPU 上、单相机 4K 分辨率配置下,PVA CRC 计算性能(基于 1000 帧测量):
none
Minimum: 412 us
Maximum: 442 us
Average: 414 us
Li VB1940 Eagle
在 AGX Thor 上、单相机 1080p 分辨率配置下,PVA CRC 计算性能(基于 1000 帧测量):
none
Minimum: 106 us
Maximum: 137 us
Average: 111 us
4.17 运行 UART 双板示例
examples/uart_dual_board_loopback.py 测试两块板之间的 UART 通信。
硬件设置:将板 1 的 GPIO 10(TX)连接到板 2 的 GPIO 11(RX),并将板 2 的 GPIO 10(TX)连接到板 1 的 GPIO 11(RX)。引脚位置请参阅 Lattice Bajoran 板 GPIO 引脚位置说明。
支持两种模式:单向 (tx/rx),一块板发送、另一块接收;以及 dual,两块板同时收发。
单向(tx/rx)------一板发送,一板接收:
bash
# 终端 1(接收方):
python3 examples/uart_dual_board_loopback.py --mode rx --hololink 192.168.2.2
# 终端 2(发送方):
python3 examples/uart_dual_board_loopback.py --mode tx --hololink 192.168.0.2
Dual 模式------两块板同时收发:
bash
# 终端 1(板 1):
python3 examples/uart_dual_board_loopback.py --mode dual --hololink 192.168.0.2 --test-string "HELLO" --expected-rx-string "WORLD"
# 终端 2(板 2):
python3 examples/uart_dual_board_loopback.py --mode dual --hololink 192.168.2.2 --test-string "WORLD" --expected-rx-string "HELLO"
传入 --mode(tx、rx 或 dual)、--hololink 指定各板 IP;在 dual 模式下还可选 --test-string、--expected-rx-string 与 --flow-control。运行 --help 查看全部选项。
UART FIFO 大小为 256 字节。两个应用都会相应地对数据分块,并校验发送与接收的数据是否一致。
4.18 运行 I2S 音频采集示例
这两个示例从板卡采集 I2S 音频并通过 ALSA 播放(可选写入 WAV 文件)。它们走 I2S 接收(RX)路径;板载数字麦克风(DMIC)驱动 I2S 时隙。
设置:使用演示启动脚本在主机上运行,该脚本会启动挂载了 PulseAudio 的演示容器,使解码后的音频从主机的扬声器或耳机播放出来。
RoCE 接收器
examples/audio_recorder.py 将音频流式传输到 ConnectX 加速主机。
bash
# 实时播放:
sh docker/demo.sh python3 examples/audio_recorder.py
# 边播放边录制到 WAV 文件,2000 帧后停止:
sh docker/demo.sh python3 examples/audio_recorder.py --output capture.wav --frame-limit 2000
# 仅采集(不播放):
sh docker/demo.sh python3 examples/audio_recorder.py --no-playback --output capture.wav
传入 --hololink 指定板卡 IP;--sensor 选择 I2S 传感器索引(hololink-lite 上默认为 2;其他板卡可能不同);--output 写入小端立体声 WAV;--frame-limit 在 N 帧后停止(省略则一直运行直到 Ctrl-C 中断);--no-playback 仅采集;--alsa-device 选择输出设备。运行 --help 查看全部选项。
音频以 48kHz 立体声 32 位 PCM 格式交付。两个 I2S 时隙作为立体声对转发(时隙 0 -> 左声道,时隙 1 -> 右声道);当 DMIC 只驱动一个时隙时,另一个时隙携带总线上当前的任意数据,并出现在相应声道中。
FuSa CoE(MGBE)接收器
examples/audio_recorder_fusa.py 将音频流式传输到 AGX Thor 或 IGX T5000。
bash
# 实时播放:
sh docker/demo.sh python3 examples/audio_recorder_fusa.py
# 边播放边录制到 WAV 文件,2000 帧后停止:
sh docker/demo.sh python3 examples/audio_recorder_fusa.py --output capture.wav --frame-limit 2000
# 仅采集(不播放):
sh docker/demo.sh python3 examples/audio_recorder_fusa.py --no-playback --output capture.wav
参数含义同上。音频同样以 48kHz 立体声 32 位 PCM 格式交付;两个 I2S 时隙作为立体声对转发(时隙 0 -> 左声道,时隙 1 -> 右声道);当 DMIC 只驱动一个时隙时,另一个时隙携带总线上当前的任意数据,并出现在相应声道中。
4.19 子帧处理(Sub-Frame Processing)示例
子帧处理允许高分辨率传感器数据帧在到达时被逐步处理与显示,从而降低延迟并实现渐进式显示。关于子帧处理工作原理的详细信息,请参阅用户指南中的子帧处理应用章节。
IMX274 子帧播放器示例
子帧 IMX274 播放器示例演示了以子帧(而非完整帧)为单位处理与显示相机帧。这为高分辨率相机实现了更低延迟的可视化。
Python:
bash
# 使用 ConnectX 加速网络控制器
python3 examples/sub_frame_imx274_player.py --sub-frame-rows 540
# 非加速配置(例如 AGX Orin、AGX Thor)
python3 examples/linux_sub_frame_imx274_player.py --sub-frame-rows 540
C++(构建后):
bash
# 使用 ConnectX 加速网络控制器
./examples/sub_frame_imx274_player --sub-frame-rows 540
# 非加速配置
./examples/linux_sub_frame_imx274_player --sub-frame-rows 540
--sub-frame-rows 参数指定每个子帧的行数。
注意: sub_frame_rows 必须能整除帧高。例如,有效值为 --sub-frame-rows 540(2160 ÷ 540 = 4 个子帧)。
VB1940 子帧可视化器示例
子帧 VB1940 播放器示例演示了使用 SubFrameVisualizerOp 进行与显示同步的采集的子帧处理。子帧在到达时被逐步可视化:每个子帧被合成到其在显示帧中的位置,而无需等待完整帧完成。采集时序通过 FPGA PTP/PPS 输出与显示刷新同步,从而最小化端到端延迟。
bash
$BUILD_DIR/examples/sub_frame_vb1940_player --sub-frame-rows 248
--sub-frame-rows 参数指定每个子帧的行数。VB1940 默认模式为 2560×1984 @ 60fps。
注意: sub_frame_rows 必须能整除帧高。对于 1984 行,有效值包括 248(8 个子帧)、496(4 个子帧)和 992(2 个子帧)。
其他选项:
--fullscreen:全屏模式运行(默认:true)--exclusive-display:使用独占显示模式以降低延迟--camera-mode:选择 VB1940 传感器模式(默认:VB1940_MODE_2560X1984_60FPS)--use-sensor:连接两个传感器时选择传感器索引(0 或 1,默认:0)--frame-limit:收到指定帧数后退出(默认:一直运行)
关于与显示同步采集的工作原理,请参阅应用指南中的 SubFrameVisualizerOp 详细说明。
子帧处理模式
子帧示例支持两种显示模式:
-
子帧合成器模式 (IMX274 示例):子帧由
SubFrameCombinerOp累积成完整帧缓冲后,再传给HolovizOp显示。采集时序独立于显示刷新率。 -
子帧可视化器模式 (VB1940 示例):子帧在到达时由
SubFrameVisualizerOp直接合成到显示上。采集通过 PTP/PPS 与显示 FPO(First Pixel Out,首像素输出)事件同步,因此每次显示刷新都展示最新可用数据,延迟最小。
子帧配置参数
sub_frame_rows:每个子帧的行数。设为 0 则禁用子帧处理(完整帧模式)。必须能整除帧高。
性能考量
-
内存 :更小的子帧可降低内存需求,但会增加处理开销。
SubFrameCombinerOp会等待所有子帧到达后再输出完整帧;若某个子帧丢失且下一帧已开始,则会输出一个不完整的帧。 -
网络:子帧大小应与网络数据包大小对齐,以尽量减少不完整的子帧并提升效率。