这是Linux网络优化系列的第四篇文章,也是最后一篇了。最近有点忙,没有抽出时间来梳理这些知识点,
看了下文章历史,这个优化系列文章前后持续了大半年时间,今天总算达成了目标*_*。
背景
自从互联网诞生以来, 音视频(Audio/Video,
AV)在网络上传输已经是稀松平常的事情. 那么,
为什么还需要一个新的基于以太网的协议来传输AV数据了?
传统的音视频传输都是点对点单向连接,
比如音频通常使用I2S或SPDIF/AES;
视频则使用SDI或者HDMI,
这种专用的单向连接在多设备情况下往往容易出现杂乱无章的连接线束:

为了解决上述问题, 满足音视频数据传输中低延迟/严格时间同步的需求,
解决音视频传输中丢包/传输延迟等问题,在2004年左右, IEEE
802.3小组接收了一个CFI(Call For Interest)有关将以太网用于低时延(Time-sensitive)的音视频传输的方案.
传统以太网是没有时间同步的, 而且由于网络链路存在难以预料的时延以及拥塞,
很难满足AV数据的传输要求,
为此IEEE专门成立了一个802.1 Audio/Video Bridging任务小组,
该小组开发出了一系列新的协议来解决上面碰到的问题,
即AVB(Audio/Video Bridging)协议族。AVB最开始是面向音视频数据传输,但其低延迟的特性使得AVB能很好的解决汽车领域中诸如娱乐座舱(摄像头/屏幕显示),车身控制以及自动驾驶等领域的问题。AVB核心的协议主要由如下三个标准协议组成:

IEEE 802.1AS-2011 (gPTP): 精确的时间同步(precise synchronization)- 支持对多媒体数据的流整形(
traffic shaping), 用于数据流均衡, 对应IEEE 802.1Qav-2009 (FQTSS, Forwarding and Queuing for Time-Sensitive Streams) - 带宽允许控制(
admission controls), 预分配足够的带宽用于AV数据传输, 即IEEE 802.1Qat-2010 (Stream Reservation Protocol, SRP), 由MMRP/MVRP/MSRP三个协议组成。
同时, AVB还提供两个传输层协议:
IEEE 1722-2011(AV Transport Protocol, AVTP)用于音视频数据的传输;IEEE 1722.1-2013(Device Discovery, Connection Management, and Control Protocol)用于AVB设备的发现与连接管理.
到2012年, 为了更好的体现AVB协议的核心理念: 通过IEEE
802(以太网)提供时间同步/低延迟的流媒体数据传输服务,
AVB被重新命名为TSN(Time-Sensitive Network),
后续所有的标准化工作都在IEEE 802.1 TSN小组展开.
随着近年来智能座舱概念的落地, 在汽车中引入更多娱乐设备, 比如扬声器,
摄像头, 甚至直播设备逐渐成为未来的趋势.
加之车载以太网从原来的100Mbps成熟演变到如今的1Gbps,
以太网已经成为车上各个域控制器的相互通讯的标准接口,
成为将车上各种设备如摄像头,扬声器,自动驾驶控制器等相互连接的方式,因此可以预见,
AVB/TSN会成为车载娱乐领域/自动驾驶相关的支撑技术而得到更为广泛的应用.
AVB协议
AVB协议基于MAC层(L2)改进而来,
发送AV数据的设备称为Talker,
而接收AV数据的设备则称为Listener.
接受端与发送端应用基于AVB通讯时(一个Talker可能对应多个Listener,
因此实际上AVB的数据流都是多播数据,
通常需要通过VLAN对数据流进行分组), 不再通过TCP/IP协议栈,
而是直接用RAW SOCKET与MAC层进行通讯,
与TCP/IP的实现不同,AVB协议都是在用户空间中实现的:

接下来, 我们就重点来看看AVB三个核心协议的具体是如何工作的.
时间同步-gPTP
AVB设备需要通过一个基准时钟定时同步时间信息,
以确保多个数据流的时间严格同步,
同时保证数据的发送与接收处于相同的时间序列.
这个用于精确时间同步的协议就是IEEE 802.1AS gPTP(generic Precise Time Protocol),
gPTP实际是另一个时间同步协议IEEE 1588
PTP的子集.
IEEE 802.1AS gPTP与IEEE 1588 PTP的区别在与,
gPTP假定所有的节点的通讯都是基于IEEE 802 MAC的PDU格式以及寻址,
而PTP可以支持从MAC层(L2)到L3/L4的通讯协议. 对于gPTP来说,
在一个时间同步域(timing domain,
遵循gPTP标准并使用其同步时间的所有设备构成一个同步域)内,
有一个设备提供主时钟信号, 为其他所有设备提供参考时钟,
这个设备被称为Grand Master Clock(GMC).
对于gPTP协议来说, 有两个问题需要解决:
- 如何选择
Grand Master Clock? - 各个通讯节点如何同步时间?
一般来说,
Grand Master Clock设备可以在连接初始化时动态选择也可以预先配置(对车载网络来说,
可以选择静态配置的方式, 通常选择网关作为Grand Master).
动态选择需要通过BMCA(Best Master Clock selection Algorithm).BMCA是一个分布式算法,
其工作原理大致是:
每个可做Grand Master的节点收到announce消息后,
比较自身时间与当前最好的Grand Master时间之间的质量值(如何衡量时间相关的质量值?),
如果8次不同的评价产生了一个比当前Grand Master时钟更好的时间值,
则完成Grand Master选择过程,
该节点宣称自己成为Grand Master.
AVB设备在物理连接建立的过程中, 会交换设备的能力信息,
如果对端设备支持PTP, 则两个设备会开始同步时钟,
否则就形成一个时间同步域(该过程通过生成树算法完成):

要同步各个节点的时间, 首先,
每个网络节点需要知道消息在网络中传递的延迟,
在gPTP协议中有一个被称为pDelay衡量的过程:
确保节点都能准确知道其与邻近节点的消息传播延迟.
为了得到准确的pDelay值,
最好利用网卡硬件的时间戳而不是软件时间来进行时间采样.
时间同步的最后关键一步是,
Grand Master需要发送sync/folow-up两个消息来完成与各个节点的时间同步.
gPTP的整个功能如下图所示:

带宽预留-SRP
IEEE 802.1Qat Stream Reservation Protocol(SRP)用于AVB网络中各个节点预分配带宽以满足音视频数据传输带宽的要求.
其大致流程是,
Talker(数据发送节点)会发送广播消息到其他AVB节点,
告知有可用的数据流;
如果某个Listener(数据接收节点)需要接收数据流,
同样需要广播该消息,
如此所有节点(包括switch)会预留足够的带宽以确保数据流可以通过.如果预留失败,
则SRP的带宽预留请求失败. 通常,
对于A类(class A, 优先级最高)流量可以最多预留50%的带宽;
B类流量(class B)流量预留20%的带宽.
对于车载应用来说, SRP预留带宽失败是不可接受的(万一此时有摄像头需要传递比较关键的ADAS数据就悲剧了), 因此可以采取静态预留带宽的方式, 由各个节点在网卡初始化时提前预留带宽.
对于带宽预留请求而言,
只需要一个唯一的64bit的stream ID即可;
stream ID通常由Talker的MAC地址,
一个16bit由Talker分配的数值以及该stream的质量数据(包括数据流类型,
包速率以及每个包的长度)组成.
下图是非压缩的立体声音频数据在不同数据流类型下所需要预留的带宽:

SRP协议使用了一组协议, MMRP(Multiple MAC Registration Protocol)(以太网协议ID为0x88F6)用于控制分组注册,
MVRP(Multiple VLAN Registration Protocol)(协议ID为0x88F6)用于VLAN组成员管理,
MSRP(Multiple Stream Registration Protocol)(协议ID为0x22EA)用于数据流带宽的预留.
数据流整形-FQTSS
AVB要求数据包在传输过程中不能出现丢包,
因此就要求网络中各个节点确保AVB数据包进行高效/快速(确保延迟满足要求)转发,
同时为了能够有效利用带宽,保证普通的数据包(Best Effort)与AVB数据直接的公平性,引入了IEEE 802.1Qav Forwarding and Queuing for Time-Sensitive Streams(简称FQTSS)协议。FQTSS主要用于流整形(traffic shaping),
其基于基于信用的流整形(credit-based shaper)的算法,对数据流进行排队与转发;
通常来说, AVB流量优先级要高于普通流量,
而AVB中的A类流量优先级又要高于B类流量。
下图是CBS算法的一个示意图,AVB数据与非AVB数据(Best Effort, BE)的传输都受到当前credit值的影响:
- 当credit >= 0时,如果没有AVB数据,
credit就会设为0;
否则持续发送AVB数据直到credit的值变为负(根据sendSlope开始减小)
- 当credit < 0时, 发送普通的BE类数据,
credit会基于idleSlope不断累积直到等于0 -
credit的变化由sendSlope以及idleSlope两个值确定,
sendSlope与idleSlope的关系如下:
1 | sendSlope = idleSlope − portTransmitRate |
这里portTransmitRate即端口的理论速率,
比如对于1000Mbps网络来说,该值为10000bit/s。

Linux的网络驱动中增加了一个CBS的流量控制模块(代码路径kernel/net/sched/sched_cbs.c),
支持软件模拟网关中硬件的CBS算法,
同时还可以将算法卸负(offload)到网卡。
详细信息也可以参考http://manpages.ubuntu.com/manpages/bionic/man8/tc-cbs.8.html.
Open-AVB
早在2013年左右, TSN标准化机构AVNU开发了一套开源的AVB协议栈openAVB,
其实现了常见的AVB协议,
如gPTP/SRP/FQTSS/AVTP/AVDECC等。基于这套协议,
我们可以开发自己的AVB应用,
更多有关该AVB协议开发的一些信息可以参考官方文档Open-AVB
AVTP Pipeline SDK.