NXP i.MX与LS1028A平台TSN特性配置与测试实战指南

NXP i.MX与LS1028A平台TSN特性配置与测试实战指南

1. 项目概述与TSN技术背景

在工业自动化、汽车电子和音视频传输这些对时间要求极其苛刻的领域,传统的“尽力而为”以太网常常力不从心。一个毫秒级的网络抖动,在运动控制中可能导致机械臂定位偏差,在车载网络中可能意味着关键安全信号的延迟,在专业音视频流中则会产生恼人的卡顿或音画不同步。时间敏感网络(TSN)正是为解决这一核心痛点而生,它并非创造一种全新的网络,而是对标准以太网进行了一系列增强,使其具备了提供确定性服务质量的能力。简单来说,TSN能让网络像铁路系统一样,为不同类型的“列车”(数据流)规划好精确的“时刻表”和“轨道优先权”,确保关键数据总能准时、可靠地到达。

NXP的i.MX 8系列和LS1028A等嵌入式处理器,凭借其集成的TSN硬件加速引擎,成为了实现这类确定性网络的理想硬件平台。它们将复杂的流量调度、时间戳记录等任务从CPU卸载到专用硬件,大幅降低了系统负载和软件复杂度。然而,硬件能力只是基础,如何正确配置并验证这些TSN特性,使其在实际系统中发挥作用,才是工程师面临的核心挑战。官方文档往往提供了命令示例,但背后的原理、参数选择的考量以及实际调试中可能遇到的“坑”,则需要一线实践经验来填补。本文将基于我在多个工业网关和控制器项目中的实操经验,深入解析在NXP i.MX 8DXL、i.MX 8M Plus、i.MX 93以及LS1028A平台上,配置与测试Qbv、Qbu、Qci、Qav等关键TSN特性的完整过程,分享从环境搭建、命令解析到问题排查的实战细节。

2. 测试环境搭建与核心工具解析

在开始任何TSN特性测试之前,一个稳定、可控的测试环境是成功的一半。这不仅仅是连接几块开发板那么简单,更需要理解网络拓扑、工具链以及底层驱动的状态。

2.1 硬件平台选择与接口确认

不同的NXP平台,其TSN功能的实现和对应的网络接口名称有所不同,这是第一个容易混淆的点。根据我的实测经验:

  • i.MX 8M Plus EVK / i.MX 93 EVK / i.MX 93 14x14 EVK:支持TSN的ENET_QOS端口通常是eth1。这里需要特别注意,对于i.MX 93 14x14 EVK,必须通过J9连接器外接TJA1103SDB ENET PHY子卡才能使用ENET_QOS接口。测试时,两块板卡需要通过TJA1103ADB PHY子卡背对背连接,并且其中一块子卡上的J14跳线需要短接2-3脚(CONFIG 6),这个硬件细节千万不能忽略,否则链路可能无法正常建立或TSN特性不生效。
  • i.MX 8DXL EVK / i.MX 93 9x9 LPDDR4 QSB:支持TSN的ENET_QOS端口通常是eth0
  • LS1028A RDB:其TSN功能主要通过ENETC(集成化以太网控制器)实现,接口名通常为eno0,eno1等。

实操心得:上电后,第一件事就是用ip link showifconfig -a确认所有网络接口。更可靠的方法是直接检查sysfs,例如在i.MX 8M Plus上,可以通过ls /sys/devices/platform/soc@0/30800000.bus/30bf0000.ethernet/net/来确认eth1是否存在。如果接口不存在,很可能是设备树(Device Tree)配置或内核驱动没有正确加载,需要回头检查BSP和内核配置。

2.2 核心软件工具:tc与ethtool

TSN在Linux下的配置主要依靠两个强大的用户空间工具:tc(Traffic Control) 和ethtool

  • tc(流量控制):这是Linux内核网络子系统中流量控制框架的用户态配置工具。TSN的队列调度(Qbv)、整形(Qav)等功能,都是通过为网络接口添加特定的qdisc(排队规则)来实现的。例如,taprioqdisc用于配置Qbv的时间感知整形器,cbsqdisc用于配置Qav的基于信用的整形器。理解tc命令的结构(qdisc,class,filter)是进行TSN配置的基础。
  • ethtool:这是一个用于查询和设置网卡驱动及硬件参数的通用工具。在TSN上下文中,我们主要用它来:
    1. 检查和配置帧抢占(Qbu)功能:ethtool --show-mm/ethtool --set-mm
    2. 检查硬件时间戳能力:ethtool -T,这对于PTP时钟同步至关重要。
    3. 查看和设置网卡的其他参数,如速度、双工模式等。

注意事项:在i.MX 8M Plus等平台上,其dwc_mac驱动在网卡设备(如eth1)未启动(ifconfig eth1 up)时,部分硬件功能(包括PTP和某些ethtool查询)可能无法正常工作。这是一个常见的“坑”。安全的做法是,在尝试任何PTP操作或详细的ethtool查询前,先确保接口已经up

2.3 测试拓扑搭建

对于功能验证,最简单的拓扑是两块支持TSN的开发板通过以太网端口背对背直连。这种拓扑排除了交换机的干扰,最适合验证点对点的TSN特性,如Qbv门控、Qbu帧抢占、Qci流过滤等。

对于需要观察流量整形效果的测试(如Qav),或者没有第二块板卡时,可以使用网络测试仪(如Spirent TestCenter、IXIA等)作为流量发生器和分析仪。测试仪的一个端口连接开发板,另一个端口可以模拟各种流量模式并精确测量延迟、抖动和带宽。

如果以上设备都没有,一个折中的方案是使用另一台Linux主机,配合pktgen(内核模块)、iperf3tcpdump进行基本的流量生成和捕获。虽然精度不如专业仪表,但对于功能验证和初步性能评估已经足够。例如,可以用一台主机运行iperf3 -s作为服务器,开发板运行iperf3 -c作为客户端产生流量,同时在开发板或另一台主机上用tcpdump -i eth0 -w tsn.pcap抓包,然后用Wireshark分析pcap文件,观察帧的间隔、大小等是否符合TSN调度预期。

3. 时钟同步(IEEE 802.1AS)配置实践

TSN所有基于时间的调度(如Qbv)都依赖于网络中所有设备拥有一个高度同步的时钟。这是TSN的基石,通常通过IEEE 802.1AS(gPTP)或IEEE 1588v2(PTP)协议实现。NXP平台集成了硬件PTP时钟,可以支持纳秒级同步。

3.1 检查与配置PTP硬件支持

首先,需要确认你的网卡接口支持硬件时间戳。这是实现高精度同步的前提。

ethtool -T eth1

查看输出中是否有hardware-transmithardware-receive能力,并且PTP Hardware Clock编号不为空。这表示内核已经识别到了硬件PTP时钟设备(通常是/dev/ptp0,/dev/ptp1等)。

3.2 运行PTP守护进程(ptp4l)

在两块背对背连接的板卡上,我们需要运行ptp4l(Linux PTP项目的一部分)来建立主从时钟关系。

  1. 为接口配置IP地址(PTP报文传输需要):

    ifconfig eth1 192.168.3.1 netmask 255.255.255.0 # 在另一块板卡上配置同网段IP,如192.168.3.2
  2. 在两块板卡上分别启动ptp4l

    ptp4l -i eth1 -p /dev/ptp1 -m -2
    • -i eth1: 指定网络接口。
    • -p /dev/ptp1: 指定使用的PTP硬件时钟设备。这里是个关键点:设备号(ptp0, ptp1)需要根据ethtool -T的输出和实际系统/dev/下的设备节点来确认,不能想当然。
    • -m: 将日志打印到标准输出。
    • -2: 使用IEEE 1588v2的二层组播报文。对于802.1AS(gPTP),则需要使用特定的配置文件。
  3. 观察同步状态:启动后,ptp4l会通过最佳主时钟算法(BMCA)自动选举出一台主时钟(Master),另一台成为从时钟(Slave)。在Slave设备的日志中,你会看到offset(时钟偏移)和delay(路径延迟)的值逐渐收敛并稳定在纳秒级别,这表示同步成功。

3.3 针对802.1AS (gPTP) 的配置

工业领域更常用的是802.1AS(gPTP)。它简化了PTP的配置,更适合车载和工业网络。配置方式通常是使用一个预定义的配置文件。

ptp4l -i eth1 -p /dev/ptp1 -f /etc/ptp4l_cfg/gPTP.cfg -m

这里-f参数指定了gPTP的配置文件。你需要确保这个配置文件存在于目标文件系统中。在NXP的Real-Time Edge BSP里,通常会提供这个文件。

3.4 帧抢占(Qbu)环境下的时钟同步特殊处理

这是一个非常重要的细节。当链路上启用了Qbu(帧抢占)功能时,PTP同步报文有可能被标记为“可抢占”帧。如果这些报文在传输过程中被高优先级的“快速”帧打断,就会引入额外的、不确定的延迟,从而破坏时钟同步的精度

为了解决这个问题,ptp4l提供了--hwts_filter参数。当对端设备启用了帧抢占,且PTP报文可能被抢占时,应在命令中增加此参数:

ptp4l -i eth1 -p /dev/ptp1 -f /etc/ptp4l_cfg/gPTP.cfg -m --hwts_filter=full

--hwts_filter=full会告知ptp4l只处理那些时间戳记录完整的报文,从而过滤掉因抢占而产生时间戳异常(或不完整)的同步报文,确保主从时钟计算的准确性。

踩坑记录:在一次汽车网关项目中,我们启用了Qbu来保证CAN FD over Ethernet流量的低延迟。但随后发现PTP同步精度从纳秒级恶化到了微秒级。排查了很久,最终发现就是没有添加--hwts_filter=full参数。添加后,同步精度立刻恢复。因此,只要网络中存在帧抢占的可能性,就强烈建议加上这个参数。

4. Qbv(时间感知整形器)配置与测试详解

Qbv是TSN的核心特性之一,它像一个精确的“交通信号灯”,为每个流量队列(Traffic Class)在特定的时间窗口内打开或关闭“门”(Gate),从而严格规划不同类型数据的发送时刻,实现确定性的延迟和零拥塞丢失。

4.1 Qbv核心概念与配置命令拆解

在i.MX和LS1028A平台上,我们使用tc工具的taprioqdisc来配置Qbv。下面以一个典型的配置命令为例,逐部分解析:

tc qdisc replace dev eth1 parent root handle 100 taprio \ num_tc 5 \ map 0 1 2 3 4 \ queues 1@0 1@1 1@2 1@3 1@4 \ base-time 1577187882000000000 \ sched-entry S 01 100000 \ sched-entry S 02 100000 \ sched-entry S 04 100000 \ flags 2
  • num_tc 5: 声明我们使用了5个流量类别(Traffic Class, TC),编号从0到4。TC的数量需要与硬件支持的队列数匹配。
  • map 0 1 2 3 4: 这是优先级映射表。它定义了网络数据包的优先级(如VLAN PCP值或IP DSCP值)映射到哪个TC。map 0 1 2 3 4是一种最简单的映射,表示优先级0映射到TC0,优先级1映射到TC1,以此类推。在实际应用中,你需要根据你的流量类型来规划这个映射。
  • queues 1@0 1@1 1@2 1@3 1@4: 定义每个TC对应的硬件发送队列。1@0表示TC0使用1个队列,队列索引为0。通常配置为一对一映射。
  • base-time 1577187882000000000基准时间,单位是纳秒。这是整个调度表开始执行的绝对时间点,必须是一个未来的PTP时间。你需要先获取当前的PTP时间,然后加上一个偏移量(如2秒后)来计算这个值。例如,使用devmem2读取PTP时钟寄存器,或者通过phc2sys工具获取系统时间对应的PTP时间。
  • sched-entry S <gate_mask> <interval>: 这是调度条目,定义了在一段时间内哪些门是打开的。
    • S: 表示“SetGateStates”,即设置门状态。
    • <gate_mask>: 一个8位的十六进制数,每一位对应一个TC的门状态(1=开,0=关)。例如01(二进制0000 0001)表示只打开TC0的门,关闭TC1-TC7的门。02(二进制0000 0010)表示只打开TC1的门。
    • <interval>: 该调度条目持续的时长,单位是纳秒。例如100000表示100微秒。
  • flags 2: 这个标志位非常关键。2对应TAPRIO_CMD_FLAG_FULL_OFFLOAD,表示将整个Qbv调度表完全卸载到硬件中执行。软件(内核)只负责下发配置,后续的门开关切换由硬件时钟精确触发,不占用CPU资源,这是实现低抖动和确定性的关键。务必确保此标志被设置

4.2 完整Qbv测试流程

假设我们要测试一个简单的调度:TC0的门打开100微秒,然后TC1的门打开100微秒,循环往复。

  1. 准备工作:确保两块板卡(A和B)的eth1接口已通过PTP同步。为eth1配置IP地址并启用接口。

  2. 计算基准时间

    # 方法一:使用devmem2直接读取PTP时钟寄存器(需知道寄存器地址,如i.MX 8M Plus的0x30bf0b08) devmem2 0x30bf0b08 # 假设返回 0x5E01F9B2,这是以秒为单位的PTP时间。 # 计算2秒后的纳秒时间:(0x5E01F9B2 + 120) * 1000000000 # 方法二(更通用):运行ptp4l后,其输出日志中会打印当前时间。也可以编写小程序通过PTP设备ioctl获取。

    将计算出的未来时间作为base-time

  3. 在发送端(板卡A)配置Qbv

    tc qdisc replace dev eth1 parent root handle 100 taprio \ num_tc 5 map 0 1 2 3 4 queues 1@0 1@1 1@2 1@3 1@4 \ base-time <你计算出的基准时间> \ sched-entry S 01 100000 \ sched-entry S 02 100000 \ sched-entry S 04 100000 \ flags 2

    这个调度表周期为300微秒(三个100微秒条目),依次打开TC0、TC1、TC2的门。注意taprio要求调度表至少有两个条目,且最后一个条目的间隔之后会循环回第一个条目。

  4. 生成测试流量:使用板载的pktgen脚本向特定队列发送流量。

    # 向队列1(对应TC1)发送数据包 /usr/share/samples/pktgen/pktgen_twoqueue.sh -i eth1 -q 1 -s 1000 -n 0 -m 90:e2:ba:ff:ff:ff # -q 指定队列,-s 指定包大小,-n 0表示无限发送,-m 指定目的MAC

    你可以同时运行多个pktgen实例,向不同队列(如TC0和TC2)发送流量。

  5. 验证结果:在接收端(板卡B)使用tcpdump抓包。

    tcpdump -i eth1 -e -nn -t -c 10000 -w qbv_test.pcap

    将抓到的qbv_test.pcap文件拷贝到电脑上,用Wireshark打开。通过分析数据包的时间戳,你应该能看到:

    • 来自TC1(队列1)的数据包,只在每个调度周期的第二个100微秒窗口内出现。
    • 来自TC0和TC2的数据包,分别只在第一个和第三个100微秒窗口内出现。
    • 数据包之间几乎没有时间重叠,且窗口间隔规律。
  6. 检查Qbv状态:可以通过读取硬件寄存器来确认Qbv调度器是否已激活。

    devmem2 0x30bf0c58 # i.MX 8M Plus上查询MTL_EST_Status寄存器

    如果状态寄存器显示为active,则表明硬件调度器正在运行。

常见问题与排查

  1. 流量没有按预期被门控:首先检查flags是否设置为2(全卸载)。如果不是,调度可能由软件模拟,精度和确定性很差。其次,检查map配置,确保你发送流量的优先级(或直接指定的队列)正确映射到了你希望控制的TC。
  2. 基准时间已过:如果base-time设置成了一个过去的时间,taprio会尝试计算下一个合适的周期起点,但行为可能不符合预期。最好总是设置一个未来时间(如当前时间+2秒)。
  3. 与Qbu的冲突:如果同时启用了Qbv和Qbu(帧抢占),需要特别注意。对于被设置为“可抢占”队列的门控,在Qbv中可能被视为常开(Hold/Release模式控制)。在配置Qbv前,最好先用ethtool --show-frame-preemption eth1检查帧抢占状态,如果已激活,可能需要先禁用(ethtool --set-frame-preemption eth1 disabled)才能进行纯Qbv测试。

5. Qbu(帧抢占)配置与测试详解

传统以太网帧一旦开始传输,就必须完整发送,即使有一个更高优先级的帧到达,也必须等待当前帧发完。这对于最大尺寸(1522字节)的帧来说,可能引入超过120微秒的延迟。Qbu(帧抢占)机制允许一个高优先级的“快速”帧(Express Frame)中断一个正在传输的低优先级“可抢占”帧(Preemptable Frame),将后者分割成多个片段发送,从而显著降低高优先级流的延迟。

5.1 启用与验证帧抢占能力

帧抢占能力依赖于链路两端的设备(本端和对端)都支持并通过LLDP(链路层发现协议)协商成功。在i.MX平台上,启用流程如下:

  1. 启用MAC合并子层(MAC Merge Sublayer, MMS)

    ethtool --set-mm eth1 tx-enabled on pmac-enabled on verify-enabled off tx-min-frag-size 60
    • tx-enabled on: 启用发送方向的帧抢占。
    • pmac-enabled on: 启用预空MAC(Preemptable MAC)。
    • verify-enabled off: 关闭验证模式(初始配置时可关闭,后续验证时需要开启)。
    • tx-min-frag-size 60: 设置最小可抢占片段大小为60字节(不包括帧校验序列FCS)。这是标准推荐值。
  2. 配置队列的抢占属性:使用mqprioqdisc的fp(frame preemption)参数来指定哪些队列是“快速”队列(Express),哪些是“可抢占”队列(Preemptable)。

    tc qdisc add dev eth1 root handle 1: mqprio num_tc 5 \ map 0 1 2 3 4 \ queues 1@0 1@1 1@2 1@3 1@4 \ fp P E P E E \ hw 1
    • fp P E P E E: 这个字符串定义了每个TC的抢占属性,长度必须与num_tc一致。E表示快速队列(Express),P表示可抢占队列(Preemptable)。例如,这里TC0和TC2是可抢占的,TC1、TC3、TC4是快速的。注意:硬件要求至少有一个快速队列。
  3. 验证抢占状态:在两块背对背连接的板卡上都执行上述配置后,使用以下命令检查:

    ethtool --show-mm eth1

    查看输出中的verify statusactive字段。如果active显示为active,则表示链路两端的帧抢占能力已成功协商并激活。

5.2 帧抢占验证测试

  1. 生成混合流量:使用pktgen脚本同时向一个快速队列(如TC1)和一个可抢占队列(如TC2)发送流量。可抢占队列的包长可以设置得大一些(例如1500字节),以增加被抢占的概率。

    /usr/share/samples/pktgen/pktgen_twoqueue.sh -i eth1 -q 1 -s 150 -n 0 -m 90:e2:ba:ff:ff:ff # 这个脚本可能会同时向两个队列发流,或者需要修改以指定不同队列。
  2. 捕获与分析mPacket:使用支持mPacket解析的专业测试仪(如Spirent TestCenter)捕获链路流量。你将能看到标准的以太网帧被拆分成了“mPacket”。一个mPacket包含:

    • SMD(Start of Packet Delimiter): 标识这是一个mPacket的开始。
    • mPacket内容: 可能是一个完整的快速帧,或者是一个可抢占帧的片段。
    • 帧校验序列(FCS): 每个mPacket都有自己的FCS。 例如,SMD值为0xD5表示包含一个快速帧;0x4C表示包含一个可抢占帧的起始片段;0x52表示包含一个可抢占帧的后续片段,并带有片段计数。
  3. 查看硬件计数器:如果没有测试仪,可以通过内核统计信息间接验证。

    ethtool -S eth1 | grep -i fragment

    查找类似mmc_tx_fpe_fragment_cntr的计数器。如果其值在流量发送期间不断增加,说明发生了帧分割,即帧抢占正在工作。

5.3 Qbu与Qbv的联合测试

当Qbu和Qbv同时启用时,对于被标记为“可抢占”的队列,其Qbv的门控逻辑会发生变化。此时,不能简单地用S(SetGateStates)来开关门,而需要使用H(Hold)和R(Release)来控制。

  • H(Hold): 暂停所有可抢占队列的传输。
  • R(Release): 恢复所有可抢占队列的传输。

配置示例:

tc qdisc replace dev eth1 parent root handle 100 taprio \ num_tc 5 map 0 1 2 3 4 queues 1@0 1@1 1@2 1@3 1@4 \ base-time <basetime> \ sched-entry H 02 100000 \ sched-entry R 04 100000 \ flags 2

这个配置表示:在第一个100微秒窗口内,Holdgate_mask02(二进制00010,即TC1)所对应的可抢占队列(根据之前的fp设置,TC1是快速队列,所以不受影响;这里H作用于所有可抢占队列,与mask关系需查证,通常H/R控制所有可抢占队列,mask可能用于其他目的或忽略)。在第二个100微秒窗口内,Release所有可抢占队列。这样,可抢占队列的发送就被限制在了特定的时间窗口内,实现了与Qbv类似的调度效果,但控制粒度是所有可抢占队列一起。

实操心得:帧抢占的验证对链路两端设备有严格要求。务必确保对端设备(另一块开发板或交换机)也支持并启用了帧抢占。仅仅本端启用是无效的。在LS1028A上,如果使用其内部的以太网交换机(Switch)端口进行测试,需要确保交换机的相应端口也通过ethtool --set-mm swp0 tx-enabled on pmac-enabled on启用了合并(Merge)能力。初次调试时,建议先用ethtool --show-mm反复确认active状态为active,再开始流量测试。

6. Qci(流过滤与监管)配置与测试详解

Qci(每流过滤与监管)是TSN中的“交警”和“流量计”。它工作在网络入口(Ingress),可以对每个数据流(Stream)进行精细化的识别、计量和策略控制。一个完整的Qci处理管道包含三个模块:

  1. 流识别(Stream Identification): 根据MAC地址、VLAN ID、IP五元组等识别特定的流。
  2. 流过滤(Stream Filtering): 将识别出的流引导到对应的流门(Stream Gate)和流量计(Flow Meter)。
  3. 流门与流量计(Stream Gate & Flow Meter): 流门基于时间表控制流的通断;流量计(通常采用双令牌桶算法)对流的带宽进行监管,标记或丢弃超速的帧。

在LS1028A平台上,NXP提供了tsntool这个专用工具来配置复杂的Qci硬件表项,比通用的tc命令更直观。

6.1 基础环境与流识别设置

假设测试拓扑为:LS1028A RDB的eno0端口连接测试仪或另一台设备。LS1028A的MAC地址设置为10:00:80:00:00:00,对端设备MAC为99:aa:bb:cc:dd:ee

首先,启动tsntool交互式shell:

tsntool tsntool> verbose # 可选,开启详细输出

测试1:无流句柄的流过滤这是最简单的情况,所有未被其他规则匹配的“默认”流都走这条路径。

# 1. 创建一个流过滤器条目(索引2),并将其关联到流门条目2。 tsntool> qcisfiset --device eno0 --index 2 --gateid 2 # 2. 创建一个流门条目(索引2),初始状态为打开(1)。 tsntool> qcisgiset --device eno0 --index 2 --initgate 1

现在,从对端设备ping LS1028A,流量应该能通过(因为门是开的)。然后,将流门初始状态改为关闭(--initgate 0),再次ping,应该超时。通过qcisfiget --device eno0 --index 2可以查看该流过滤器的计数器,观察match(匹配次数)、pass(通过次数)、gate_drop(因门关闭而丢弃的次数)等。

6.2 基于MAC和VLAN的流识别

测试2:空流识别条目(Null Stream Identify)这种条目仅根据目的MAC和VLAN ID(可选)进行过滤。

# 1. 设置流门1为常闭 tsntool> qcisgiset --device eno0 --index 1 --initgate 0 # 2. 创建一个流识别条目(索引1),匹配目的MAC为10:00:80:00:00:00,VLAN ID为10(或任意,由--nulltagged决定) tsntool> cbstreamidset --device eno0 --index 1 --nullstreamid --nulldmac 0x000000800010 --nulltagged 3 --nullvid 10 --streamhandle 100 # --nulldmac: 目的MAC,格式为48位整数的十六进制低位表示。0x000000800010 对应 10:00:80:00:00:00。 # --nulltagged 3: 3表示“带tag或未带tag的帧都匹配”(1=仅匹配未tagged,2=仅匹配tagged)。 # --nullvid 10: 要匹配的VLAN ID,如果tagged为3,此字段可能被忽略或用于特定tagged帧匹配。 # --streamhandle 100: 一个用户定义的句柄,用于关联流过滤器。 # 3. 创建一个流过滤器条目(索引1),关联上述流识别(句柄100)和流门1。 tsntool> qcisfiset --device eno0 --streamhandle 100 --index 1 --gateid 1

配置完成后,从对端发送目的MAC为10:00:80:00:00:00的帧,会被流识别条目1匹配,然后交给流过滤器1,由于关联的流门1是关闭的,因此帧被丢弃(gate_drop计数器增加)。

6.3 流量计(FMI)测试

流量计用于限制流的带宽。LS1028A支持双令牌桶算法,包含承诺信息速率(CIR)、承诺突发大小(CBS)、超额信息速率(EIR)和超额突发大小(EBS)。

测试3:流量监管

# 1. 创建一个流过滤器条目2,并关联一个流量计条目2。 tsntool> qcisfiset --device eno0 --index 2 --gateid 2 --flowmeterid 2 # 2. 配置流量计条目2:启用颜色模式(--cm)和耦合标志(--cf),设置CIR=5Mbps, CBS=1500字节, EIR=5Mbps, EBS=1500字节。 tsntool> qcifmiset --device eno0 --index 2 --cm --cf --cbs 1500 --cir 5000 --ebs 1500 --eir 5000 # 3. 将关联的流门2设置为常开。 tsntool> qcisgiset --device eno0 --index 2 --initgate 1
  • --cm(颜色模式): 启用后,流量计会根据帧的TCI(Tag Control Information)中的颜色位(通常是DEI位)来判断帧是“绿色”还是“黄色”。绿色帧受CIR/CBS约束,黄色帧受EIR/EBS约束。如果不启用,所有帧都视为绿色。
  • --cf(耦合标志): 启用后,黄色帧的令牌桶计算会考虑绿色帧已使用的带宽,使得总带宽控制在CIR+EIR内。这是一种更灵活的整形方式。

配置完成后,从对端以高于10Mbps(CIR+EIR)的速率向eno0发送流量。通过qcifmiget --device eno0 --index 2查看流量计计数器,你会看到bytecount(总字节数)增加,但drop(丢弃计数)可能为0,因为总带宽(10Mbps)尚未超过。如果你将EIR调低,例如--eir 2000,那么总带宽变为7Mbps,此时发送10Mbps的流量,就会看到drop计数器开始增加,部分帧被丢弃。

排查技巧:Qci的配置较为复杂,表项(流识别、流过滤、流门、流量计)之间存在关联关系。调试时,务必遵循“自底向上”或“自顶向下”的逻辑。例如,可以先配置一个“常开”的流门和“不限速”的流量计,确保流识别和过滤能正常工作(帧能匹配并通过)。然后再逐步添加门控时间表或调低带宽限制,观察帧被丢弃或延迟的现象。大量使用tsntoolget命令(如qcisfiget,qcisgiget,qcifmiget)来查询配置和计数器状态,是定位问题的关键。

7. Qav(基于信用的整形器)配置与测试详解

Qav(也称为Credit-Based Shaper, CBS)是TSN中用于保证高优先级流量(如音频视频桥接流)低延迟和低抖动的关键机制。它不同于Qbv的严格门控,而是为每个队列维护一个“信用值”。发送数据包会消耗信用,信用为负时必须等待信用恢复为正才能发送,从而平滑了流量突发,限制了高优先级流的最大占用带宽。

7.1 Qav在i.MX平台上的配置(使用tc cbs)

在i.MX 8M Plus等平台上,使用tccbsqdisc来配置Qav。

  1. 首先设置mqprio,定义流量类别到硬件队列的映射

    tc qdisc add dev eth1 root handle 1: mqprio num_tc 5 \ map 0 1 2 3 4 \ queues 1@0 1@1 1@2 1@3 1@4 \ hw 0 # 注意:对于Qav,`hw`参数通常设为0,因为CBS整形可能在软件或混合模式下实现。
  2. 为特定队列(例如队列3,对应TC3)配置CBS参数,限制其带宽为20 Mbps

    tc qdisc replace dev eth1 parent 1:4 cbs \ locredit -1470 \ hicredit 30 \ sendslope -980000 \ idleslope 20000 \ offload 1
    • idleslope: 空闲斜率,单位是比特/秒。表示信用值增长的速度,即允许的平均带宽。20000表示 20,000 bps = 20 kbps?注意:这里文档示例是20000,但描述是20Mbit/s,可能存在单位混淆。通常idleslope应以bits per second为单位,20 Mbps 应为20000000。需要根据硬件数据手册确认。示例中可能用了简化值。
    • sendslope: 发送斜率,单位是比特/秒。表示发送数据时信用值下降的速度。计算公式为sendslope = idleslope - link_speed。对于1Gbps链路,sendslope = 20,000,000 - 1,000,000,000 = -980,000,000。示例中的-980000可能单位是kbps或存在笔误。
    • hicreditlocredit: 信用值的高低容限。它们与最大帧长和链路速度有关,用于计算信用值的上下界,防止信用值无限增长或减少。具体计算方式参考IEEE 802.1Q-2018标准。
    • offload 1: 尝试启用硬件卸载。
  3. 生成测试流量并测量带宽

    /usr/share/samples/pktgen/pktgen_sample01_simple.sh -i eth1 -q 3 -s 500 -n 3000

    脚本运行后会输出结果,查看Result:行中的带宽(如19Mb/sec)。你可能会发现实测带宽略低于设定的idleslope目标值(如19 Mbps vs 20 Mbps)。

  4. 理解带宽偏差:根据NXP文档提到的勘误(TKT0649448),实测带宽与目标带宽之间存在一个系统性的偏差,其公式为:实际带宽 = 目标带宽 * (1 – (12 / (8 + 平均包长)))其中,12字节是每个包增加的“额外开销”(可能包括帧间隔IFG等),8是以太网前导码和帧起始定界符的长度。对于一个500字节的包(平均包长 = 500),计算如下:实际带宽 = 20 Mbps * (1 – (12 / (8 + 500))) ≈ 20 Mbps * (1 – 0.02362) ≈ 19.528 Mbps这个结果与测试输出的19 Mbps接近。因此,在配置Qav时,如果需要精确的带宽,需要根据这个公式进行反推,设置一个略高的idleslope目标值。

7.2 Qav在LS1028A平台上的配置(使用tsntool)

在LS1028A上,使用tsntool配置Qav更为简洁,它直接使用百分比来设置带宽。

  1. 启用mqprio(同样需要):

    tc qdisc add dev eno0 root handle 1: mqprio num_tc 8 \ map 0 1 2 3 4 5 6 7 \ queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 \ hw 1
  2. 使用tsntool为流量类别设置带宽百分比

    tsntool cbsset --device eno0 --tc 7 --percentage 60 tsntool cbsset --device eno0 --tc 6 --percentage 20

    这表示TC7(最高优先级)的队列可以获得60%的链路带宽信用,TC6获得20%的带宽信用。剩余的20%带宽留给其他未配置CBS的队列(BE流量)。

  3. 验证带宽:使用pktgen向TC7和TC6对应的队列发送流量,并测量实际带宽。你应该能看到TC7的流量速率被限制在链路速度的60%左右,TC6被限制在20%左右。当同时发送时,它们应能共享链路,且高优先级(TC7)的流量抖动更低。

注意事项:Qav(CBS)通常用于保障高优先级、低数据量的实时流(如音频),而不是用于严格的带宽限制。它的目的是防止低优先级流量(如大量TCP备份)阻塞高优先级流量,通过信用机制平滑发送,从而降低最大帧延迟和抖动。在配置时,需要仔细规划每个优先级类别的idleslope或百分比,确保所有配置的CBS队列的idleslope之和不超过链路总带宽,否则会导致信用无法恢复,所有队列都被阻塞。