ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

与硬件时钟对话:PHC原理、操作与PTP同步实战

与硬件时钟对话:PHC原理、操作与PTP同步实战 搞时间同步这些年我发现一个很有意思的现象很多刚接触PTP的人第一反应是去抠协议报文、研究状态机的状态流转花了好几天把协议看得很透结果一到实际部署发现同步精度连微秒级都够呛。问题出在哪儿十有八九是没搞明白PTP协议跑起来的底座——PHCPTP Hardware ClockPTP硬件时钟到底是个什么东西更别说怎么去操作它、调整它。PTP协议本质上就是一套流程真正干时间戳和调时钟的脏活累活都是PHC在扛。这篇咱们就专门聊聊PHC怎么读它、调它、让它乖乖听话把“与硬件时钟对话”这件事聊透。这篇文章适合谁看两种人。一种是刚入手PTP、被ptp4l和phc2sys这两个工具搞得一头雾水的新人你需要先搞清楚它们和PHC之间的关系不然看多少教程都是晕的。另一种是已经在跑PTP但精度上不去、或者想深入理解时钟伺服过程的开发者这篇文章可以帮你把PHC操作这块的经验和坑补齐。咱们不聊协议包怎么走就聊硬件时钟本身。1. PTP与PHC为什么精度承诺必须靠硬件兑现1.1 时间戳的位置决定了同步精度的天花板PTPPrecision Time ProtocolIEEE 1588的同步原理并不复杂主时钟和从时钟之间互发报文通过记录报文的发送和接收时刻算出主从之间的时间偏差offset和链路延迟delay然后把自己的时钟校正过去。听起来很简单但这里藏着一个致命问题——你记录的那个“发送时刻”和“接收时刻”到底是哪个环节的时间是在应用层send()调用返回时打的时间戳还是在报文真正从网线接口出去的瞬间打的时间戳这两种时间戳之间的差距可能就是几十微秒甚至几毫秒。这就是软件时间戳和硬件时间戳的本质区别。软件时间戳是CPU在协议栈处理过程中随手记的中间经历了系统调用、内核协议栈排队、驱动处理、DMA传输时间漂移非常严重。而硬件时间戳则是网卡芯片在物理收发报文的那一瞬间自动打上去的几乎不受系统负载和CPU调度影响。PTP最终能达到纳秒级精度靠的就是硬件时间戳而硬件时间戳的依托正是PHC。打个不太严谨但很贴切的比方软件时间戳就像快递员在网点扫描包裹时记录的到站时间硬件时间戳则是包裹上装的GPS定位器记录的实际到达位置。前者是流程时间中间隔了无数环节后者才是真实物理世界的时间。1.2 PHC的本质网卡里那枚“独立旱地优质时钟”PHC全称PTP Hardware Clock现在的大多数厂商也管它叫“NIC内嵌时钟”或“Ethernet PHC”本质上就是集成在网卡芯片里的一个高精度硬件计时器。它内部有一个基于晶振驱动的计数器频率一般是125MHz、156.25MHz或者250MHz取决于网卡的具体实现。PHC不依赖操作系统时钟它自己独立运行哪怕系统时钟乱了、被NTP抢走调整了PHC依然按自己的节奏走。为什么PTP必须依赖PHC而不是直接用系统时钟原因在于系统时钟CLOCK_REALTIME是软件维护的它的精度受内核定时器中断频率、调度延迟、NTP调整策略等因素影响秒级精度还行但做不到稳定可预期的纳秒级精度。而PHC是硬件计时器它的更新只受自身晶振的相位噪声和频率漂移影响这个特性让它可以成为PTP时间同步的锚点。主从双方都基于各自的PHC打硬件时间戳再通过PTP协议把两边的PHC拉到一致精度才能上去。1.3 PHC、系统时钟、RTC三者的分工别搞混和PHC一起经常被搞混的还有系统时钟和RTCReal-Time Clock。很多新人总是把这几个时间混为一谈实际它们的分工完全不同时钟类型载体特点典型用途RTC主板独立芯片CMOS掉电后靠电池维持精度很低ppm级偏差开机后给系统提供一个初始时间系统时钟内核维护软件定时器驱动精度取决于内核和晶振可被NTP/PTP调整应用程序读取的本地时间PHC网卡芯片内部硬件计时器独立于系统时钟纳秒级精度可被PTP精确调整打硬件时间戳PTP同步的锚点这三者之间不是独立的需要一套机制把它们串起来。系统会用RTC做开机初始化然后通过phc2sys这类工具把PHC的时间同步到系统时钟上必要时也可以反着来从系统时钟同步到PHC比如用软件时间戳跑PTP时。后面我详细讲怎么操作。2. 与PHC对话的工具箱ptp4l、phc2sys、phc_ctl2.1 ptp4l只管PTP协议不负责调系统时钟在Linux生态里与PHC打交道最常用的就是linuxptp套件核心是三个工具ptp4l、phc2sys和phc_ctl。很多新人以为跑起ptp4l时间就同步好了这是一个很大的误区。ptp4l只负责PTP协议本身的状态机运转——在主从之间交换报文计算offset和delay然后调整自己指定的那个时钟默认是网卡的PHC。它根本不知道系统时钟的存在也不会去动它。如果你只跑ptp4l -i eth0PHC会逐步和主时钟对齐但你在应用层用date命令看到的时间完全没有变化因为系统时钟根本没人管。ptp4l最常用的启动命令是ptp4l -i eth0 -m -H这里的-H表示使用硬件时间戳Hardware timestamp这是PTP达到高精度的前提。如果你的网卡不支持硬件时间戳只能用-S软件时间戳那精度就别指望太高了。-m是打印日志方便实时观察同步状态。2.2 phc2sys把PHC和系统时钟串起来的桥梁phc2sys的职责就是一个字——搬。它负责在PHC和系统时钟之间做伺服同步。比如PTP链路跑通了网卡PHC已经和主时钟同步得很好了纳秒级但系统时钟还没跟上这时候就需要phc2sys读取PHC的时间通过调用系统时钟调整接口一点一点把系统时钟拉齐。典型用法是自动模式它会自动识别和PTP同步的那个PHCphc2sys -a -r也可以手动指定源时钟和目标时钟phc2sys -s /dev/ptp0 -c CLOCK_REALTIME -m -O 0这里-s指定源时钟被同步的PHC-c指定目标时钟通常是系统时钟CLOCK_REALTIME-O 0表示主时钟和UTC的偏移是0秒实际使用中要根据PTP域的类型调整比如PTP域里跑的是TAI时间本地系统时间是UTC中间差8秒当前闰秒数那-O 0就不对。2.3 phc_ctl直接操作PHC的“单兵工具”phc_ctl是这三个工具里最不起眼但调试时最实用的一个。它可以直接对指定的PHC设备执行读取时间、调整时间、调整频率等操作不需要启动整个PTP协议栈。调试网卡、验证PHC是否正常工作、以及排查硬件问题的时候这个工具是首选。常用命令# 查看PHC当前时间 phc_ctl /dev/ptp0 get # 设置PHC时间手动调时 phc_ctl /dev/ptp0 set 1698880000 # 查看PHC的能力 phc_ctl /dev/ptp0 capsphc_ctl get会打印PHC当前的时间和PPS相位的状态一般就能判断PHC是不是在走。phc_ctl caps则会显示这个PHC支持的最大频率调整范围max_adj这个参数后面调整频率时非常关键。2.4 PHC在内核里的统一入口/dev/ptp*不管底层是哪个品牌的网卡PHC在内核统一被抽象成/dev/ptp0、/dev/ptp1这样的设备节点。你通过ls /sys/class/ptp/或者ls /dev/ptp*就能看到机器上有哪些PHC。有个很常见的坑——网卡数量不等于PHC数量。有些网卡支持多个PTP域会有多个PHC有些网卡虽然有多个千兆口但共享一个PHC还有的网卡根本不支持PTP硬件时间戳自然就没有PHC。判断方式是用ethtool -T eth0查看网卡的时间戳能力输出里如果有hardware-transmit和hardware-receive就说明支持硬件时间戳相应的PHC设备由它驱动管理。反之如果只看到software-transmit和software-receive那这个网卡没法参与基于PHC的高精度PTP只能靠软件时间戳凑合。3. 时钟调整的核心原理怎么让PHC听指挥3.1 调整的三个层级跳变、渐进调整、频率调整和硬件时钟对话核心就是围绕三个操作设置时间跳变、调整时间渐进、调整频率伺服。这三个概念一定要区分开因为它们对应着完全不同的底层机制也对应着不同的应用场景。第一种是绝对跳变Step也就是直接把PHC的时间戳设置成一个新值。比如phc_ctl /dev/ptp0 set 1698880000就是把时钟瞬间拨到那个时刻。这种操作简单粗暴代价是时钟会发生非连续性跳变如果系统里正好有依赖单调时间或需要时间连续性的应用会造成问题。所以跳变通常只用于初始同步或者人工干预调优PTP正常运行时不建议主动做跳变。第二种是渐进调整Slew也叫“平滑调时”。这个操作的底层原理是内核不会直接改时间值而是让时钟在一段时间内“走得快一点”或“走得慢一点”逐步把偏差消化掉。类似你戴的手表慢了5秒你捏着秒针慢慢往前拨而不是直接咔哒一下跳5秒。这种调整方式时间连续对应用层影响小是phc2sys默认采用的策略。第三种是频率调整Frequency Adjustment这才是伺服控制的核心。PHC计数器的实际走时频率和理想频率之间是有偏差的比如晶振标称是250MHz实际可能是249.999995MHz偏差用ppbparts per billion十亿分之一来表示。通过调整计数器的分频系数或压控参数让PHC的实际走时频率尽量接近理想频率这就是频率调整。PTP同步之所以稳定就是因为它能感知到主从PHC之间的频率偏差主动把从端的PHC频率校正过来而不是每次等偏差累积到一定程度才去拨时间。3.2 从用户空间到内核ioctl是对话的语言要真正理解PHC操作光会敲几个命令还不行还得知道背后的机制。Linux内核为PHC提供了统一的IO控制接口定义在linux/ptp_clock.h头文件里。应用层通过open()打开/dev/ptp0然后用ioctl()系统调用就能实现对PHC的完整控制。获取PHC能力是第一步#include stdio.h #include fcntl.h #include sys/ioctl.h #include linux/ptp_clock.h int main() { int fd open(/dev/ptp0, O_RDWR); if (fd 0) { perror(open); return -1; } struct ptp_clock_caps caps; if (ioctl(fd, PTP_CLOCK_GETCAPS, caps) 0) { printf(PHC索引: %d\n, caps.index); printf(最大频率调整范围: %d ppb\n, caps.max_adj); printf(精度: %d ns\n, caps.precision); printf(支持PPS: %d\n, caps.pps); } close(fd); return 0; }读取PHC当前时间用的是PTP_CLOCK_GETTIMEstruct ptp_clock_time pct {0}; ioctl(fd, PTP_CLOCK_GETTIME, pct); printf(PHC时间: %lld.%09lu 秒\n, (long long)pct.sec, pct.nsec);调整PHC时间既可以用跳变PTP_CLOCK_SETTIME也可以用渐进调整PTP_CLOCK_ADJTIME。跳变就是把ptp_clock_time的值直接塞进去struct ptp_clock_time pct {0}; pct.sec 1698880000; pct.nsec 0; ioctl(fd, PTP_CLOCK_SETTIME, pct);而渐进调整PTP_CLOCK_ADJTIME的参数是一个timex结构里面指定要调整的偏移量。内核会精细地控制时钟的走速在一段时间内消化掉这个偏移过程平滑连续。phc2sys实际调时钟时用的就是这套机制它会根据伺服控制器算出的偏差量周期性地调用PTP_CLOCK_ADJTIME来慢慢把PHC拉齐。3.3 频率调整让PHC的“步伐”贴合主时钟有了PTP_CLOCK_ADJTIME处理短时偏差为什么还需要PTP_CLOCK_ADJFREQ因为PHC自身的频率偏差是持续存在的如果不校正频率就算某一刻把时间拨准了过一会儿偏差又会重新累积回来。频率校正的做法是通过调整PHC计数器的增量步长让它在单位时间内的“走字数”贴近理想值。内核在PTP_CLOCK_ADJFREQ的调用里接受一个以ppb为单位的频率偏移量。正数表示让PHC走快一点负数表示让它走慢一点。比如struct ptp_clock_adjtime adj {0}; long ppb 500; /* 让PHC每十亿纳秒走快500纳秒 */ adj.freq ppb; ioctl(fd, PTP_CLOCK_ADJFREQ, adj);调整的范围不是无限的每个PHC芯片都标定了自己的最大可调范围就是phc_ctl caps里看到的max_adj。一般常见的是±500000 ppb也就是±500 ppm左右。伺服算法比如PI控制器会根据实时的offset测量值计算出一个合适的频率调整量持续地微调PHC最终让偏移在一个很小的范围内波动。这整个过程本质上就是锁相环PLL思想的应用测量相位差调整频率再测量再调整收敛到一个动态平衡的状态。PTP的“精密”其实也来源于这种闭环控制而不是一次性的粗调。3.4 为什么不能直接粗暴地“拨表”我在实际项目中遇到过不少同事刚上手PTP时喜欢用settime直接拨PHC时间觉得一步到位最省事。但在有业务在跑的产线上这种做法风险很高。跳变带来的时间不连续可能导致依赖时间戳的日志顺序错乱、事务记录时间倒挂、加密协议校验失败等问题。尤其是如果系统里同时跑着PTP和NTP两边互相较劲NTP的管理员一看系统时间不对直接ntpdate强行拨过去PTP这边伺服半天刚收敛的状态一下就毁了。所以成熟的部署里phc2sys和ptp4l默认都是走渐进的频率调整路线不停对时而是让时钟在闭环伺服中自然收敛。手动跳变只允许在系统刚启动、PHC和真实时间差得很远比如差了几小时这种场景下使用帮助快速收敛到大概区间然后交给伺服逻辑微调。4. 实操过程与核心环节实现从零搭建一套PHC同步链路4.1 硬件与系统准备先确认你的网卡够不够格动手之前花一分钟确认硬件能力能帮你少走很多弯路。用ethtool -T查看网卡的时间戳能力$ ethtool -T eth0 Time stamping parameters for eth0: Capabilities: hardware-transmit (SOF_TIMESTAMPING_TX_HARDWARE) hardware-receive (SOF_TIMESTAMPING_RX_HARDWARE) hardware-raw-clock (SOF_TIMESTAMPING_RAW_HARDWARE) PTP Hardware Clock: 0 Hardware Transmit Timestamp Modes: off (HWTSTAMP_TX_OFF) on (HWTSTAMP_TX_ON) Hardware Receive Filter Modes: none (HWTSTAMP_FILTER_NONE) ptpv1-l4-sync (HWTSTAMP_FILTER_PTP_V1_L4_SYNC) ptpv2-l4-sync (HWTSTAMP_FILTER_PTP_V2_L4_SYNC) ptpv2-l2-sync (HWTSTAMP_FILTER_PTP_V2_L2_SYNC) ptpv2-event (HWTSTAMP_FILTER_PTP_V2_EVENT)关键看PTP Hardware Clock: 0这一行说明这块网卡的PHC被内核注册为/dev/ptp0。如果你看到的是PTP Hardware Clock: none恭喜你这块卡没法用硬件时间戳跑PTP只能退而求其次用软件时间戳精度就别指望太离谱了。目前常见支持PTP硬件时间戳的网卡数据中心场景用得比较多的是Intel的X710/XL710系列、MellanoxNVIDIA的ConnectX系列以及部分Broadcom和Marvell的网卡新出的有些2.5G/5G电口网卡也带PHC但要看具体型号确认。另一个需要注意的是内核配置PHC设备依赖内核里CONFIG_PTP_1588_CLOCK这个选项一般主流发行版的内核都默认开启了。如果/dev/ptp*不存在但网卡本身支持可以检查下是不是内核没带这个模块ls /sys/class/ptp/ modprobe ptp4.2 单机验证先用phc_ctl确认PHC活着拿到一台机器不用急着起整套PTP先单机验证PHC是否正常工作。最直接的办法就是读取时间$ phc_ctl /dev/ptp0 get phc_ctl: phc: 0, device: /dev/ptp0, ref clock: 0 phc_ctl: read 1700000000.500000000, total cycles 213525000, rms 0.000000, max abs 0.000000能看到一个合理的时间戳和total cycles说明PHC在正常走时计数器没有停摆。这时候再连续读几次比如隔几秒再读确认时间在同步往前走基本可以判断PHC硬件是好的。如果你的时间比真实时间离谱地偏了好几百年常见于新出厂网卡PHC寄存器未被初始化可以用phc_ctl set手动把它拨到大概正确的位置。比如用系统时间做参考phc_ctl /dev/ptp0 set date %s这只是初始化不是精同步。4.3 双机互连ptp4l起链路phc2sys搭桥假设有两台服务器A和B通过以太网直连A作为masterB作为slave。在B上启动ptp4lptp4l -i eth0 -m -H-i指定网络接口-H指定硬件时间戳。启动后ptp4l会先监听PTP报文通过最佳主时钟算法BMCA决定自己是master还是slave。如果网络里还有别的PTP设备可能不是理想的主从关系也可以用配置文件固化角色。实际部署时我强烈建议写一个配置文件而不是每次敲一堆命令行参数。在/etc/linuxptp/ptp4l.conf里指定[global] domainNumber 0 priority1 128 priority2 128 slaveOnly 0 network_transport L2 delay_mechanism E2E然后ptp4l -f /etc/linuxptp/ptp4l.conf -i eth0 -m -H启动。delay_mechanism E2E是端到端延迟机制适合大多数场景如果网络里hub和交换机比较多可以考虑P2P点对点这个后面细说。链路起来之后用ptp4l -m的日志观察offset变化。正常情况下offset会从几百纳秒逐渐收敛到几十纳秒甚至更好。这里有个看日志的技巧ptp4l日志周期性打印的offset和path delay值要看的是稳定后的offset比如ptp4l[123.456]: master offset -12 ns s2 freq 2453 ppboffset -12 ns表示从时钟比主时钟慢12纳秒freq 2453 ppb表示当前对PHC的频率校正量为2453ppb。看到这个输出说明ptp4l已经在实时调整PHC了。但这只是PHC层面的同步系统时间还没动。另开一个终端跑phc2sys把PHC时间桥接到系统时钟phc2sys -s /dev/ptp0 -c CLOCK_REALTIME -m -O 0日志里如果看到类似phc2sys[123.456]: CLOCK_REALTIME phc offset 27 ns freq -102 ppb就说明系统时钟正在被PHC伺服。之后在B机上跑date会发现它已经和A机时间基本一致了。4.4 把这个过程自动化systemd服务配置手动调试时为了看得清楚我都会前台跑工具观察日志但正式部署必须把服务固化成systemd unit。这里有一个非常容易踩坑的点——ptp4l和phc2sys的启动顺序。正确顺序是先启动ptp4l等PHC已经被伺服到主时钟ptp4l日志里offset收敛再启动phc2sys。如果两个同时启动phc2sys可能一开始读到的是还没同步的PHC时间会把系统时钟带偏。简单的systemd服务配置可以这样写在[Unit]里加依赖关系[Unit] DescriptionPTP slave Afternetwork-online.target Wantsnetwork-online.target [Service] Typesimple ExecStart/usr/sbin/ptp4l -f /etc/linuxptp/ptp4l.conf -i eth0 -m -H ExecStartPost/bin/sleep 5 ExecStartPost/usr/sbin/phc2sys -s /dev/ptp0 -c CLOCK_REALTIME -m -O 0 [Install] WantedBymulti-user.target加一个5秒的延时给ptp4l一个建立链路的时间再去启phc2sys能有效减少初始阶段的混乱。5. 常见问题与排查技巧实录5.1 ptp4l一直找不到master或状态机在FAULT/UNCALIBRATED之间跳这个问题见过不少新手遇到。第一件事是检查网络二层连通性和PTP报文能不能正常到达。PTP默认使用组播地址如果中间隔了交换机要考虑交换机有没有开启组播过滤或者PTP是否走了配置里的network_transport L2二层链路。在实验室直连环境基本不涉及交换机但在机房环境里交换机对PTP的支持程度直接影响同步。另一个常见原因是网卡驱动默认过滤掉了PTP报文。很多网卡的硬件时间戳过滤默认是关闭的ptp4l启动时驱动应该自动设置相关寄存器但如果驱动和ptp4l版本不匹配或者驱动有bug就可能出现设备收不到事件报文的情况。这时候先用ethtool -T确认网卡时间戳能力再检查dmesg有没有网卡驱动报错。还有一点如果网络里有多台PTP设备BMCA选主可能选到你不希望的那个设备。排查方法是用ptp4l -m的详细日志看它宣布的时钟优先级、clockIdentity。如果是业务时间源强烈建议用配置文件把priority1和priority2调低让设备更有可能当选master。5.2 同步精度一直差在几百纳秒上不去精度上不去主要从两个方向排查相位噪声和链路延迟测量。相位噪声通常来自网卡驱动对PHC中断的处理延迟。硬件时间戳本身是准的但驱动把时间戳从硬件寄存器读出来的那一刻如果被中断调度延迟影响就会引入抖动。解决思路是看驱动版本更新日志以及对网卡进行中断亲缘性绑定CPU affinity。链路延迟测量不准则大概率出在交换机的透明时钟Transparent Clock或边界时钟Boundary Clock配置上。PTP报文在交换机里转发有一个驻留时间residence time如果交换机支持PTP但不开启相关功能PTP事件报文的驻留时间会被当作链路延迟的一部分导致主从计算delay时出现一个不对称的误差。直连的时候没有这个问题经过交换机就要仔细检查。如果延时用的是E2E机制有些交换机要求开启PTP透传才会修正驻留时间。配置好之后再对比看ptp4l日志里的path delay如果delay值稳定且很小精度才有保证。5.3 虚拟机里跑PTP不是不行是精度很难看虚拟化环境是PTP部署的重灾区。虚拟机里千兆网卡通常是virtio虚拟网卡它没有真正的PHC硬件ptp4l即使能起来也只能用软件时间戳。软件时间戳受宿主机调度、CPU抢占、半虚拟化驱动队列延迟这些因素影响非常大抖动几十微秒都是常事所以虚拟机同步精度很难保证。如果确实需要在虚拟机里做时间同步可以这样处理。宿主机作为边界时钟先同步好虚拟机通过宿主机的时间同步机制比如KVM的kvm-clock获取时间这个路径很成熟千兆虚拟化环境下的kvm-clock稳态偏移通常能控制在亚毫秒级。要想在虚拟机里获得纳秒级PTP精度需要SR-IOV或者VFIO直通真正的物理网卡给虚拟机让它拥有自己的PHC这是现在高性能NFV场景的标准做法。5.4 多网卡多PHC别让“时间源”打架了一台机器多块网卡、多个PHC的情况下一个很坑的场景是eth0的PHC在跑PTP slaveeth1的PHC也在跑PTP slave而系统时钟被phc2sys同时往两个方向调。两个PHC对系统时钟的参考时间可能互相冲突导致系统时钟被反复纠偏越调越乱。解决办法是明确时间源的分层关系。要么只让一块网卡作为PTP时间源其余保持free-running状态要么把多块网卡组成PTP边界时钟下游网卡之间维护自己的sync关系。多PHC管理时还需要确认网卡和PHC设备节点的对应关系用ethtool -T eth0和ls /sys/class/ptp/对比确认后再配置不要在没确认的情况下乱写/dev/ptp0。5.5 温度变化导致PHC频率漂移最后一个经验和硬件可靠性相关。PHC内部的晶振频率会随温度变化发生漂移这是物理特性没办法从根本上消除只能通过伺服补偿。服务器机房恒温环境一般不太明显但如果设备放在户外机柜昼夜温差大的话ptp4l日志里的freq值会跟着温度呈现周期性的波动同步误差也会变大。实践中的一个做法是机房部署时尽量把PTP主时钟放在温控稳定的环境从时钟如果必须有温度变化靠PI控制器的积分项在短时间内就能补偿掉大部分低频温度漂移。如果工作环境温度变化剧烈可以考虑选用带恒温晶振OCXO的专用PTP网卡虽然贵但频率稳定度确实比普通网卡的晶振好一个数量级以上。最后分享一点经验在PTP这条路上踩过不少坑我最深的体会是PTP调试的难点往往不在协议本身而在于你能否真正把PHC当作一个独立的硬件来对待理解它有自己的时间、自己的频率、自己的性格。刚开始接触时我犯过最蠢的错误是拿系统时钟的时间去和PHC比较发现差了几毫秒就以为PTP坏了后来才明白这两个时钟本来就可以不一样它们的同步是通过伺服逻辑主动建立的不是天然一致的。所以如果你也在调试PTP我的建议是先从phc_ctl get开始把PHC当前的状态摸清楚再一步步搭建链路。把时间戳拿干净、把伺服看明白、把频率调稳当剩下的就是硬件不断升级、厂商驱动不断迭代自然会越来越准。
返回列表