当前位置: 首页 > 工具软件 > smart-socket > 使用案例 >

Linux报文硬件时间戳,sockets

刘子实
2023-12-01

我正在研究有关网络同步的项目。 由于我想获得最佳性能,因此我尝试将软件时间戳记结果与硬件时间戳记结果进行比较。

我已经关注了这个先前发表过的问题: Linux内核UDP接收时间戳,但是经过几次测试,在尝试获取硬件接收时间戳时遇到了一些问题。

我的场景由两台设备,一台PC和一台Gateworks Ventana板组成,这两个设备都应该等待数据包在其网络中广播并加盖其接收时间,我尝试使用此代码(省略了某些部分):

int rc=1;

int flags;

flags = SOF_TIMESTAMPING_RX_HARDWARE

| SOF_TIMESTAMPING_RAW_HARDWARE;

rc = setsockopt(sock, SOL_SOCKET,SO_TIMESTAMPING, &flags, sizeof(flags));

rc = bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr));

struct msghdr msg;

struct iovec iov;

char pktbuf[2048];

char ctrl[CMSG_SPACE(sizeof(struct timespec))];

struct cmsghdr *cmsg = (struct cmsghdr *) &ctrl;

msg.msg_control = (char *) ctrl;

msg.msg_controllen = sizeof(ctrl);

msg.msg_name = &serv_addr;

msg.msg_namelen = sizeof(serv_addr);

msg.msg_iov = &iov;

msg.msg_iovlen = 1;

iov.iov_base = pktbuf;

iov.iov_len = sizeof(pktbuf);

//struct timeval time_kernel, time_user;

//int timediff = 0;

FILE *f = fopen("server.csv", "w");

if (f == NULL) {

error("Error opening file!\n");

exit(1);

}

fprintf(f, "Time\n");

struct timespec ts;

int level, type;

int i;

for (i = 0; i < 10; i++) {

rc = recvmsg(sock, &msg, 0);

for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg))

{

level = cmsg->cmsg_level;

type = cmsg->cmsg_type;

if (SOL_SOCKET == level && SO_TIMESTAMPING == type) {

//ts = (struct timespec *) CMSG_DATA(cmsg);

memcpy(&ts, CMSG_DATA(cmsg), sizeof(ts));

printf("HW TIMESTAMP %ld.%09ld\n", (long)ts.tv_sec, (long)ts.tv_nsec);

}

}

}

printf("COMPLETED\n");

fclose(f);

close(sock);

return 0;

}

在这两种设备中,收到数据包后我得到的输出:

HW TIMESTAMP 0.000000000

另一方面,如果使用相同的代码,则我的标志是:

flags = SOF_TIMESTAMPING_RX_HARDWARE

| SOF_TIMESTAMPING_RX_SOFTWARE

| SOF_TIMESTAMPING_SOFTWARE;

我得到适当的时间戳:

HW TIMESTAMP 1551721801.970270543

但是,它们似乎是软件时间戳记。 处理接收到的数据包的硬件时间戳的正确解决方案/方法是什么?

 类似资料: