VxWorks 7 TSN协议栈实现

作者: 古斟布衣 | 来源:发表于2022-07-29 11:44 被阅读0次

    本文介绍了TSN协议的基本原理及其在VxWorks上的实现和使用方法。

    0. 参考

    1. 基本概念

    1. TSN:时间敏感网络,基于802.1AVB演化而来,通过 IEEE 802 网络提供确定性服务,即保证具有有限低延迟、低数据包延迟变化和低数据包丢失的数据包传输。
    2. IEEE1588v2/PTP: 一种精确时间协议PTP(Precision Time Protocol),包括IEEE1588v1和IEEE1588v2两个版本。该标准适用于通过支持多播信息传递的局域网进行通信的系统,包括但不限于以太网。该协议支持亚微秒级(100纳秒)的全系统同步精度,可以映射到UDP/IP、DeviceNet和第二层以太网即链路层。PTP基本原理包含频率同步和相位同步:
      • 相位同步原理如下(以TwoStep模式为例,OneStep模式中sync报文包含t1,所以不需要Follow_up报文), 其中传输延时delay((t2 - t1) + (t4 - t3)) / 2,相位偏差offset(t2 - t1) -传输延时delay,即((t2 - t1) - (t4 - t3)) / 2
        image.png
        • 频率同步原理如下所示,其中从设备时钟频率调整因数为(T(n+1) - Tn) / (T(n+1)' - Tn')
          image.png
    3. 802.1AS/gPTP Standard:IEEE1588协议的一个简化版二层Profile又称为gPTP,通过将大量不同的IEEE1588选项缩小到可管理的几个关键选项,从而适用于汽车或工业自动化环境。注意, gPTP和PTP的同步原理类似,除了只支持TwoStep和P2P模式,具体可参考车载以太网AVB简介—第二篇:gPTP简介
    4. 802.1Qbv Standard:支持调度流量的增强,即通过规定时间感知队列的消耗方式,为传输帧分配不同优先级的虚拟局域网(VLAN)标签,使得网桥和终端能够根据源自IEEE802.1AS时间同步帧对传输进行调度,从而允许同时支持计划流量、基于信用的整型器流量和其他通过局域网(LAN)的桥接流量。
    5. 802.1Qbu Standard:规定IEEE802.1AS时间同步帧的抢占原则,允许桥接端口在传输一个或多个时间关键帧时暂停非时间关键帧的传输,并为网桥端口和终端设备提供发现、配置和控制抢占服务的功能,降低关键帧的传输延迟。

    2. VxWorks7 TSN

    2.1 概述

    VxWorks 7通过TSN、PTP和GPTP等3个layer提供TSN支持,并依赖于END、IPNET_COREIP和UTILS_JANSSON等3个layer。其中,TSN栈位于net\tsn-2.0.2.2目录,包括时钟、Qav/Qbv、Stream和配置等4个部分以及对应的demo,同时通过_WRS_CONFIG_TSN_STREAM和_WRS_CONFIG_TSN_CONFIG在IPNET等layer中引入相关修改。

    TSN设备驱动包括网口驱动和1588定时器驱动两部分,其中1588定时驱动位于net\end-2.0.3.3\drv\src\1588目录中,网口驱动位于PSL或者net\end-2.0.3.3\drv\src\end目录中。

    2.2 TSN配置

    TSN使用JSON文件作为配置来源并通过tsnConfig接口或者shell命令对指定的TSN网口进行配置,示例如下:

    {
        "schedule": { // Schedule timing is mandatory
            "cycle_time": 1000000, // Cycle time is 1000 usecs.(门控列表调度执行周期)
            "start_sec": 0, // Schedule starts at { start_sec, start_nsec }
            "start_nsec": 0
        },
        "preemption": { // Preemption enabled (optional)
            "tclass_mask": 0x01 // Traffic class mask. TC 0 is preemptible, other TCs are express.
        },
        "gate_control_list": [ // 802.1Qbv gate control list (optional).
            // Total gate time must be equal to cycle time.
            {
                "tclass_mask": 0x80, // Traffic class mask. Only TC 7 can transmit.
                "time": 100000 // Gate time 100 usec, opens at 0 usec for first gate.
            },
            {
                "tclass_mask": 0x40, // Only TC 6 can transmit.
                "time": 200000 // Gate time 200 us, opens at 100 usec.
            },
            {
                "tclass_mask": 0x3f, // TC 0-5 can transmit. Use for "best-effort" traffic.
                "time": 700000 // Gate time 700 usec, opens at 300 usec.
            }
        ],
        "stream_objects": [ // At least one stream object is mandatory
            {
                "stream": {
                    "name": "flow1",
                    "dst_mac": "01:c0:ff:ee:00:04", // Muticast MAC address
                    "vid": 3000, // VLAN ID
                    "pcp": 7, // normally pcp==tclass
                    "tclass": 7, // Stream maps to TC 7.
                    "tx_time": { // Transmission time based scheduling (optional), 
                                 // usually no gate control list should be defined
                        "offset": 50000 // Stream transmits at 50 usecs.
                    }
                }
            },
            {
                "stream": {
                    "name": "flow2",
                    "dst_mac": "01:c0:ff:ee:00:05",
                    "vid": 3001,
                    "pcp": 6,
                    "tclass": 6 // Stream maps to TC 6, transmitting in 100-300 usec window.
                },
                "ip": { // IP interception (optional)
                    "dst_ip": "192.168.1.11",
                    "dst_mask": "255.255.255.255",
                    "dst_port": 0, // available when proto == 6 or 17
                    "src_ip": "192.168.1.10",
                    "src_mask": "255.255.255.255",
                    "src_port": 0, // available when proto == 6 or 17
                    "proto": 0 // IP protocol number. e.g. UDP: 17, TCP: 6
                }
            }
        ]
    }
    

    2.3 TSN时钟和定时器

    TSN时钟和定时器功能依赖于TSN、PTP和GPTP等3个layer,其核心文件包括:

    • net\tsn-2.0.2.2\src\clock\src\tsnClkLib.c
    • net\tsn-2.0.2.2\src\clock\h\tsnClkLib.h
    • net\end-2.0.3.3\drv\src\1588\vxbIeee1588.c

    TSN 1588定时器驱动通过ioctl提供PTP硬件时钟寄存器(PHC)的获取/设置和1588 timer的分配、释放、中断回调挂接、中断路由、周期/one-shot模式切换等功能,并通过TSN layer的tsnClkLib提供用户接口。

    每个TSN网口通常支持2个1588定时器。

    2.3.1 PTP启动

    master和slave端都需要使用ptpdAdd()为相应网卡绑定PTP协议,并使用ptpSart()启动PTP:

    /******************************************************************************
    *
    * ptpdAdd - bind ptpd to Ethernet interface
    *
    * This function is used to bind ptpd to different Ethernet interfaces.
    *    ethName       the Ethernet device name. For example, "gei0".
    *    layer         transport layer PTP_DEVICE_LAYER_2 or PTP_DEVICE_LAYER_4
    *    slaveMaster   0=SLAVE, 1=MASTER, 2 (others)= BMCA
    *    delayMechanism 0=PTP_DEVICE_E2E  or 1=PTP_DEVICE_P2P
    *    oneStepMode    0=PTP_DEVICE_TWO_STEP or 1=PTP_DEVICE_ONE_STEP
    *    pri          PTP Priority When Configured as Master Clock
    *    PdelayReq    PTP Pdelay Request Interval,reciprocal of N times of power of 2,
    *                 (1 ~ -4) means (0.5PPS ~ 16PPS)
    *    profile     Select ptp profile 1=PTP_802_1AS_PROFILE or 0=PTP_DEFAULT_PROFILE
    * RETURNS: PTP_OK or PTP_ERROR
    *
    * ERRNO: N/A
    */
    

    例如,

    # ethName("gei1")、transport layer(2)、master mode(1)、delayMechanism(PTP_DEVICE_P2P)、
    # oneStepMode(PTP_DEVICE_TWO_STEP)、PTP Priority(128)、PTP Pdelay Request Interval(8PPS)
    # profile(PTP_802_1AS_PROFILE)
    -> ptpdAdd "gei1",2,1,1,0,128,-3,1 # 
    
    # ethName("gei1")、transport layer(2)、slave mode(0)、delayMechanism(PTP_DEVICE_P2P)、
    # oneStepMode(PTP_DEVICE_TWO_STEP)、PTP Priority(128)、PTP Pdelay Request Interval(8PPS)
    # profile(PTP_802_1AS_PROFILE)
    -> ptpdAdd "gei1",2,0,1,0,128,-3,1
    

    使用方法为在master和slave侧运行如下命令:

    # master
    -> ptpdStop "gei0"
    -> ptpdClearAll
    -> ptpdAdd "gei0",2,1,1,0,128,-4,1
    -> ptpdStart
    -> ptpdSetDebugLevel "gei0", 1
    
    # slave
    -> ptpdStop "gei1"
    -> ptpdClearAll
    -> ptpdAdd "gei1",2,1,1,0,128,-4,1
    -> ptpdStart
    -> ptpdSetDebugLevel "gei1", 1
    

    成功时打印如下信息:

    AVnu AP Status : STATION_STATE_AVB_SYNC
    

    命令中的核心参数组合如下所示:

    模式 Master参数
    layer-Master-P2P-onestep-pri-PPS-profile
    Slave参数
    layer-Master-P2P-onestep-pri-PPS-profile
    结果
    Master competition 2,1,1,0,128,-4,1 2,1,1,0,128,-4,1 MAC小的成为Best Master,另一个成为passive master
    BMCA 2,2,1,0,128,-4,1 2,2,1,0,128,-4,1 1)MAC小的成为Best Master,另一个成为Slave
    2)收敛时间小于7秒
    BMCA Priority 2,2,1,0,1,-4,1 2,2,1,0,128,-4,1 1)优先级高(数字小)的成为 Master
    2)收敛时间小于7秒
    802.1AS with TwoStep 2,1,1,0,128,-4,1 2,0,1,0,1,-4,1 Offset from Master小于1微秒
    802.1AS with OneStep 2,1,1,1,128,-4,1 2,0,1,1,128,-4,1 IEEE802.1AS只支持TwoStep
    802.1AS with 4 layer 4,1,1,0,128,-4,1 4,0,1,0,128,-4,1 IEEE802.1AS只支持2 layer
    802.1AS with E2E 2,1,0,0,128,0,1 2,0,0,0,128,0,1 IEEE802.1AS只支持P2P
    no 802.1 AS,2 layer,P2P,TwoStep 2,1,1,0,128,-4,0 2,0,1,0,128,-4,0 1)Offset from Master小于1微秒
    2)收敛时间小于30秒
    no 802.1 AS,2 layer,E2E,TwoStep 2,1,0,0,128,0,0 2,0,0,0,128,0,0 1)Offset from Master小于1微秒
    2)收敛时间小于35秒
    no 802.1 AS,4 layer,P2P,TwoStep 4,1,1,0,128,-4,0 4,0,1,0,128,-4,0 1)Offset from Master小于1微秒
    2)收敛时间小于35秒
    no 802.1 AS,4 layer,E2E,TwoStep 4,1,0,0,128,0,0 4,0,0,0,128,0,0 1)Offset from Master小于1微秒
    2)收敛时间小于35秒

    2.3.2 gPTP启动

    master和slave端都需要使用daemon_cl()为相应网卡绑定gPTP协议并启动gPTP dameon,格式如下所示:

    void VxDaemonParam::print_usage( char *arg0 ) {
        printf( "%s <network interface> [-R <priority 1>] "
                "[-E] [-V] [-GM] [-INITSYNC <value>] "
                "\n",
                arg0 );
        printf
            ( "\t-R <priority 1> priority 1 value\n"
              "\t-E enable test mode (as defined in AVnu automotive profile)\n"
              "\t-V enable AVnu Automotive Profile\n"
              "\t-GM set grandmaster for Automotive Profile\n"
              "\t-INITSYNC <value> initial sync interval (Log base 2. 0 = 1 second)\n"
            );
    }
    

    其中:

    • gPTP支持BMCAAVnu Automotive两种互斥的模式,通过-V参数选择;
    • BMCA模式仅支持-R参数。

    使用方法为在master和slave侧运行如下命令:

    # master
    > daemon_cl("gei0 -V -E -GM")
    # slave
    > daemon_cl("gei1 -V -E")
    

    成功时打印如下信息:

    AVnu AP Status : STATION_STATE_AVB_SYNC
    

    命令中的核心参数组合如下所示:

    模式 msater参数 salve参数 结果
    Normal Configuration for GM for automotive profile -V -E -GM -V -E OK
    Normal configuration for GM without test mode -V -GM -V Fail
    Normal configuration with -INITSYNC -V -E -INITSYNC -3 -GM -V -E -INITSYNC -3 OK
    Normal configuration with -INITSYNC without test mode -V -INITSYNC -3 -GM -V -INITSYNC -3 Fail
    Normal configuration with -INITSYNC without test mode -V -INITSYNC -3 -GM -V -INITSYNC -3 Fail
    Normal configuration in BMCA mode -R 1 -R 248 Fail
    All devices in BMCA mode with default priority1 NA NA Fail
    All devices in BMCA mode, one with specified priority1, another with default priority1 -R 1 NA Fail
    One device with fixed GM, one in BMCA mode -V -E -GM -R 248 Fail

    综上所述,只有两种参数组合能够在VxWorks下通过测试:

    • 包含测试模式的自动化Profile:-V -E -GM/-V -E
    • 包含测试模式和初始同步间隔的自动化Profile:-V -E -INITSYNC -3 -GM/-V -E -INITSYNC -3

    2.3.3 获取PTP时间

    用户可以通过tsnClockIdGet() 获得1588定时器的描述符,然后通过tsnClockTimeGet() 获得PTP时间:

    clockid_t cid;
    struct timespec tm;
    cid = tsnClockIdGet("gei",0,0);
    if (cid != 0)
        {
        ret = tsnClockTimeGet (cid, &tm);
        }
    

    2.3.3 定时器操作

    用户可以对PTP定时器采用普通定时器类似的操作,包括:

    tsnTimerAllocate()
    tsnTimerRelease()
    tsnClockConnect()
    tsnClockDisable()
    tsnClockEnable()
    tsnClockRateGet()
    tsnClockRateSet()
    tsnClockIntReroute()
    

    2.4 802.1Qbv

    VxWorks通过如下两种方式来使能802.1Qbv:

    • Time Specific Departure (TSD)
    • Time Gated - IEEE 802.1Qbv

    2.4.1 TSD

    TSD使用户能够指定何时可以传输一个帧。当这种能力被启用时,设备将延迟帧的传输,以便它可以 在精确指定的时间内传输。TSD是在具有最高优先级的队列7上启用的。目前,TSN流量将通过队列7,其他流量将通过队列0。

    与此同时,多队列和VLAN也被实现。对于多队列,有8个Tx 队列(0~7)和一个Rx队列(0)。对于VLAN,并网口支持的所有VLAN功能都被启用。只有TSN流所要求的功能被启用。

    Queue No Priority Traffic Class (TC)
    0 0 0
    1 1 1
    ... ... ...
    7 7 7

    TSD存在如下限制:

    • 周期和时隙是由TSN流库维护的。由于软件延迟,一个数据包有可能错过它的时隙。
    • 尽管网卡可能支持多达16个Tx队列和8个流量类别(TC),但为了保证TSD的性能,只有最高优先级的队列(具有TC7的队列7)才被使用。所以多个TSN流共享同一个Tx队列。
    • 有必要使用ETF(Earliest TxTime First)来确保所有来自不同数据流(通常来自不同Task)的报文按照Tx时间的先后顺序存在于Tx队列中。
    • TSD只允许在一个周期的时隙内,从一个流中发送一个数据包。如果希望在一个时间段内发送多个数据包,需要将多个流与一个应用程序绑定在一起。

    注意:ETF依赖于IPNET_QOS

    2.4.2 Time Gated - IEEE 802.1Qbv

    IEEE 802.1 Qbv中规定的时间感知整形器(TAS),也被称为时间门控,允许每个流量类别的传输相对于已知的时间尺度进行规划。允许每个流量类别的传输相对于一个已知的时间颗粒来安排。为了 为了实现这一目标,每个流量类别都有一个传输门,传输门的状态决定是否排队和可以选择排队的帧进行传输。传输门门可以处于如下两种状态之一:

    • 打开:根据与流量类别相关的传输选择算法的定义,排队的帧被选择用于传输。
    • 关闭:排队的帧不被选择用于传输。
      门控列表如下所示:
    0 1 2 3 4
    持续时间(ns) 100000 200000 100000 300000 300000
    TC0 1(开放) 0(关闭) 0(关闭) 0(关闭) 1(开放)
    TC7 0(关闭) 1(开放) 0(关闭) 0(关闭) 0(关闭)
    TC6 0(关闭) 0(关闭) 1(开放) 0(关闭) 0(关闭)
    TC5 0(关闭) 0(关闭) 0(关闭) 1(开放) 1(开放)
    • 与一个端口相关的门控列表(GCL)包含一个有序的门操作列表。
    • 每个门操作都指定了所有门的门控状态和这些状态的持续时间,以及可以在开放期间传输的TC。
    • 如果没有配置新的GCL,当前的GCL将从每个周期的第一个门开始循环。因此,门的时间之和必须小于或等于周期时间。
    • 如果配置了一个新的GCL,它不会立即生效,而会等到旧GCL的当前周期结束。

    如上所述,使用IEEE 802.1Qbv,可以消除TSD的许多限制:

    • 通过硬件控制周期和闸门,消除软件造成的延迟,从而提供最佳的性能。
    • 8个Tx队列和相应的8个流量类别得到了充分的利用。
    • 每个流可以有其专用的Tx队列、优先级和流量类别,从而消除了顺序错误的数据包的问题。
    • 只要门的周期足够长,在一个门中为一个流发送数据包就没有限制。

    2.4.2.1 配置

    配置可以通过2.2 TSN配置提到的JSON配置文件方式配置,也可以组合使用如下接口进行配置:

    tsnStreamCreate()
    tsnStreamDeviceSet()
    tsnStreamCycleStartSet()
    tsnStreamPeriodSet()
    tsnStreamOffsetSet()
    tsnStreamVidSet()
    tsnStreamPcpSet()
    tsnStreamDstSet()
    

    配置完成之后,可以通过如下3种方式在TSN流上进行数据收发:

    • 套接字绑定,即创建一个通用UD/TCP套接字并绑定到TSN流。
    • IP截获,即通过配置到每个TSN流中的一组IP参数过滤所有UD/TCP套接字。
    • 链路层载荷,使用TSN流直接发送以太网数据包的载荷。

    2.4.2.3 套接字绑定方式数据收发

    发送端套接字采用如下方式与TSN流绑定后,发出的报文即可自动添加TSN需要的报文头,例如VLAN头,同时按照配置好的规则发送出去:

    setsockopt(socketFd, SOL_SOCKET, SO_X_QBV, (void*)streamName, TSN_STREAMNAMSIZ)
    

    注意SO_X_QBV相关功能在RTNET中不支持,需要1~3天的移植工作量。

    接收端不需要进行绑定,一般只需要添加VLAN对应的多播地址和设置VALN接口,并使用setsockopt()设置SO_TIMESTAMPING/SOF_TIMESTAMPING_RX_HARDWARE控制。与此同时,还需要支持对应的SO_TIMESTAMP报文类型。 注意SO_TIMESTAMP相关功能在RTNET中不支持,需要3~5天的移植工作量。

    2.4.2.4 IP截获方式数据收发

    IP截获是动态可改变的,比套接字绑定方式更灵活:

    • 当套接字处于运行状态时,IP截获可以被启用、禁用或者替换为新的过滤器。
    • IP截获可以提前于套接字建立。

    发送端可以通过2.2 TSN配置提到的JSON配置文件方式或者如下接口来设置过滤器:

    tsnStreamIpDstSet()
    tsnStreamIpSrcSet()
    tsnStreamIpPortSet()
    tsnStreamIpProtoSet()
    tsnStreamIpAccessEnable()
    

    接收端不需要使能IP截获,一般只需要添加VLAN对应的多播地址和设置VALN接口,并使用setsockopt()设置SO_TIMESTAMPING/SOF_TIMESTAMPING_RX_HARDWARE控制。与此同时,还需要支持对应的SO_TIMESTAMP报文类型。

    2.4.2.5 链路层载荷方式数据收发

    发送端只需要调用endPoolTupleGet()从END驱动中获取mBlk,拷贝数据,填写以太网报文类型,并将mBlkPktHdr.streamCookie指向TSN流,就可以通过muxSend()发送,TSN需要的报文头会自动添加。

    接收端只需要添加VLAN对应的多播地址,并使用muxBind()绑定接收回调函数即可。

    2.5 Frame pre-emption - 802.1Qbu

    帧抢占是为了中断长帧的传输以支持高优先级的 帧。一旦高优先级的流量通过,被中断的帧的剩余部分就可以传输。

    发送端接收端可以通过如下方式设置指定端口的优先级向量,为每个TC选择使用高优先级还是低优先级队列发送:

    muxIoctl (pEnd, EIOCSQBU, (caddr_t)(unsigned long)tcVec) 
    

    相关文章

      网友评论

        本文标题:VxWorks 7 TSN协议栈实现

        本文链接:https://www.haomeiwen.com/subject/vmfyuktx.html