Skip to contentSkip to conversation

About timestamping and can-utils

DISCUSSION Stephane Grosjean 2 participants 4 messages Mar 6, 2014

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

Hi linux-can team,

I've got one question about how timestamping is done now in linux-can, regarding to HW timestamps.

In the early ages (~v3.4), the CAN hardware driver could set the timestamp of an skb by itself and push it with the received CAN frame, so that the application could get it using SO_TIMESTAMP socket option, right? Now, this "hardware" timestamp is to be copied into "hwstamp" field of the "skb_hwtstamps(skb)" area.

But how does user application manage to get this hardware timestamp on its side? AFAIK, the "candump" can-utils utility always reads and displays the "network" timestamp (that is, always uses SO_TIMESTAMP socket option). I had a quick look to the Kernel sources and tried to find the links between things but it's not very clear to me: first idea I tested was to set the SO_TIMESTAMPING socket option, but candump never received any hw timestamp in the control messages he reads from the CAN socket...

Any help would be appreciated.

Regards,

Stéphane
--
PEAK-System Technik GmbH, Otto-Roehm-Strasse 69, D-64293 Darmstadt Geschaeftsleitung: A.Gach/U.Wilhelm,St.Nr.:007/241/13586 FA Darmstadt HRB-9183 Darmstadt, Ust.IdNr.:DE 202220078, WEE-Reg.-Nr.: DE39305391 Tel.+49 (0)6151-817320 / Fax:+49 (0)6151-817329, [email protected]

#1 lore raw

Hi Stephane,

here's a discussion thread from last year focussing HW timestamping:

http://marc.info/?l=linux-can&m=138210737431112&w=2

Additionally I attached two patches:

cants-test.patch:
added some functionality to add a monotonic (sw) timestamp to sja1000

candump-hwts.patch:
added some functionality to candump to get these timestamps

The candump patch is from the time before the include file cleanup inside the can-utils provided by Uwe. (including from socketcan directory)

Together with the discussion thread from above, this should give a good starting point.

Regards,
Oliver

Quoted 19 lines · Stephane Grosjean

Hi linux-can team,

I've got one question about how timestamping is done now in linux-can, regarding to HW timestamps.

In the early ages (~v3.4), the CAN hardware driver could set the timestamp of an skb by itself and push it with the received CAN frame, so that the application could get it using SO_TIMESTAMP socket option, right? Now, this "hardware" timestamp is to be copied into "hwstamp" field of the "skb_hwtstamps(skb)" area.

But how does user application manage to get this hardware timestamp on its side? AFAIK, the "candump" can-utils utility always reads and displays the "network" timestamp (that is, always uses SO_TIMESTAMP socket option). I had a quick look to the Kernel sources and tried to find the links between things but it's not very clear to me: first idea I tested was to set the SO_TIMESTAMPING socket option, but candump never received any hw timestamp in the control messages he reads from the CAN socket...

Quoted 11 lines

Any help would be appreciated.

Regards,

Stéphane

Signature · 5 lines
PEAK-System Technik GmbH, Otto-Roehm-Strasse 69, D-64293 Darmstadt
Geschaeftsleitung: A.Gach/U.Wilhelm,St.Nr.:007/241/13586 FA Darmstadt HRB-9183
Darmstadt, Ust.IdNr.:DE 202220078, WEE-Reg.-Nr.: DE39305391 Tel.+49
(0)6151-817320 / Fax:+49 (0)6151-817329, [email protected]
-- 
drivers/net/can/sja1000/sja1000.c +7 -0
index 7164a99..57b5d44 100644
@@ -326,6 +326,8 @@ static void sja1000_rx(struct net_device *dev)
 	struct net_device_stats *stats = &dev->stats;
 	struct can_frame *cf;
 	struct sk_buff *skb;
+	struct timespec tsraw, tsreal;
+	struct skb_shared_hwtstamps *hwts;
 	uint8_t fi;
 	uint8_t dreg;
 	canid_t id;
@@ -366,6 +368,11 @@ static void sja1000_rx(struct net_device *dev)
 	/* release receive buffer */
 	sja1000_write_cmdreg(priv, CMD_RRB);
 
+	getnstime_raw_and_real(&tsraw, &tsreal);
+	skb->tstamp = timespec_to_ktime(tsreal);
+	hwts = skb_hwtstamps(skb);
+	hwts->syststamp = timespec_to_ktime(tsraw);
+
 	netif_rx(skb);
 
 	stats->rx_packets++;
kernel/time/timekeeping.c +0 -4
index 947ba25..19fc013 100644
@@ -431,8 +431,6 @@ ktime_t ktime_get_clocktai(void)
 }
 EXPORT_SYMBOL(ktime_get_clocktai);
 
-#ifdef CONFIG_NTP_PPS
-
 /**
  * getnstime_raw_and_real - get day and raw monotonic time in timespec format
  * @ts_raw:	pointer to the timespec to be set to raw monotonic time
@@ -467,8 +465,6 @@ void getnstime_raw_and_real(struct timespec *ts_raw, struct timespec *ts_real)
 }
 EXPORT_SYMBOL(getnstime_raw_and_real);
 
-#endif /* CONFIG_NTP_PPS */
-
 /**
  * do_gettimeofday - Returns the time of day in a timeval
  * @tv:		pointer to the timeval to be set
Makefile +1 -0
index 2f79ee7..40067fb 100644
@@ -45,6 +45,7 @@ MAKEFLAGS = -k
 
 CFLAGS    = -O2 -Wall -Wno-parentheses -Iinclude \
 	    -fno-strict-aliasing \
+	    -DSO_TIMESTAMPING=37 \
 	    -DSO_RXQ_OVFL=40 \
 	    -DPF_CAN=29 \
 	    -DAF_CAN=PF_CAN
candump.c +77 -12

152 lines not on this page · raw message

include/linux/net_tstamp.h +1 -0
index e69de29..a8724a7 100644
@@ -0,0 +1 @@
+#include <socketcan/net_tstamp.h>
include/socketcan/net_tstamp.h +113 -0

113 lines not on this page · raw message

#2 lore raw

Hi Oliver,

(sending this message again, first was in HTML... Sorry for the noise)

Thanks for your quick answer.
Meanwhile, I finally found by myself how to get the "hardware" timestamps the (peak_usb) driver is saving for each CAN frame it receives... Comparing to your candump patch, there are several things a bit different I want to discuss about:

Your patch enables to get the (so-called) "hardware raw timestamp" as well as the "hardware system transformed timestamp", right ?

When I look into net/socket.c, both timestamps are copied by "__sock_recv_timestamp()", according to:

- SOCK_TIMESTAMPING_RAW_HARDWARE flag ("shhwtstamps->hwtstamp" is copied into the skb ctrlmsg)
- SOCK_TIMESTAMPING_SYS_HARDWARE flag ("shhwtstamps->syststamp" is copied into the skb ctrlmsg)

If I understand well:

"hwtstamp" is the RAW timestamp received from the CAN device, without ANY transformation, while "syststamp" is a "system transformed hardware timestamp", which I understand as a timestamp the CAN device driver has computed (according to the "raw timestamp" for example), to be consistent with the system/kernel time.

So, a well-mannered linux-can device driver should (in case it is able to get hardware timestamps from its device):

- store in "hwstamp" the raw value received from the device
- store in "syststamp" the "transformed" value the driver computes

Is it right?

Regards,

Stéphane

Quoted 17 lines · Oliver Hartkopp

Hi Stephane,

here's a discussion thread from last year focussing HW timestamping:

http://marc.info/?l=linux-can&m=138210737431112&w=2

Additionally I attached two patches:

cants-test.patch:
added some functionality to add a monotonic (sw) timestamp to sja1000

candump-hwts.patch:
added some functionality to candump to get these timestamps

The candump patch is from the time before the include file cleanup inside the can-utils provided by Uwe. (including from socketcan directory)

Quoted 38 lines

Together with the discussion thread from above, this should give a good starting point.

Regards,
Oliver

Quoted 30 lines · Stephane Grosjean

Hi linux-can team,

I've got one question about how timestamping is done now in linux-can, regarding to HW timestamps.

In the early ages (~v3.4), the CAN hardware driver could set the timestamp of an skb by itself and push it with the received CAN frame, so that the application could get it using SO_TIMESTAMP socket option, right? Now, this "hardware" timestamp is to be copied into "hwstamp" field of the "skb_hwtstamps(skb)" area.

But how does user application manage to get this hardware timestamp on its side? AFAIK, the "candump" can-utils utility always reads and displays the "network" timestamp (that is, always uses SO_TIMESTAMP socket option). I had a quick look to the Kernel sources and tried to find the links between things but it's not very clear to me: first idea I tested was to set the SO_TIMESTAMPING socket option, but candump never received any hw timestamp in the control messages he reads from the CAN socket...

Any help would be appreciated.

Regards,

Stéphane

Signature · 5 lines
PEAK-System Technik GmbH, Otto-Roehm-Strasse 69, D-64293 Darmstadt
Geschaeftsleitung: A.Gach/U.Wilhelm,St.Nr.:007/241/13586 FA Darmstadt HRB-9183
Darmstadt, Ust.IdNr.:DE 202220078, WEE-Reg.-Nr.: DE39305391 Tel.+49
(0)6151-817320 / Fax:+49 (0)6151-817329,[email protected]
-- 

--
PEAK-System Technik GmbH, Otto-Roehm-Strasse 69, D-64293 Darmstadt Geschaeftsleitung: A.Gach/U.Wilhelm,St.Nr.:007/241/13586 FA Darmstadt HRB-9183 Darmstadt, Ust.IdNr.:DE 202220078, WEE-Reg.-Nr.: DE39305391 Tel.+49 (0)6151-817320 / Fax:+49 (0)6151-817329, [email protected]

#3 lore raw
Quoted 2 lines · Stephane Grosjean

Meanwhile, I finally found by myself how to get the "hardware" timestamps the (peak_usb) driver is saving for each CAN frame it receives...

Yes. That was a quick patch that time to put the PCAN USB hw timestamp to a less bad place :-)

Quoted 5 lines

Comparing to your candump patch, there are several things a bit different I want to discuss about:

Your patch enables to get the (so-called) "hardware raw timestamp" as well as the "hardware system transformed timestamp", right ?

In the patch I was using the getnstime_raw_and_real(&tsraw, &tsreal) function to test the syscall API. As the SJA1000 does not have any hw timestamp I just wanted the standard sys timestamp and a monotonic clock. The latter is important for logfiles as you don't want to have clock adjustments or clock jumps (e.g. from ntp) in your logfile.

Quoted 9 lines

When I look into net/socket.c, both timestamps are copied by "__sock_recv_timestamp()", according to:

- SOCK_TIMESTAMPING_RAW_HARDWARE flag ("shhwtstamps->hwtstamp" is copied into the skb ctrlmsg)
- SOCK_TIMESTAMPING_SYS_HARDWARE flag ("shhwtstamps->syststamp" is copied into the skb ctrlmsg)

Quoted 7 lines

If I understand well:

"hwtstamp" is the RAW timestamp received from the CAN device, without ANY transformation, while "syststamp" is a "system transformed hardware timestamp", which I understand as a timestamp the CAN device driver has computed (according to the "raw timestamp" for example), to be consistent with the system/kernel time.

That's my understanding too.

Quoted 7 lines

So, a well-mannered linux-can device driver should (in case it is able to get hardware timestamps from its device):

- store in "hwstamp" the raw value received from the device
- store in "syststamp" the "transformed" value the driver computes

Is it right?

Yes. But to me a

- hwtstamp (raw from the device)
- monotonic systime (just a monotonic clock)
- tstamp (standard system time - might be changed by ntp)

makes more sense.

To me it's unclear how this magic "transformation" is intended to work. Did you find any handy description what this transformation should do?

Btw. there was a recent discussion on netdev ML where the unclear timestamp definitions were discussed too:

http://marc.info/?t=139389972600001&r=1&w=2

Which led to this patch:
http://marc.info/?l=linux-netdev&m=139398266230777&w=2

Regards,
Oliver