本文介紹了TSN協議的基本原理及其在VxWorks上的實現和使用方法。
0. 參考
- IIEEE 1588 Precision Time Protocol (PTP)
- PTP時鐘協議原理
- 車載以太網AVB簡介—第二篇:gPTP簡介
- 傳統以太網和時間敏感網絡TSN的區別
- 下一代工業通信—TSN(時間敏感網絡),工業物聯網的助推器
- H3C TSN技術白皮書
- IEEE TSN Task Group主頁
- VxWorks_7_Time-Sensitive_Networking_Programmer_s_Guide
1. 基本概念
- TSN:時間敏感網絡,基于802.1AVB演化而來,通過 IEEE 802 網絡提供確定性服務,即保證具有有限低延遲、低數據包延遲變化和低數據包丟失的數據包傳輸。
-
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
- 頻率同步原理如下所示,其中從設備時鐘頻率調整因數為
- 相位同步原理如下(以TwoStep模式為例,OneStep模式中sync報文包含t1,所以不需要Follow_up報文), 其中傳輸延時delay為
- 802.1AS/gPTP Standard:IEEE1588協議的一個簡化版二層Profile,又稱為gPTP,通過將大量不同的IEEE1588選項縮小到可管理的幾個關鍵選項,從而適用于汽車或工業自動化環境。注意, gPTP和PTP的同步原理類似,除了只支持TwoStep和P2P模式,具體可參考車載以太網AVB簡介—第二篇:gPTP簡介。
- 802.1Qbv Standard:支持調度流量的增強,即通過規定時間感知隊列的消耗方式,為傳輸幀分配不同優先級的虛擬局域網(VLAN)標簽,使得網橋和終端能夠根據源自IEEE802.1AS時間同步幀對傳輸進行調度,從而允許同時支持計劃流量、基于信用的整型器流量和其他通過局域網(LAN)的橋接流量。
- 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支持BMCA和AVnu 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)