can_tsync同步原理
整体来说,can的时间同步还是比较简单的,如下图所示,整个过程如下(tips:时间戳自1970年1月1日00:00:00经过的时间,是由秒+纳秒组成的。):
1time master在t01时刻以广播的形式发送一个sync报文,并把时间秒部分的时间放到报文上,发送到time slave;使用can confirmation的机制,记下sync报文实际从can驱动发送出去的时间,t1r.
time slave在t2r时刻接收到sync报文
time master在sync发送完之后,随后发送follow up报文,并把t1r的纳秒通过报文发送出去,即t4r = t2r-s(t0r)。这里有一个潜在条件,那就是sync报文由can timesync模块组装好报文后调用发送接口,直到从can driver上出去,整个时间是不会超过1s的。所以t4r实际上就是从can timesync报文发送出去直到can driver发送出去的一个延时。
time slave在t3r接收到follow up报文。
因此在t3r时刻,master此刻真正的时间t(master_now) = t3r - t2r + t4r
注意:实际上,上面的时间大多都是不精确的:
时间戳是软件加上的,并不是由硬件加上的
没有考虑can总线上的延迟
没有考虑到从t3r到adjust时钟这段时间的误差。
SYNC和FOLLOW_UP消息分为两种格式,Type=0x10为不安全的不带CRC校验的报文格式,对应FUP消息类型为0x18;Type=0x20为带CRC校验的安全报文格式,对应FUP消息类型为0x28。
Byte0:时间同步类型:0x20代表当前发送的是带CRC校验的TSync同步消息, 0x28代表当前发送的是对应0x20 SYNC消息的FUP同步消息;0x10代表当前发送的是不带CRC校验的TSync同步消息, 0x18代表当前发送的是对应0x10 SYNC消息的FUP同步消息;
Byte1:byte0为0x20或0x28时,Byte1为该消息的CRC校验值;
Byte2:高4位为时间同步域Time Domain;低4位为Sequence Counter,随发送次数循环累加;
Byte3:byte0为0x10或0x20时,Byte3为UserByte0;同步类型为0x28或0x18时,高5位保留, bit3 SGW为时间同步状态(0:SyncToGTM, 1:SyncToSubDomain),bit1-bit0 OVS为时间同步溢出时间overflow of seconds;
Byte4-Byte7为同步时间,同步类型为SYNC消息时为32bits 秒时间,同步类型为FUP消息时为30bits ns时间。