linuxptp的接口函数列举

欢迎淘宝搜索飞灵科技,我司相关新产品陆续上线。

之前的博文IEEE 1588/802.1AS标准、硬件,Linux软件学习建议中有一段介绍了1588整体的软硬件系统。我搬到这里作为第1章,而这篇文章简单列举下linuxptp软件和内核空间的接口函数。

系统框图

我们通过一个系统框图对1588软硬件系统进行整体的认识。这个系统框图是基于Linux操作系统的,纯FPGA的1588实现就不介绍了。
在这里插入图片描述

  • 硬件层:硬件层就是带有1588硬件辅助的网络控制器,由硬件PTP时钟向网络报文提供时间戳,时间戳的捕获是在MAC这一层。图里没有画PHY,类似地,如果使用PHY的1588功能的话,那硬件层就是PHY,由PHY上的PTP时钟向网络报文提供时间戳,时间戳的捕获是在PHY这一层。
  • 内核空间:Linux内核空间主要由两部分驱动来支持1588功能。其一是PTP时钟驱动,用于对硬件PTP时钟进行操作。其二是网络驱动,确切的说是网络驱动中的1588硬件时间戳的支持,用于捕获收发报文的硬件时间戳。当然,如果硬件层使用的是PHY的1588功能的话,内核空间对应的收发网络报文硬件时间戳的支持就在PHY驱动中。
  • 用户空间:PTP软件协议栈是用户空间的应用程序,它与内核驱动以及硬件的交互,是通过内核的用户空间API的实现的。对PTP时钟的操作是通过PHC (PTP Hardware Clock) API,对报文的收发以及硬件时间戳的使用是通过socket函数和SO_TIMESTAMPING选项。

linuxptp中ptp4l程序和内核的接口函数同样包含两部分,第一部分是ptp clock操作的函数,第二部分是socket报文收发和时间戳的函数。

ptp clock操作函数

对于ptp4l程序,ptp clock的操作其实只用到了两个函数:

  • clock_gettime
  • clock_adjtime

clock_gettime

用于获取时钟的时间,根据传入的clockid,可以获取不同的时钟时间,如CLOCK_MONOTONIC单调时间,即流逝时间;CLOCK_REALTIME系统时间,即挂钟时间;或者传入ptp clock id,获取ptp时钟时间,等等。详细信息可参考https://man7.org/linux/man-pages/man2/clock_gettime.2.html

clock_adjtime

用于调整时钟的时间,同样可以根据clockid调整不同的时钟。其功能包含,调整时间偏差,调整频率偏差等。详细信息可参考https://man7.org/linux/man-pages/man2/clock_adjtime.2.html

socket函数

Linux的报文收发,以及时间戳的使用都是通过socket函数,还有一些ioctl函数和内核交互。ptp4l用到的socket函数包括:

  • socket
  • setsockopt
  • getsockopt
  • sendto
  • recvmsg

socket

socket函数创建一个socket用于网络通信。socket和ioctl的详细信息可参考https://man7.org/linux/man-pages/man2/socket.2.htmlhttps://man7.org/linux/man-pages/man7/socket.7.html

setsockopt/getsockopt

对socket的配置,以及获取配置,如传输协议,多播地址,时间戳类型等等都是通过setsockopt/getsockopt函数。详细信息可参考https://man7.org/linux/man-pages/man2/getsockopt.2.html

sendto

sendto用于报文的发送,详细信息可参考https://man7.org/linux/man-pages/man2/sendto.2.html

recvmsg

recvmsg用于报文的接收,详细信息可参考https://man7.org/linux/man-pages/man2/recvmsg.2.html

时间戳

时间戳的操作在这里单独介绍一下,硬件时间戳的配置实际上是通过上面介绍的ioctl和setsockopt完成的:

  • ioctl(fd, SIOCSHWTSTAMP, &ifreq)
  • setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &flags, sizeof(flags))

报文的发送和接收时间戳的获取,都是通过解析recvmsg接收到的报文的辅助数据域获得的。对于接收报文,通过recvmsg来接收可以理解,对于发送报文,为什么要调用recvmsg呢?其实Linux内核在通过sendto函数发送报文后,会将这个报文的拷贝包含它的发送时间戳通过error queue返回给socket,在sendto发送报文后,立即调用recvmsg(注意传入MSG_ERRQUEUE参数)就可以获取发送的报文和时间戳了。

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值