Merge pull request #59 from FabianInostroza/hw_timestamp

Add option to read hardware timestamps.
pull/62/head
Oliver Hartkopp 2017-12-06 10:15:00 +01:00 committed by GitHub
commit 7b8607ca89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 39 additions and 10 deletions

View File

@ -58,6 +58,7 @@
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <net/if.h>
#include <linux/net_tstamp.h>
#include <linux/can.h>
#include <linux/can/raw.h>
@ -108,6 +109,7 @@ void print_usage(char *prg)
fprintf(stderr, "\nUsage: %s [options] <CAN interface>+\n", prg);
fprintf(stderr, " (use CTRL-C to terminate %s)\n\n", prg);
fprintf(stderr, "Options: -t <type> (timestamp: (a)bsolute/(d)elta/(z)ero/(A)bsolute w date)\n");
fprintf(stderr, " -H (Read hardware timestamps)\n");
fprintf(stderr, " -c (increment color mode level)\n");
fprintf(stderr, " -i (binary output - may exceed 80 chars/line)\n");
fprintf(stderr, " -a (enable additional ASCII output)\n");
@ -208,6 +210,7 @@ int main(int argc, char **argv)
int bridge = 0;
useconds_t bridge_delay = 0;
unsigned char timestamp = 0;
unsigned char hwtimestamp = 0;
unsigned char down_causes_exit = 1;
unsigned char dropmonitor = 0;
unsigned char extra_msg_info = 0;
@ -224,7 +227,10 @@ int main(int argc, char **argv)
int join_filter;
char *ptr, *nptr;
struct sockaddr_can addr;
char ctrlmsg[CMSG_SPACE(sizeof(struct timeval)) + CMSG_SPACE(sizeof(__u32))];
struct {
struct cmsghdr cm;
char control[512];
} ctrlmsg;
struct iovec iov;
struct msghdr msg;
struct cmsghdr *cmsg;
@ -244,7 +250,7 @@ int main(int argc, char **argv)
last_tv.tv_sec = 0;
last_tv.tv_usec = 0;
while ((opt = getopt(argc, argv, "t:ciaSs:b:B:u:lDdxLn:r:heT:?")) != -1) {
while ((opt = getopt(argc, argv, "t:HciaSs:b:B:u:lDdxLn:r:heT:?")) != -1) {
switch (opt) {
case 't':
timestamp = optarg[0];
@ -256,6 +262,10 @@ int main(int argc, char **argv)
}
break;
case 'H':
hwtimestamp = 1;
break;
case 'c':
color++;
break;
@ -555,12 +565,21 @@ int main(int argc, char **argv)
if (timestamp || log || logfrmt) {
const int timestamp_on = 1;
if (setsockopt(s[i], SOL_SOCKET, SO_TIMESTAMP,
&timestamp_on, sizeof(timestamp_on)) < 0) {
perror("setsockopt SO_TIMESTAMP");
return 1;
int timestamping_flags = 1;
if (hwtimestamp) {
timestamping_flags = SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_RX_SOFTWARE | \
SOF_TIMESTAMPING_RAW_HARDWARE;
if (setsockopt(s[i], SOL_SOCKET, SO_TIMESTAMPING,
&timestamping_flags, sizeof(timestamping_flags)) < 0) {
perror("setsockopt SO_TIMESTAMPING");
return 1;
}
} else {
if (setsockopt(s[i], SOL_SOCKET, SO_TIMESTAMP,
&timestamping_flags, sizeof(timestamping_flags)) < 0) {
perror("setsockopt SO_TIMESTAMP");
return 1;
}
}
}
@ -688,9 +707,19 @@ int main(int argc, char **argv)
for (cmsg = CMSG_FIRSTHDR(&msg);
cmsg && (cmsg->cmsg_level == SOL_SOCKET);
cmsg = CMSG_NXTHDR(&msg,cmsg)) {
if (cmsg->cmsg_type == SO_TIMESTAMP)
if (cmsg->cmsg_type == SO_TIMESTAMP) {
memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv));
else if (cmsg->cmsg_type == SO_RXQ_OVFL)
} else if (cmsg->cmsg_type == SO_TIMESTAMPING) {
struct timespec *stamp = (struct timespec *)CMSG_DATA(cmsg);
// stamp[0] is the software timestamp
// stamp[1] is deprecated
// stamp[2] is the raw hardware timestamp
// See 2.1.2 in doc/Documentation/networking/timestamping.txt
tv.tv_sec = stamp[2].tv_sec;
tv.tv_usec = stamp[2].tv_nsec/1000;
} else if (cmsg->cmsg_type == SO_RXQ_OVFL)
memcpy(&dropcnt[i], CMSG_DATA(cmsg), sizeof(__u32));
}