gPTP协议

gPTP协议

一、背景

车载领域要求网络中设备保持时间同步,不再纠结原因。
需要解决以下问题:

  • 1、时间基准,即主时钟。
  • 2、主时钟定期发布同步信号。
  • 3、其他时钟根据同步信号同步自己的本地时钟。
    同步本地时钟有两方面:
    a、绝对时间同步,又称为相位同步。(即两个表的指针位置一模一样)
    b、频率同步。(即两个表的指针转的一样快)

二、体系结构

在这里插入图片描述
一个主时钟(Grandmaster Clock),它是标准时间的来源;
其他的都是从时钟(Slave Clock),它们必须把自己的时间和主时钟调整一致。
它包含两种类型的节点:

  • 1、Time-aware end station:它可以是主时钟(时间源,Grandmaster),也可以是从时钟(被校时的设备)。
  • 2、Time-aware Bridge:它可以是主时钟,也可以仅仅是个中转设备(交换机),连接网络内的其他设备。作为中转设备,它需要接收主时钟的时间信息并将该信息转发出去(在转发的时候,需要矫正链路传输时延和驻留时间)

三、主时钟选取

gPTP中的主时钟,既可以预先指定,也可以通过BMCA(Best Master Clock Algorithm) 动态选取。

  • 1、预先指定
  • 2、BMCA(Best Master Clock Algorithm)是gPTP的主时钟选择机制。在系统启动之初,所有设备都可以通过发送Announce报文,参与Grandmaster的“竞选”,Announce报文中含有参选设备的时钟信息(相当于竞选宣言),一旦参选设备发现自己的时钟不具备优势,就会主动退出主时钟竞选。BMCA是一种“能者优先”机制,获胜选出的Grandmaster一般具有更高精度的本地时钟,并能够和世界时保持同步(如GPS同步)。

四、绝对时间同步

在这里插入图片描述

五、频率同步

在这里插入图片描述
频率比=(t9-t5)/(t10-t6)
我要求master和slave两边跑得一样快,
即频率比为1。
如果大于1,说明请求方走得慢,如果小于1,说明走的快。请求方可以根据该值将自己的计时值转化为基于应答方时基的计时值。

六、gPTP-时间同步

在这里插入图片描述
ta =t1+delay+(tb−t2)∗频率比

七、gPTP-报文

802.1AS包括两种类型(Message class)General message和Event message,二者的区别在于,发送或接收Event message时,相应的时间戳会被记录,而General message则不会。General message包括Announce、Signaling、Follow_Up、Pdelay_Resp_Follow_Up,Event message包括Sync、Pdelay_Req、Pdelay_Resp。

在这里插入图片描述
Announce报文包含时钟相关信息,并且传输中,会记录途径的各PTP节点的Id添加到path trace TLV中;
Signaling报文包含该PTP节点支持的信息,比如是否支持“一步法”、允许的Announce Interval等;
Sync报文由GrandMaster发送,包含主时钟信息,其他节点计算本地时钟与主时钟的差值,实现同步;
Follow_Up以及Pdelay_Resp_Follow_Up则是“两步法”中提供补充时间戳的报文,前者与Sync连用,后者与Pdelay_Resp连用;
Pdelay_Req与Pdelay_Resp一起构成P2P测量机制的基础。

“一步法”

所谓“一步法”(也称为“on-the-fly”)是指在发送报文的同时,将在接近物理层的发送时间戳添加到报文中直接发送出去,这样将所需要的信息放在一帧报文中,更加高效,但是需要额外的硬件支持。对于接收节点,同样需要对“一步法”报文解析的能力。
在这里插入图片描述
与之相对的是“两步法”,这种方法仅在Sync或Pdelay_Resp报文发送时记录发送时间戳,再把这一信息封装在Follow_Up或Pdelay_Resp_Follow_Up报文中发送,从而在不需要额外的硬件支持下获得精确的时间戳。

八、影响校时因素

1、传输时延不对称。

gPTP对策:
要求网络内的节点都是时间敏感的;
传输延时分段测量(P2P方式)减少平均误差;
中间转发节点可以计算报文的驻留时间,保证校时信号传输时间的准确性;
如果已知链路不对称,可以将该值写在配置文件中,对于endpoint,在校时的时候会把该偏差考虑进去;对于bridge设备,在转发的时候,会在PTP报文的矫正域中(correctionField)把对应的差值补偿过来。

2、驻留时间:从接收报文到转发报文所消耗的时间

gPTP对策:
Bridge设备必须具有测量驻留时间的能力,在转发报文的时候,需要将驻留时间累加在PTP报文的矫正域中(correctionField)。

3、时间戳采样点

为了达到高精度的时间同步,必须消除软件带来的不确定因素,这就要求必须把时间采集点放在最靠近传输介质的地方。
gPTP对策:
比较合适的采集点就是MAC层:在发送方,当报文离开MAC层进入PHY层的时候记录当前时刻;在接收方,当报文离开PHY层刚到达MAC层的时候记录当前时刻。这样可以消除协议栈带来的不确定性。
MAC时间戳可以通过软件的方式打,也可以通过硬件的方式打,硬件方式会更精确(可以消除系统调度带来的不确定性)。gPTP中要求使用硬件方式,也就是常说的硬件时间戳。

4、时钟频率。

gPTP对策:
晶振频率越高,误差越小,校时越精确。
gPTP要求晶振频率不小于25MHz,误差不大于100PPM(每天8.64s误差)。

5、传输路径延时测量方式

gPTP要求使用P2P方式,并且要求网络中所有设备都支持PTP协议,路径传输延时测量只在相邻节点间进行。它使用Pdelay_Req、Pdelay_Resp、Pdelay_Resp_Follow_Up消息来测量路径传输延时。
在Peer-to-Peer机制中,不仅节点A会主动发起测量请求,节点B也会主动发起测量请求,也就是说,每个节点都知道和自己紧挨着的节点的传输延时(Peer-to-Peer的名字也是这样来的)。不过有的场景下(比如固定主时钟的情况),可能会禁止master port进行路径测量。

九、gPTP网络的时钟校准过程

在这里插入图片描述

  • 1、Grandmaster时钟在t1时刻发送时间同步报文Sync到Bridge,报文Sync的originTimestamp中填充时间信息t1,矫正域correction填充ns的小数部分(Sync报文的时间戳部分只能表示秒和纳秒,不足1纳秒的只能放在矫正域)。
  • 2、Bridge收到Sync报文后,不仅要矫正自己的时钟,还要把Sync报文转发出去
  • 3、Bridge根据Sync报文调整自己的时钟:
    Bridge在t2时刻收到Sync报文,并从中解析出Grandmaster是在t1时刻发送该报文的,以及Grandmaster填充的矫正值correction。在t2时刻,Grandmaster的时钟显示的值应该是:t1 + correction + path_delay1
    由此可以计算出Bridge的时钟偏差,并调整自己的时钟:clock_offset = t1 + correction + path_delay1 – t2
  • 4、Bridge转发Sync报文:
    如下图所示,收到Sync报文后,Bridge将自己与上级节点的路径延时(path_delay1)和Sync报文在自己这里的驻留时间(rEsidence_time)累加到Sync报文的矫正域,并转发出去。此时矫正域correction值如下:
    correction = old_value_of_ correction + path_delay1 + residence_time
  • 5、End-Point在t4时刻收到Sync报文,并从中解析出Grandmaster是在t1时刻发送该报文的,以及Bridge矫正后的correction。在t4时刻,Grandmaster的时钟显示的值应该是:t1 + correction + path_delay2
    由此可以计算出End-Point和Grandmaster的时钟偏差,并调整自己的时钟:clock_offset = t1 + correction + path_delay2 – t4

整个校时过程像水面的波纹一样从Grandmaster开始向外一层层的扩散,每个节点只关注自己和上级节点的传输延时,Bridge负责将中间路径的传输延时和缓存时间逐段累加到矫正域。
在这里插入图片描述
主时钟在时刻master_t1发出校时信号Sync_1,从时钟接收到该信号的时候,记录两个值:
slave_t1:接收到Sync_1信号时,slave本地时钟的值,这个值是当前时刻在slave时间坐标系下的采样
slave_t1’:接收到Sync_1信号时master时间坐标系的值:master_t1 + 传输时延 + 矫正域
master_t1和矫正域的值在Sync报文中携带,传输延时可以通过前面的方法测量。
根据频率同步原理,可以通过下面的公式判断自己的频率和主时钟是否保持一致:
ratio = (slave_tn – slave_t1) / (slave_tn’ – slave_t1’)
ratio的值应该是1,如果大于1,说明从时钟走的快了,如果小于1,说明走的慢了。从时钟可以根据该值调整自己的频率。

十、raw_socket使用

raw socket,即原始套接字,可以接收本机网卡上的数据帧或者数据包,对与监听网络的流量和分析是很有作用的.一共可以有3种方式创建这种socket
理解一下SOCK_RAW的原理, 比如网卡收到了一个 14+20+8+100+4 的udp的以太网数据帧.

1. socket(AF_INET, SOCK_RAW, IPPROTO_UDP)

能:该套接字可以接收协议类型为(tcp udp icmp等)发往本机的ip数据包,从上面看的就是20+8+100.
不能:不能收到非发往本地ip的数据包(ip软过滤会丢弃这些不是发往本机ip的数据包).
不能:不能收到从本机发送出去的数据包.
发送的话需要自己组织tcp udp icmp等头部.可以setsockopt来自己包装ip头部
这种套接字用来写个ping程序比较适合

2. socket(PF_PACKET, SOCK_RAW, htons(x));

这个套接字比较强大,创建这种套接字可以监听网卡上的所有数据帧.从上面看就是20+20+8+100.最后一个以太网crc从来都不算进来的,因为内核已经判断过了,对程序来说没有任何意义了.
能: 接收发往本地mac的数据帧
能: 接收从本机发送出去的数据帧(第3个参数需要设置为ETH_P_ALL)
能: 接收非发往本地mac的数据帧(网卡需要设置为promisc混杂模式)
协议类型一共有四个
ETH_P_IP 0x800 只接收发往本机mac的ip类型的数据帧
ETH_P_ARP 0x806 只接受发往本机mac的arp类型的数据帧
ETH_P_ARP 0x8035 只接受发往本机mac的rarp类型的数据帧
ETH_P_ALL 0x3 接收发往本机mac的所有类型ip arp rarp的数据帧, 接收从本机发出的所有类型的数据帧.(混杂模式打开的情况下,会接收到非发往本地mac的数据帧)

3. socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL)),

这个一般用于抓包程序。

网络层socket(三层socket)
  • (1)创建
    socket(AF_INET, SOCK_RAW, IPPROTO_UDP );//第三个参数可以是UDP,TCP或者ICMP
  • (2)接收
    recvfrom(sd, buffer, sizeof(buffer), 0,(struct sockaddr *)&client_addr, &addrlen));
  • (3)发送
    /如果IP_HDRINCL未开启,由进程让内核发送的数据是从IP首部之后的第一个字节开始的,内核会自动构造合适的IP,如果IP_HDRINGL开启,进程需要自行构造IP包/
    /*
    if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL, val, sizeof(int)))
    {
    perror(“setsockopt() error”);
    exit(-1);
    }
    */
    sendto(sd, buffer, request_length, 0, (sockaddr *)&client_addr, addrlen);
数据链路层scoket(二层socket)
  • (1)创建
    sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));//第三个参数可以为ETH_P_ALL ETH_P_IP ETH_P_ARP等
  • (2)接受
    struct sockaddr_ll client;
    socklen_t addr_length = sizeof(sockaddr_ll);
    recvfrom(sock, buffer, 2048, 0, (sockaddr *)&client, &addr_length);//此时的地址是数据链路层的地址
    接受的报文是从以太网的帧开始的
  • (3)发送
    sendto(sock, sendbuffer, n, 0, (struct sockaddr *) &client, sizeof(client));

十一、硬件时间戳

在一些应用中我们需要获取网路报文进出MAC的精准的时间戳。相比较于软件时间戳,硬件时间戳排除了系统软件引起的延时和抖动。
在这里插入图片描述

查看网卡捕获时间戳的能力:

使用ethtool -T eth0 来查看对应的MAC捕获时间戳的能力
配置捕获硬件时间戳功能:
要捕获硬件时间戳,需要配置MAC上的PHC硬件和配置socket 生成时间戳的类型
通过SIOCSHWTSTAMP ioctl命令配置硬件发送时间戳捕获模式和 硬件接收时间戳的过滤器。

struct ifreq hwtstamp;
struct hwtstamp_config hwconfig;
memset(&hwtstamp, 0, sizeof(hwtstamp)); 
memset(&hwconfig, 0, sizeof(hwconfig)); 
hwtstamp.ifr_name = “eth1”;
hwtstamp.ifr_data = (void*)&hwconfig;
// 设置网卡捕获所有发送报文的硬件时间戳。
hwconfig.tx_type = HWTSTAMP_TX_ON;
// 设置网卡捕获所有接收到的报文的时间戳。 
hwconfig.rx_filter = HWTSTAMP_FILTER_ALL;
ioctl(sock, SIOCSHWTSTAMP, &hwtstamp)

配置socket 捕获时间戳的类型

int so_timestamping_flags = SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE;
setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING,&so_timestamping_flags, sizeof(so_timestamping_flags)) < 0)

获取发送或接收报文的时间戳
在发送完或接收完报文后,时间戳被记录到一个 cmsg_level为SOL_SOCKET, cmsg_type 为SCM_TIMESTAMPING, data为 struct scm_timestamping 的一个control message中。这个cmsg可以通过recvmsg() 接口读取。
对于发送报文的时间戳,是放在socket的error 队列中,使用下面函数取到msg中。

ssize_t recv_len = recvmsg(sock, &msg, MSG_ERRQUEUE);

对于接收到的报文的时间戳,使用下面函数取到msg中。

ssize_t recv_len = recvmsg(sock, &msg, 0);

时间戳信息以struct scm_timestamping结构保存在cmsg消息的data段中。结构里包含三个时间戳:

struct scm_timestamping { 
    struct timespec ts[3]; 
};

ts[0]里存放的时software 时间戳,如果使能的话有效,否则为0。
ts[1]里存放的是一个被转化为系统时间的硬件时间戳,这个硬件时间类似一个影子时钟,用来系统时间和MAC上phc 时钟同步。
ts[2]里存放的便是我们想要获取的硬件时间戳。

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

起风就扬帆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值