我正在通过recvmsg()接收数据包,并期待3张时间戳:
我看到了第一个和第三个时间戳,但是我得到了第二个的零。
我的代码是基于这个Onload示例的:
https://github.com/Xilinx-CNS/onload/blob/master/src/tests/onload/hwtimestamping/rx_timestamping.c
我导出了用于时间戳的环境变量:
export EF_RX_TIMESTAMPING=1
我预装了加载库。
我设置了套接字选项:
int enable = SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE |
SOF_TIMESTAMPING_SYS_HARDWARE | SOF_TIMESTAMPING_SOFTWARE;
assert(setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &enable, sizeof(int)) == 0);我创建消息头并使用recvmsg()检索数据包:
while(_running)
{
struct iovec iov;
char control[1024];
struct msghdr msg;
iov.iov_base = buffer;
iov.iov_len = 2048;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_control = control;
msg.msg_controllen = 1024;
int num bytes = recvmsg(sock, &msg, 0);
handle_time(&msg);
LOG("Got packet");
}我读了时间戳:
static void handle_time(struct msghdr* msg)
{
struct timespec* ts = NULL;
struct cmsghdr* cmsg;
for( cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg,cmsg) ) {
if( cmsg->cmsg_level != SOL_SOCKET )
continue;
switch( cmsg->cmsg_type ) {
case SO_TIMESTAMPNS:
ts = (struct timespec*) CMSG_DATA(cmsg);
break;
case SO_TIMESTAMPING:
ts = (struct timespec*) CMSG_DATA(cmsg);
break;
default:
/* Ignore other cmsg options */
break;
}
}
print_time(ts);
}
static void print_time(struct timespec* ts)
{
if( ts != NULL ) {
/* Hardware timestamping provides three timestamps -
* system (software)
* transformed (hw converted to sw)
* raw (hardware)
* in that order - though depending on socket option, you may have 0 in
* some of them.
*/
printf("timestamps " TIME_FMT TIME_FMT TIME_FMT "\n",
(uint64_t)ts[0].tv_sec, (uint64_t)ts[0].tv_nsec,
(uint64_t)ts[1].tv_sec, (uint64_t)ts[1].tv_nsec,
(uint64_t)ts[2].tv_sec, (uint64_t)ts[2].tv_nsec );
} else
{
printf( "no timestamp\n" );
}
}收到第二个时间戳有什么遗漏吗?
发布于 2021-08-05 05:44:59
可能是网络接口驱动程序需要从硬件中添加时间戳。我们说的是什么样的硬件?你能显示一些ethanol输出吗?
https://stackoverflow.com/questions/68658903
复制相似问题