* Flexcan - timestamp from message buffer to userspace
@ 2013-10-18 9:56 Martin Kozusky
2013-10-18 10:55 ` Martin Kozusky
0 siblings, 1 reply; 12+ messages in thread
From: Martin Kozusky @ 2013-10-18 9:56 UTC (permalink / raw)
To: linux-can
Hello,
is there any official way how to read timestamp from flexcans message
buffer?
I see there is a macro defined FLEXCAN_MB_CNT_TIMESTAMP in flexcan.c,
but not used.
I would modify function flecan_read_fifo like
+ u32 timestamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
but what to do with timestamp variable next and how to read it in
userspace? :) I could change structure can_frame and add u32 timestamp
into it, but it wouldn't be very nice hack I think.
BTW: is timestamp read with SO_TIMESTAMP actualy taken when CAN message
arrives?
Thanks,
Martin
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Flexcan - timestamp from message buffer to userspace
2013-10-18 9:56 Flexcan - timestamp from message buffer to userspace Martin Kozusky
@ 2013-10-18 10:55 ` Martin Kozusky
2013-10-18 14:42 ` Oliver Hartkopp
0 siblings, 1 reply; 12+ messages in thread
From: Martin Kozusky @ 2013-10-18 10:55 UTC (permalink / raw)
To: linux-can
Dne 18.10.2013 11:56, Martin Kozusky napsal(a):
> Hello,
> is there any official way how to read timestamp from flexcans message
> buffer?
> I see there is a macro defined FLEXCAN_MB_CNT_TIMESTAMP in flexcan.c,
> but not used.
> I would modify function flecan_read_fifo like
>
> + u32 timestamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
sorry, u32 should be just u16
> but what to do with timestamp variable next and how to read it in
> userspace? :) I could change structure can_frame and add u32 timestamp
also u16, not u32
> into it, but it wouldn't be very nice hack I think.
>
> BTW: is timestamp read with SO_TIMESTAMP actualy taken when CAN message
> arrives?
>
> Thanks,
> Martin
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Flexcan - timestamp from message buffer to userspace
2013-10-18 10:55 ` Martin Kozusky
@ 2013-10-18 14:42 ` Oliver Hartkopp
2013-10-21 6:54 ` Martin Kozusky
0 siblings, 1 reply; 12+ messages in thread
From: Oliver Hartkopp @ 2013-10-18 14:42 UTC (permalink / raw)
To: Martin Kozusky; +Cc: linux-can
On 18.10.2013 12:55, Martin Kozusky wrote:
>
> Dne 18.10.2013 11:56, Martin Kozusky napsal(a):
>> Hello,
>> is there any official way how to read timestamp from flexcans message
>> buffer?
>> I see there is a macro defined FLEXCAN_MB_CNT_TIMESTAMP in flexcan.c,
>> but not used.
>> I would modify function flecan_read_fifo like
>>
>> + u32 timestamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
>
> sorry, u32 should be just u16
>
>> but what to do with timestamp variable next and how to read it in
>> userspace? :) I could change structure can_frame and add u32 timestamp
> also u16, not u32
>
>> into it, but it wouldn't be very nice hack I think.
>>
>> BTW: is timestamp read with SO_TIMESTAMP actualy taken when CAN message
>> arrives?
>>
Hello Martin,
with SO_TIMESTAMP you get the system timestamp in nanosec resolution.
It is set at the time when the CAN frame is pushed to the network layer by
the CAN drivers interrupt routine.
See net_timestamp_check() in netif_rx():
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/core/dev.c#n3228
You may get this timestamp via ioctl() or recvmsg().
To pass hardware timestamps there's some infrastructure for ethernet devices in the
mainlaine kernel, which is configured with "ethtool":
ethtool -T|--show-time-stamping DEVNAME Show time stamping capabilities
See details at
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping.txt
And some example source code at
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping/timestamping.c
There needs to be added some infrastructure to the network devices to query
and configure the timestamping possibilities.
This is currently missing for CAN devices ...
Even if I moved a wrongly assigned hardware timestamp to another place here:
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/net/can/usb/peak_usb?id=c9faaa09e2a1335678f09c70a0d0eda095564bab
the rest of the hardware timestamping (& configuration) is still missing.
Regards,
Oliver
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Flexcan - timestamp from message buffer to userspace
2013-10-18 14:42 ` Oliver Hartkopp
@ 2013-10-21 6:54 ` Martin Kozusky
2013-10-21 8:00 ` Wolfgang Grandegger
0 siblings, 1 reply; 12+ messages in thread
From: Martin Kozusky @ 2013-10-21 6:54 UTC (permalink / raw)
To: linux-can
Dne 18.10.2013 16:42, Oliver Hartkopp napsal(a):
> On 18.10.2013 12:55, Martin Kozusky wrote:
>>
>> Dne 18.10.2013 11:56, Martin Kozusky napsal(a):
>>> Hello,
>>> is there any official way how to read timestamp from flexcans message
>>> buffer?
>>> I see there is a macro defined FLEXCAN_MB_CNT_TIMESTAMP in flexcan.c,
>>> but not used.
>>> I would modify function flecan_read_fifo like
>>>
>>> + u32 timestamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
>>
>> sorry, u32 should be just u16
>>
>>> but what to do with timestamp variable next and how to read it in
>>> userspace? :) I could change structure can_frame and add u32 timestamp
>> also u16, not u32
>>
>>> into it, but it wouldn't be very nice hack I think.
>>>
>>> BTW: is timestamp read with SO_TIMESTAMP actualy taken when CAN message
>>> arrives?
>>>
>
> Hello Martin,
>
> with SO_TIMESTAMP you get the system timestamp in nanosec resolution.
>
> It is set at the time when the CAN frame is pushed to the network layer by
> the CAN drivers interrupt routine.
>
> See net_timestamp_check() in netif_rx():
>
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/core/dev.c#n3228
Hello Oliver,
I'm already using SO_TIMESTAMP with recvmmsg so may be I should switch
to SO_TIMESTAMPNS for better times, right?
> You may get this timestamp via ioctl() or recvmsg().
>
> To pass hardware timestamps there's some infrastructure for ethernet devices in the
> mainlaine kernel, which is configured with "ethtool":
>
> ethtool -T|--show-time-stamping DEVNAME Show time stamping capabilities
>
> See details at
>
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping.txt
>
> And some example source code at
>
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping/timestamping.c
>
> There needs to be added some infrastructure to the network devices to query
> and configure the timestamping possibilities.
>
> This is currently missing for CAN devices ...
>
> Even if I moved a wrongly assigned hardware timestamp to another place here:
>
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/net/can/usb/peak_usb?id=c9faaa09e2a1335678f09c70a0d0eda095564bab
>
> the rest of the hardware timestamping (& configuration) is still missing.
So I could just do
struct skb_shared_hwtstamps *hwts;
hwts = skb_hwtstamps(skb);
hwts->hwtstamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
in flecan_read_fifo ?
And then how to read it?
Or will it be easier for me just to change can_frame structure? :)
Thanks,
Martin
> Regards,
> Oliver
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-can" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Flexcan - timestamp from message buffer to userspace
2013-10-21 6:54 ` Martin Kozusky
@ 2013-10-21 8:00 ` Wolfgang Grandegger
2013-10-21 8:11 ` Wolfgang Grandegger
0 siblings, 1 reply; 12+ messages in thread
From: Wolfgang Grandegger @ 2013-10-21 8:00 UTC (permalink / raw)
To: Martin Kozusky; +Cc: linux-can
On Mon, 21 Oct 2013 08:54:30 +0200, Martin Kozusky <mkozusky@kkmicro.cz>
wrote:
> Dne 18.10.2013 16:42, Oliver Hartkopp napsal(a):
>> On 18.10.2013 12:55, Martin Kozusky wrote:
>>>
>>> Dne 18.10.2013 11:56, Martin Kozusky napsal(a):
>>>> Hello,
>>>> is there any official way how to read timestamp from flexcans message
>>>> buffer?
>>>> I see there is a macro defined FLEXCAN_MB_CNT_TIMESTAMP in flexcan.c,
>>>> but not used.
>>>> I would modify function flecan_read_fifo like
>>>>
>>>> + u32 timestamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
>>>
>>> sorry, u32 should be just u16
>>>
>>>> but what to do with timestamp variable next and how to read it in
>>>> userspace? :) I could change structure can_frame and add u32
timestamp
>>> also u16, not u32
>>>
>>>> into it, but it wouldn't be very nice hack I think.
>>>>
>>>> BTW: is timestamp read with SO_TIMESTAMP actualy taken when CAN
>>>> message
>>>> arrives?
>>>>
>>
>> Hello Martin,
>>
>> with SO_TIMESTAMP you get the system timestamp in nanosec resolution.
>>
>> It is set at the time when the CAN frame is pushed to the network layer
>> by
>> the CAN drivers interrupt routine.
>>
>> See net_timestamp_check() in netif_rx():
>>
>>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/core/dev.c#n3228
> Hello Oliver,
> I'm already using SO_TIMESTAMP with recvmmsg so may be I should switch
> to SO_TIMESTAMPNS for better times, right?
>
>> You may get this timestamp via ioctl() or recvmsg().
>>
>> To pass hardware timestamps there's some infrastructure for ethernet
>> devices in the
>> mainlaine kernel, which is configured with "ethtool":
>>
>> ethtool -T|--show-time-stamping DEVNAME Show time stamping
>> capabilities
>>
>> See details at
>>
>>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping.txt
>>
>> And some example source code at
>>
>>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping/timestamping.c
>>
>> There needs to be added some infrastructure to the network devices to
>> query
>> and configure the timestamping possibilities.
>>
>> This is currently missing for CAN devices ...
>>
>> Even if I moved a wrongly assigned hardware timestamp to another place
>> here:
>>
>>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/net/can/usb/peak_usb?id=c9faaa09e2a1335678f09c70a0d0eda095564bab
>>
>> the rest of the hardware timestamping (& configuration) is still
missing.
>
> So I could just do
>
> struct skb_shared_hwtstamps *hwts;
> hwts = skb_hwtstamps(skb);
> hwts->hwtstamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
>
> in flecan_read_fifo ?
>
> And then how to read it?
See:
http://lxr.free-electrons.com/source/Documentation/networking/timestamping/
>
> Or will it be easier for me just to change can_frame structure? :)
No.
> Thanks,
> Martin
>
>> Regards,
>> Oliver
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-can" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-can" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Flexcan - timestamp from message buffer to userspace
2013-10-21 8:00 ` Wolfgang Grandegger
@ 2013-10-21 8:11 ` Wolfgang Grandegger
2013-10-21 8:54 ` Martin Kozusky
0 siblings, 1 reply; 12+ messages in thread
From: Wolfgang Grandegger @ 2013-10-21 8:11 UTC (permalink / raw)
To: Martin Kozusky; +Cc: linux-can
My previous mail went out to early, sorry... completing it now...
On Mon, 21 Oct 2013 10:00:28 +0200, Wolfgang Grandegger
<wg@grandegger.com> wrote:
> On Mon, 21 Oct 2013 08:54:30 +0200, Martin Kozusky <mkozusky@kkmicro.cz>
> wrote:
>> Dne 18.10.2013 16:42, Oliver Hartkopp napsal(a):
>>> On 18.10.2013 12:55, Martin Kozusky wrote:
>>>>
>>>> Dne 18.10.2013 11:56, Martin Kozusky napsal(a):
>>>>> Hello,
>>>>> is there any official way how to read timestamp from flexcans
message
>>>>> buffer?
>>>>> I see there is a macro defined FLEXCAN_MB_CNT_TIMESTAMP in
flexcan.c,
>>>>> but not used.
>>>>> I would modify function flecan_read_fifo like
>>>>>
>>>>> + u32 timestamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
>>>>
>>>> sorry, u32 should be just u16
>>>>
>>>>> but what to do with timestamp variable next and how to read it in
>>>>> userspace? :) I could change structure can_frame and add u32
> timestamp
>>>> also u16, not u32
>>>>
>>>>> into it, but it wouldn't be very nice hack I think.
>>>>>
>>>>> BTW: is timestamp read with SO_TIMESTAMP actualy taken when CAN
>>>>> message
>>>>> arrives?
>>>>>
>>>
>>> Hello Martin,
>>>
>>> with SO_TIMESTAMP you get the system timestamp in nanosec resolution.
>>>
>>> It is set at the time when the CAN frame is pushed to the network
layer
>>> by
>>> the CAN drivers interrupt routine.
>>>
>>> See net_timestamp_check() in netif_rx():
>>>
>>>
>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/core/dev.c#n3228
>> Hello Oliver,
>> I'm already using SO_TIMESTAMP with recvmmsg so may be I should switch
>> to SO_TIMESTAMPNS for better times, right?
>>
>>> You may get this timestamp via ioctl() or recvmsg().
>>>
>>> To pass hardware timestamps there's some infrastructure for ethernet
>>> devices in the
>>> mainlaine kernel, which is configured with "ethtool":
>>>
>>> ethtool -T|--show-time-stamping DEVNAME Show time stamping
>>> capabilities
>>>
>>> See details at
>>>
>>>
>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping.txt
>>>
>>> And some example source code at
>>>
>>>
>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping/timestamping.c
>>>
>>> There needs to be added some infrastructure to the network devices to
>>> query
>>> and configure the timestamping possibilities.
>>>
>>> This is currently missing for CAN devices ...
>>>
>>> Even if I moved a wrongly assigned hardware timestamp to another place
>>> here:
>>>
>>>
>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/net/can/usb/peak_usb?id=c9faaa09e2a1335678f09c70a0d0eda095564bab
>>>
>>> the rest of the hardware timestamping (& configuration) is still
> missing.
Supporting SIOCSHWTSTAMP seem the right way to go.
>>
>> So I could just do
>>
>> struct skb_shared_hwtstamps *hwts;
>> hwts = skb_hwtstamps(skb);
Most drivers do as well:
memset(hwts, 0, sizeof(*hwts));
>> hwts->hwtstamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
This should assign a proper ktime. [nm]s_to_ktime() may help.
>>
>> in flecan_read_fifo ?
>>
>> And then how to read it?
>
> See:
>
>
http://lxr.free-electrons.com/source/Documentation/networking/timestamping/
This also shows how to do read the timestamp.
>
>>
>> Or will it be easier for me just to change can_frame structure? :)
>
> No.
Please use the forseen interface.
Wolfgang
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Flexcan - timestamp from message buffer to userspace
2013-10-21 8:11 ` Wolfgang Grandegger
@ 2013-10-21 8:54 ` Martin Kozusky
2013-10-21 9:51 ` Martin Kozusky
0 siblings, 1 reply; 12+ messages in thread
From: Martin Kozusky @ 2013-10-21 8:54 UTC (permalink / raw)
To: linux-can; +Cc: Wolfgang Grandegger
Dne 21.10.2013 10:11, Wolfgang Grandegger napsal(a):
> My previous mail went out to early, sorry... completing it now...
>
>
>
> On Mon, 21 Oct 2013 10:00:28 +0200, Wolfgang Grandegger
>
> <wg@grandegger.com> wrote:
>
>> On Mon, 21 Oct 2013 08:54:30 +0200, Martin Kozusky <mkozusky@kkmicro.cz>
>
>> wrote:
>
>>> Dne 18.10.2013 16:42, Oliver Hartkopp napsal(a):
>
>>>> On 18.10.2013 12:55, Martin Kozusky wrote:
>
>>>>>
>
>>>>> Dne 18.10.2013 11:56, Martin Kozusky napsal(a):
>
>>>>>> Hello,
>
>>>>>> is there any official way how to read timestamp from flexcans
>
> message
>
>>>>>> buffer?
>
>>>>>> I see there is a macro defined FLEXCAN_MB_CNT_TIMESTAMP in
>
> flexcan.c,
>
>>>>>> but not used.
>
>>>>>> I would modify function flecan_read_fifo like
>
>>>>>>
>
>>>>>> + u32 timestamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
>
>>>>>
>
>>>>> sorry, u32 should be just u16
>
>>>>>
>
>>>>>> but what to do with timestamp variable next and how to read it in
>
>>>>>> userspace? :) I could change structure can_frame and add u32
>
>> timestamp
>
>>>>> also u16, not u32
>
>>>>>
>
>>>>>> into it, but it wouldn't be very nice hack I think.
>
>>>>>>
>
>>>>>> BTW: is timestamp read with SO_TIMESTAMP actualy taken when CAN
>
>>>>>> message
>
>>>>>> arrives?
>
>>>>>>
>
>>>>
>
>>>> Hello Martin,
>
>>>>
>
>>>> with SO_TIMESTAMP you get the system timestamp in nanosec resolution.
>
>>>>
>
>>>> It is set at the time when the CAN frame is pushed to the network
>
> layer
>
>>>> by
>
>>>> the CAN drivers interrupt routine.
>
>>>>
>
>>>> See net_timestamp_check() in netif_rx():
>
>>>>
>
>>>>
>
>>
>
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/core/dev.c#n3228
>
>>> Hello Oliver,
>
>>> I'm already using SO_TIMESTAMP with recvmmsg so may be I should switch
>
>>> to SO_TIMESTAMPNS for better times, right?
>
>>>
>
>>>> You may get this timestamp via ioctl() or recvmsg().
>
>>>>
>
>>>> To pass hardware timestamps there's some infrastructure for ethernet
>
>>>> devices in the
>
>>>> mainlaine kernel, which is configured with "ethtool":
>
>>>>
>
>>>> ethtool -T|--show-time-stamping DEVNAME Show time stamping
>
>>>> capabilities
>
>>>>
>
>>>> See details at
>
>>>>
>
>>>>
>
>>
>
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping.txt
>
>>>>
>
>>>> And some example source code at
>
>>>>
>
>>>>
>
>>
>
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping/timestamping.c
>
>>>>
>
>>>> There needs to be added some infrastructure to the network devices to
>
>>>> query
>
>>>> and configure the timestamping possibilities.
>
>>>>
>
>>>> This is currently missing for CAN devices ...
>
>>>>
>
>>>> Even if I moved a wrongly assigned hardware timestamp to another place
>
>>>> here:
>
>>>>
>
>>>>
>
>>
>
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/net/can/usb/peak_usb?id=c9faaa09e2a1335678f09c70a0d0eda095564bab
>
>>>>
>
>>>> the rest of the hardware timestamping (& configuration) is still
>
>> missing.
>
>
>
> Supporting SIOCSHWTSTAMP seem the right way to go.
>
>
>
>>>
>
>>> So I could just do
>
>>>
>
>>> struct skb_shared_hwtstamps *hwts;
>
>>> hwts = skb_hwtstamps(skb);
>
>
>
> Most drivers do as well:
>
>
>
> memset(hwts, 0, sizeof(*hwts));
>
>
>
>>> hwts->hwtstamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
>
>
>
> This should assign a proper ktime. [nm]s_to_ktime() may help.
But value read from registers is just 16bit value having nothing to do
with real time. But now when I see the ns_to_ktime function, it will
just assign my 16bit value to .tv64 union member, ok I will use it.
But I see another problem here:
flexcan registers are read in function flexcan_read_fifo but I need to
know the timestamp in function flexcan_read_frame, how do I transfer it
from there?
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/net/can/flexcan.c#n519
Should I just create some global variable in flexcan.c and store the
16bit value into it and then use it?
>
>>> in flecan_read_fifo ?
>
>>>
>
>>> And then how to read it?
>
>>
>
>> See:
>
>>
>
>>
>
> http://lxr.free-electrons.com/source/Documentation/networking/timestamping/
>
>
>
> This also shows how to do read the timestamp.
>
So you mean this setup:
memset(&hwtstamp, 0, sizeof(hwtstamp));
strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
hwtstamp.ifr_data = (void *)&hwconfig;
memset(&hwconfig, 0, sizeof(hwconfig));
hwconfig.tx_type = HWTSTAMP_TX_OFF;
hwconfig.rx_filter = HWTSTAMP_FILTER_ALL;
hwconfig_requested = hwconfig;
if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) {
if ((errno == EINVAL || errno == ENOTSUP) &&
hwconfig_requested.tx_type == HWTSTAMP_TX_OFF &&
hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE)
printf("SIOCSHWTSTAMP: disabling hardware time stamping not
possible\n");
else
bail("SIOCSHWTSTAMP");
}
printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d
requested, got %d\n",
hwconfig_requested.tx_type, hwconfig.tx_type,
hwconfig_requested.rx_filter, hwconfig.rx_filter);
and read from this cmsg_type:
case SO_TIMESTAMPING: {
struct scm_timestamping *stamp =
(struct scm_timestamping *)CMSG_DATA(cmsg);
printf("SO_TIMESTAMPING ");
printf("HW raw %ld.%09ld",
(long)stamp->hwtimeraw->tv_sec,
(long)stamp->hwtimeraw->tv_nsec);
break;
}
or did I forget something?
Thank you,
Martin
>
>>>
>
>>> Or will it be easier for me just to change can_frame structure? :)
>
>>
>
>> No.
>
>
>
> Please use the forseen interface.
>
>
>
> Wolfgang
> --
> To unsubscribe from this list: send the line "unsubscribe linux-can" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Flexcan - timestamp from message buffer to userspace
2013-10-21 8:54 ` Martin Kozusky
@ 2013-10-21 9:51 ` Martin Kozusky
2013-10-21 11:23 ` Wolfgang Grandegger
0 siblings, 1 reply; 12+ messages in thread
From: Martin Kozusky @ 2013-10-21 9:51 UTC (permalink / raw)
To: linux-can
Dne 21.10.2013 10:54, Martin Kozusky napsal(a):
> Dne 21.10.2013 10:11, Wolfgang Grandegger napsal(a):
>> My previous mail went out to early, sorry... completing it now...
>>
>>
>>
>> On Mon, 21 Oct 2013 10:00:28 +0200, Wolfgang Grandegger
>>
>> <wg@grandegger.com> wrote:
>>
>>> On Mon, 21 Oct 2013 08:54:30 +0200, Martin Kozusky <mkozusky@kkmicro.cz>
>>
>>> wrote:
>>
>>>> Dne 18.10.2013 16:42, Oliver Hartkopp napsal(a):
>>
>>>>> On 18.10.2013 12:55, Martin Kozusky wrote:
>>
>>>>>>
>>
>>>>>> Dne 18.10.2013 11:56, Martin Kozusky napsal(a):
>>
>>>>>>> Hello,
>>
>>>>>>> is there any official way how to read timestamp from flexcans
>>
>> message
>>
>>>>>>> buffer?
>>
>>>>>>> I see there is a macro defined FLEXCAN_MB_CNT_TIMESTAMP in
>>
>> flexcan.c,
>>
>>>>>>> but not used.
>>
>>>>>>> I would modify function flecan_read_fifo like
>>
>>>>>>>
>>
>>>>>>> + u32 timestamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
>>
>>>>>>
>>
>>>>>> sorry, u32 should be just u16
>>
>>>>>>
>>
>>>>>>> but what to do with timestamp variable next and how to read it in
>>
>>>>>>> userspace? :) I could change structure can_frame and add u32
>>
>>> timestamp
>>
>>>>>> also u16, not u32
>>
>>>>>>
>>
>>>>>>> into it, but it wouldn't be very nice hack I think.
>>
>>>>>>>
>>
>>>>>>> BTW: is timestamp read with SO_TIMESTAMP actualy taken when CAN
>>
>>>>>>> message
>>
>>>>>>> arrives?
>>
>>>>>>>
>>
>>>>>
>>
>>>>> Hello Martin,
>>
>>>>>
>>
>>>>> with SO_TIMESTAMP you get the system timestamp in nanosec resolution.
>>
>>>>>
>>
>>>>> It is set at the time when the CAN frame is pushed to the network
>>
>> layer
>>
>>>>> by
>>
>>>>> the CAN drivers interrupt routine.
>>
>>>>>
>>
>>>>> See net_timestamp_check() in netif_rx():
>>
>>>>>
>>
>>>>>
>>
>>>
>>
>> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/core/dev.c#n3228
>>
>>
>>>> Hello Oliver,
>>
>>>> I'm already using SO_TIMESTAMP with recvmmsg so may be I should switch
>>
>>>> to SO_TIMESTAMPNS for better times, right?
>>
>>>>
>>
>>>>> You may get this timestamp via ioctl() or recvmsg().
>>
>>>>>
>>
>>>>> To pass hardware timestamps there's some infrastructure for ethernet
>>
>>>>> devices in the
>>
>>>>> mainlaine kernel, which is configured with "ethtool":
>>
>>>>>
>>
>>>>> ethtool -T|--show-time-stamping DEVNAME Show time stamping
>>
>>>>> capabilities
>>
>>>>>
>>
>>>>> See details at
>>
>>>>>
>>
>>>>>
>>
>>>
>>
>> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping.txt
>>
>>
>>>>>
>>
>>>>> And some example source code at
>>
>>>>>
>>
>>>>>
>>
>>>
>>
>> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping/timestamping.c
>>
>>
>>>>>
>>
>>>>> There needs to be added some infrastructure to the network devices to
>>
>>>>> query
>>
>>>>> and configure the timestamping possibilities.
>>
>>>>>
>>
>>>>> This is currently missing for CAN devices ...
>>
>>>>>
>>
>>>>> Even if I moved a wrongly assigned hardware timestamp to another place
>>
>>>>> here:
>>
>>>>>
>>
>>>>>
>>
>>>
>>
>> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/net/can/usb/peak_usb?id=c9faaa09e2a1335678f09c70a0d0eda095564bab
>>
>>
>>>>>
>>
>>>>> the rest of the hardware timestamping (& configuration) is still
>>
>>> missing.
>>
>>
>>
>> Supporting SIOCSHWTSTAMP seem the right way to go.
>>
>>
>>
>>>>
>>
>>>> So I could just do
>>
>>>>
>>
>>>> struct skb_shared_hwtstamps *hwts;
>>
>>>> hwts = skb_hwtstamps(skb);
>>
>>
>>
>> Most drivers do as well:
>>
>>
>>
>> memset(hwts, 0, sizeof(*hwts));
>>
>>
>>
>>>> hwts->hwtstamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
>>
>>
>>
>> This should assign a proper ktime. [nm]s_to_ktime() may help.
>
> But value read from registers is just 16bit value having nothing to do
> with real time. But now when I see the ns_to_ktime function, it will
> just assign my 16bit value to .tv64 union member, ok I will use it.
>
> But I see another problem here:
> flexcan registers are read in function flexcan_read_fifo but I need to
> know the timestamp in function flexcan_read_frame, how do I transfer it
> from there?
>
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/net/can/flexcan.c#n519
>
>
> Should I just create some global variable in flexcan.c and store the
> 16bit value into it and then use it?
>
>
>>
>>>> in flecan_read_fifo ?
>>
>>>>
>>
>>>> And then how to read it?
>>
>>>
>>
>>> See:
>>
>>>
>>
>>>
>>
>> http://lxr.free-electrons.com/source/Documentation/networking/timestamping/
>>
>>
>>
>>
>> This also shows how to do read the timestamp.
>>
>
>
> So you mean this setup:
>
>
> memset(&hwtstamp, 0, sizeof(hwtstamp));
> strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
> hwtstamp.ifr_data = (void *)&hwconfig;
> memset(&hwconfig, 0, sizeof(hwconfig));
> hwconfig.tx_type = HWTSTAMP_TX_OFF;
> hwconfig.rx_filter = HWTSTAMP_FILTER_ALL;
> hwconfig_requested = hwconfig;
> if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) {
> if ((errno == EINVAL || errno == ENOTSUP) &&
> hwconfig_requested.tx_type == HWTSTAMP_TX_OFF &&
> hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE)
> printf("SIOCSHWTSTAMP: disabling hardware time stamping not
> possible\n");
> else
> bail("SIOCSHWTSTAMP");
> }
> printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d
> requested, got %d\n",
> hwconfig_requested.tx_type, hwconfig.tx_type,
> hwconfig_requested.rx_filter, hwconfig.rx_filter);
When I do
ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) it returns ENOTSUP :( do I have
to define this ioctl somehow in the flexcan driver or somewhere else?
Martin
>
> and read from this cmsg_type:
>
> case SO_TIMESTAMPING: {
> struct scm_timestamping *stamp =
> (struct scm_timestamping *)CMSG_DATA(cmsg);
> printf("SO_TIMESTAMPING ");
> printf("HW raw %ld.%09ld",
> (long)stamp->hwtimeraw->tv_sec,
> (long)stamp->hwtimeraw->tv_nsec);
> break;
> }
>
>
> or did I forget something?
>
> Thank you,
> Martin
>
>>
>>>>
>>
>>>> Or will it be easier for me just to change can_frame structure? :)
>>
>>>
>>
>>> No.
>>
>>
>>
>> Please use the forseen interface.
>>
>>
>>
>> Wolfgang
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-can" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-can" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Flexcan - timestamp from message buffer to userspace
2013-10-21 9:51 ` Martin Kozusky
@ 2013-10-21 11:23 ` Wolfgang Grandegger
2013-10-21 16:29 ` Oliver Hartkopp
0 siblings, 1 reply; 12+ messages in thread
From: Wolfgang Grandegger @ 2013-10-21 11:23 UTC (permalink / raw)
To: Martin Kozusky; +Cc: linux-can
On Mon, 21 Oct 2013 11:51:20 +0200, Martin Kozusky <mkozusky@kkmicro.cz>
wrote:
> Dne 21.10.2013 10:54, Martin Kozusky napsal(a):
>> Dne 21.10.2013 10:11, Wolfgang Grandegger napsal(a):
>>> My previous mail went out to early, sorry... completing it now...
>>>
>>>
>>>
>>> On Mon, 21 Oct 2013 10:00:28 +0200, Wolfgang Grandegger
>>>
>>> <wg@grandegger.com> wrote:
>>>
>>>> On Mon, 21 Oct 2013 08:54:30 +0200, Martin Kozusky
>>>> <mkozusky@kkmicro.cz>
>>>
>>>> wrote:
>>>
>>>>> Dne 18.10.2013 16:42, Oliver Hartkopp napsal(a):
>>>
>>>>>> On 18.10.2013 12:55, Martin Kozusky wrote:
>>>
>>>>>>>
>>>
>>>>>>> Dne 18.10.2013 11:56, Martin Kozusky napsal(a):
>>>
>>>>>>>> Hello,
>>>
>>>>>>>> is there any official way how to read timestamp from flexcans
>>>
>>> message
>>>
>>>>>>>> buffer?
>>>
>>>>>>>> I see there is a macro defined FLEXCAN_MB_CNT_TIMESTAMP in
>>>
>>> flexcan.c,
>>>
>>>>>>>> but not used.
>>>
>>>>>>>> I would modify function flecan_read_fifo like
>>>
>>>>>>>>
>>>
>>>>>>>> + u32 timestamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
>>>
>>>>>>>
>>>
>>>>>>> sorry, u32 should be just u16
>>>
>>>>>>>
>>>
>>>>>>>> but what to do with timestamp variable next and how to read it in
>>>
>>>>>>>> userspace? :) I could change structure can_frame and add u32
>>>
>>>> timestamp
>>>
>>>>>>> also u16, not u32
>>>
>>>>>>>
>>>
>>>>>>>> into it, but it wouldn't be very nice hack I think.
>>>
>>>>>>>>
>>>
>>>>>>>> BTW: is timestamp read with SO_TIMESTAMP actualy taken when CAN
>>>
>>>>>>>> message
>>>
>>>>>>>> arrives?
>>>
>>>>>>>>
>>>
>>>>>>
>>>
>>>>>> Hello Martin,
>>>
>>>>>>
>>>
>>>>>> with SO_TIMESTAMP you get the system timestamp in nanosec
resolution.
>>>
>>>>>>
>>>
>>>>>> It is set at the time when the CAN frame is pushed to the network
>>>
>>> layer
>>>
>>>>>> by
>>>
>>>>>> the CAN drivers interrupt routine.
>>>
>>>>>>
>>>
>>>>>> See net_timestamp_check() in netif_rx():
>>>
>>>>>>
>>>
>>>>>>
>>>
>>>>
>>>
>>>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/core/dev.c#n3228
>>>
>>>
>>>>> Hello Oliver,
>>>
>>>>> I'm already using SO_TIMESTAMP with recvmmsg so may be I should
switch
>>>
>>>>> to SO_TIMESTAMPNS for better times, right?
>>>
>>>>>
>>>
>>>>>> You may get this timestamp via ioctl() or recvmsg().
>>>
>>>>>>
>>>
>>>>>> To pass hardware timestamps there's some infrastructure for
ethernet
>>>
>>>>>> devices in the
>>>
>>>>>> mainlaine kernel, which is configured with "ethtool":
>>>
>>>>>>
>>>
>>>>>> ethtool -T|--show-time-stamping DEVNAME Show time stamping
>>>
>>>>>> capabilities
>>>
>>>>>>
>>>
>>>>>> See details at
>>>
>>>>>>
>>>
>>>>>>
>>>
>>>>
>>>
>>>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping.txt
>>>
>>>
>>>>>>
>>>
>>>>>> And some example source code at
>>>
>>>>>>
>>>
>>>>>>
>>>
>>>>
>>>
>>>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/timestamping/timestamping.c
>>>
>>>
>>>>>>
>>>
>>>>>> There needs to be added some infrastructure to the network devices
to
>>>
>>>>>> query
>>>
>>>>>> and configure the timestamping possibilities.
>>>
>>>>>>
>>>
>>>>>> This is currently missing for CAN devices ...
>>>
>>>>>>
>>>
>>>>>> Even if I moved a wrongly assigned hardware timestamp to another
>>>>>> place
>>>
>>>>>> here:
>>>
>>>>>>
>>>
>>>>>>
>>>
>>>>
>>>
>>>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/net/can/usb/peak_usb?id=c9faaa09e2a1335678f09c70a0d0eda095564bab
>>>
>>>
>>>>>>
>>>
>>>>>> the rest of the hardware timestamping (& configuration) is still
>>>
>>>> missing.
>>>
>>>
>>>
>>> Supporting SIOCSHWTSTAMP seem the right way to go.
>>>
>>>
>>>
>>>>>
>>>
>>>>> So I could just do
>>>
>>>>>
>>>
>>>>> struct skb_shared_hwtstamps *hwts;
>>>
>>>>> hwts = skb_hwtstamps(skb);
>>>
>>>
>>>
>>> Most drivers do as well:
>>>
>>>
>>>
>>> memset(hwts, 0, sizeof(*hwts));
>>>
>>>
>>>
>>>>> hwts->hwtstamp = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
>>>
>>>
>>>
>>> This should assign a proper ktime. [nm]s_to_ktime() may help.
>>
>> But value read from registers is just 16bit value having nothing to do
>> with real time. But now when I see the ns_to_ktime function, it will
>> just assign my 16bit value to .tv64 union member, ok I will use it.
>>
>> But I see another problem here:
>> flexcan registers are read in function flexcan_read_fifo but I need
to
>> know the timestamp in function flexcan_read_frame, how do I transfer it
>> from there?
>>
>>
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/net/can/flexcan.c#n519
>>
>>
>> Should I just create some global variable in flexcan.c and store the
>> 16bit value into it and then use it?
>>
>>
>>>
>>>>> in flecan_read_fifo ?
>>>
>>>>>
>>>
>>>>> And then how to read it?
>>>
>>>>
>>>
>>>> See:
>>>
>>>>
>>>
>>>>
>>>
>>>
http://lxr.free-electrons.com/source/Documentation/networking/timestamping/
>>>
>>>
>>>
>>>
>>> This also shows how to do read the timestamp.
>>>
>>
>>
>> So you mean this setup:
>>
>>
>> memset(&hwtstamp, 0, sizeof(hwtstamp));
>> strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
>> hwtstamp.ifr_data = (void *)&hwconfig;
>> memset(&hwconfig, 0, sizeof(hwconfig));
>> hwconfig.tx_type = HWTSTAMP_TX_OFF;
>> hwconfig.rx_filter = HWTSTAMP_FILTER_ALL;
>> hwconfig_requested = hwconfig;
>> if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) {
>> if ((errno == EINVAL || errno == ENOTSUP) &&
>> hwconfig_requested.tx_type == HWTSTAMP_TX_OFF &&
>> hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE)
>> printf("SIOCSHWTSTAMP: disabling hardware time stamping not
>> possible\n");
>> else
>> bail("SIOCSHWTSTAMP");
>> }
>> printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d
>> requested, got %d\n",
>> hwconfig_requested.tx_type, hwconfig.tx_type,
>> hwconfig_requested.rx_filter, hwconfig.rx_filter);
>
> When I do
> ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) it returns ENOTSUP :( do I have
> to define this ioctl somehow in the flexcan driver or somewhere else?
Yes, it looks like. Doing an "identifier search" for SIOCSHWTSTAMP in
"http://lxr.free-electrons.com/source/" should list various drivers
implementing that request.
Wolfgang.
> Martin
>
>>
>> and read from this cmsg_type:
>>
>> case SO_TIMESTAMPING: {
>> struct scm_timestamping *stamp =
>> (struct scm_timestamping *)CMSG_DATA(cmsg);
>> printf("SO_TIMESTAMPING ");
>> printf("HW raw %ld.%09ld",
>> (long)stamp->hwtimeraw->tv_sec,
>> (long)stamp->hwtimeraw->tv_nsec);
>> break;
>> }
>>
>>
>> or did I forget something?
>>
>> Thank you,
>> Martin
>>
>>>
>>>>>
>>>
>>>>> Or will it be easier for me just to change can_frame structure? :)
>>>
>>>>
>>>
>>>> No.
>>>
>>>
>>>
>>> Please use the forseen interface.
>>>
>>>
>>>
>>> Wolfgang
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-can"
in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>>
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-can" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-can" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Flexcan - timestamp from message buffer to userspace
2013-10-21 11:23 ` Wolfgang Grandegger
@ 2013-10-21 16:29 ` Oliver Hartkopp
2013-10-22 12:22 ` Martin Kozusky
0 siblings, 1 reply; 12+ messages in thread
From: Oliver Hartkopp @ 2013-10-21 16:29 UTC (permalink / raw)
To: Wolfgang Grandegger, Martin Kozusky; +Cc: linux-can
On 21.10.2013 13:23, Wolfgang Grandegger wrote:
> On Mon, 21 Oct 2013 11:51:20 +0200, Martin Kozusky <mkozusky@kkmicro.cz>
>
>> When I do
>
>> ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) it returns ENOTSUP :( do I have
>
>> to define this ioctl somehow in the flexcan driver or somewhere else?
>
>
>
> Yes, it looks like. Doing an "identifier search" for SIOCSHWTSTAMP in
>
> "http://lxr.free-electrons.com/source/" should list various drivers
>
> implementing that request.
>
Hi Martin,
if you want to configure the selection of available timestamps, there needs
to be implemented something in the driver itself.
E.g. if a network driver supports filtering for special packet types to send
the timestamps only for these packets, it need to present it's capabilities
and also needs to implement the existing configuration API.
E.g. if you say:
# ethtool -T can0
Time stamping parameters for can0:
Capabilities:
software-receive (SOF_TIMESTAMPING_RX_SOFTWARE)
software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
PTP Hardware Clock: none
Hardware Transmit Timestamp Modes: none
Hardware Receive Filter Modes: none
This is the output from my SJA1000 based EMS PCMCIA card.
But for the software device vcan0 it's the same.
From what i get from this interface is only software timestamps.
I played with candump yesterday:
diff --git a/candump.c b/candump.c
index c865bd7..44a59b2 100644
--- a/candump.c
+++ b/candump.c
@@ -60,6 +60,7 @@
#include <linux/can.h>
#include <linux/can/raw.h>
+#include <linux/net_tstamp.h>
#include "terminal.h"
#include "lib.h"
@@ -537,6 +538,7 @@ int main(int argc, char **argv)
if (timestamp || log || logfrmt) {
+#if 1
const int timestamp_on = 1;
if (setsockopt(s[i], SOL_SOCKET, SO_TIMESTAMP,
@@ -544,6 +546,17 @@ int main(int argc, char **argv)
perror("setsockopt SO_TIMESTAMP");
return 1;
}
+#endif
+#if 1
+// const int timestamping_flags = ( SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_SOFTWARE);
+ const int timestamping_flags = ( SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE);
+
+ if (setsockopt(s[i], SOL_SOCKET, SO_TIMESTAMPING,
+ ×tamping_flags, sizeof(timestamping_flags)) < 0) {
+ perror("setsockopt SO_TIMESTAMPING");
+ return 1;
+ }
+#endif
}
if (dropmonitor) {
@@ -664,10 +677,36 @@ 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) {
+ printf("SO_TIMESTAMP\n");
tv = *(struct timeval *)CMSG_DATA(cmsg);
- else if (cmsg->cmsg_type == SO_RXQ_OVFL)
+ } else if (cmsg->cmsg_type == SO_TIMESTAMPNS) {
+ printf("SO_TIMESTAMPNS\n");
+ tv = *(struct timeval *)CMSG_DATA(cmsg);
+ } else if (cmsg->cmsg_type == SO_TIMESTAMPING) {
+
+ struct timespec *stamp = (struct timespec *)CMSG_DATA(cmsg);
+
+ printf("SO_TIMESTAMPING\n");
+ tv = *(struct timeval *)CMSG_DATA(cmsg);
+
+ printf("SW %lu.%09lu ",
+ (long)stamp->tv_sec,
+ (long)stamp->tv_nsec);
+ stamp++;
+ printf("HW transformed %lu.%09lu ",
+ (long)stamp->tv_sec,
+ (long)stamp->tv_nsec);
+ stamp++;
+ printf("HW raw %lu.%09lu",
+ (long)stamp->tv_sec,
+ (long)stamp->tv_nsec);
+ printf("\n");
+
+ } else if (cmsg->cmsg_type == SO_RXQ_OVFL) {
+ printf("SO_RXQ_OVFL\n");
dropcnt[i] = *(__u32 *)CMSG_DATA(cmsg);
+ } else printf("cmsg->cmsg_type = %d\n", cmsg->cmsg_type);
}
/* check for (unlikely) dropped frames on this specific socket */
The problem is, when i set both SO_TIMESTAMP AND SO_TIMESTAMPING i get trash
in the SO_TIMESTAMPING values.
When I set either SO_TIMESTAMP OR SO_TIMESTAMPING i can see a good and valid
software timestamp. (compared with an unmodified candump).
Any idea about that?
Best regards,
Oliver
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: Flexcan - timestamp from message buffer to userspace
2013-10-21 16:29 ` Oliver Hartkopp
@ 2013-10-22 12:22 ` Martin Kozusky
2013-10-22 19:36 ` Oliver Hartkopp
0 siblings, 1 reply; 12+ messages in thread
From: Martin Kozusky @ 2013-10-22 12:22 UTC (permalink / raw)
To: linux-can; +Cc: socketcan
Dne 21.10.2013 18:29, Oliver Hartkopp napsal(a):
> On 21.10.2013 13:23, Wolfgang Grandegger wrote:
>> On Mon, 21 Oct 2013 11:51:20 +0200, Martin Kozusky <mkozusky@kkmicro.cz>
>
>
>>
>>> When I do
>>
>>> ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) it returns ENOTSUP :( do I have
>>
>>> to define this ioctl somehow in the flexcan driver or somewhere else?
>>
>>
>>
>> Yes, it looks like. Doing an "identifier search" for SIOCSHWTSTAMP in
>>
>> "http://lxr.free-electrons.com/source/" should list various drivers
>>
>> implementing that request.
>>
>
> Hi Martin,
>
> if you want to configure the selection of available timestamps, there needs
> to be implemented something in the driver itself.
>
> E.g. if a network driver supports filtering for special packet types to send
> the timestamps only for these packets, it need to present it's capabilities
> and also needs to implement the existing configuration API.
>
> E.g. if you say:
> # ethtool -T can0
> Time stamping parameters for can0:
> Capabilities:
> software-receive (SOF_TIMESTAMPING_RX_SOFTWARE)
> software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
> PTP Hardware Clock: none
> Hardware Transmit Timestamp Modes: none
> Hardware Receive Filter Modes: none
>
> This is the output from my SJA1000 based EMS PCMCIA card.
> But for the software device vcan0 it's the same.
>
> From what i get from this interface is only software timestamps.
>
> I played with candump yesterday:
>
> diff --git a/candump.c b/candump.c
> index c865bd7..44a59b2 100644
> --- a/candump.c
> +++ b/candump.c
> @@ -60,6 +60,7 @@
>
> #include <linux/can.h>
> #include <linux/can/raw.h>
> +#include <linux/net_tstamp.h>
>
> #include "terminal.h"
> #include "lib.h"
> @@ -537,6 +538,7 @@ int main(int argc, char **argv)
>
> if (timestamp || log || logfrmt) {
>
> +#if 1
> const int timestamp_on = 1;
>
> if (setsockopt(s[i], SOL_SOCKET, SO_TIMESTAMP,
> @@ -544,6 +546,17 @@ int main(int argc, char **argv)
> perror("setsockopt SO_TIMESTAMP");
> return 1;
> }
> +#endif
> +#if 1
> +// const int timestamping_flags = ( SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_SOFTWARE);
> + const int timestamping_flags = ( SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE);
> +
> + if (setsockopt(s[i], SOL_SOCKET, SO_TIMESTAMPING,
> + ×tamping_flags, sizeof(timestamping_flags)) < 0) {
> + perror("setsockopt SO_TIMESTAMPING");
> + return 1;
> + }
> +#endif
> }
>
> if (dropmonitor) {
> @@ -664,10 +677,36 @@ 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) {
> + printf("SO_TIMESTAMP\n");
> tv = *(struct timeval *)CMSG_DATA(cmsg);
> - else if (cmsg->cmsg_type == SO_RXQ_OVFL)
> + } else if (cmsg->cmsg_type == SO_TIMESTAMPNS) {
> + printf("SO_TIMESTAMPNS\n");
> + tv = *(struct timeval *)CMSG_DATA(cmsg);
> + } else if (cmsg->cmsg_type == SO_TIMESTAMPING) {
> +
> + struct timespec *stamp = (struct timespec *)CMSG_DATA(cmsg);
> +
> + printf("SO_TIMESTAMPING\n");
> + tv = *(struct timeval *)CMSG_DATA(cmsg);
> +
> + printf("SW %lu.%09lu ",
> + (long)stamp->tv_sec,
> + (long)stamp->tv_nsec);
> + stamp++;
> + printf("HW transformed %lu.%09lu ",
> + (long)stamp->tv_sec,
> + (long)stamp->tv_nsec);
> + stamp++;
> + printf("HW raw %lu.%09lu",
> + (long)stamp->tv_sec,
> + (long)stamp->tv_nsec);
> + printf("\n");
> +
> + } else if (cmsg->cmsg_type == SO_RXQ_OVFL) {
> + printf("SO_RXQ_OVFL\n");
> dropcnt[i] = *(__u32 *)CMSG_DATA(cmsg);
> + } else printf("cmsg->cmsg_type = %d\n", cmsg->cmsg_type);
> }
>
> /* check for (unlikely) dropped frames on this specific socket */
>
>
>
>
>
> The problem is, when i set both SO_TIMESTAMP AND SO_TIMESTAMPING i get trash
> in the SO_TIMESTAMPING values.
>
> When I set either SO_TIMESTAMP OR SO_TIMESTAMPING i can see a good and valid
> software timestamp. (compared with an unmodified candump).
>
> Any idea about that?
Hello Oliver,
today I was searching kernel sources for the place where SO_TIMESTAMPING msg is filled with data from skb_shared_hwtstamps.
I found a place in net/socket.c - function __sock_recv_timestamp
I found that I just need to use those flags:
const int so_timestamping_flags = SOF_TIMESTAMPING_SOFTWARE|SOF_TIMESTAMPING_RAW_HARDWARE|SOF_TIMESTAMPING_SYS_HARDWARE
to have all 3 items of scm_timestamping struct filled.
So I enabled it with setsockopt SO_TIMESTAMPING ...
And also was getting strange results when I got SO_TIMESTAMP enabled.
Then I was going through kernel sources to the closest level to user and debuged data from msg. Timestamps were always correct in kernel, but not in program.
Then I noticed, that I have ctrmsg used in recvmsg
msg.msg_control = &ctrlmsg
msg.msg_controllen = sizeof(ctrlmsg);
defined as
char ctrlmsg[CMSG_SPACE(sizeof(struct timeval)) + CMSG_SPACE(sizeof(__u32))];
(yes, copied from candump when I was starting :)
I tried to use definition from
http://lxr.free-electrons.com/source/Documentation/networking/timestamping/timestamping.c
struct {
struct cmsghdr cm;
char control[512];
} ctrlmsg;
and wow, it's working now :)
I have all 3 timestamps available and correct. And I can also use SO_TIMESTAMPING and SO_TIMESTAMP together
I also added support for the call of ioctl/SIOCSHWTSTAMP to the flexcan driver (although it does nothing and later I removed this call from the program and just use setsockopt/SO_TIMESTAMPING)
this is my patch for flexcan.c, I could also add support for hwtstamp to error frames, but I don't need that now.
--- flexcan.c_old_2013_10_21 2013-10-21 14:01:56.000000000 +0200
+++ flexcan.c 2013-10-22 14:17:53.000000000 +0200
@@ -459,6 +459,8 @@
return 1;
}
+u16 rx_time;
+
static void flexcan_read_fifo(const struct net_device *dev,
struct can_frame *cf)
{
@@ -481,7 +483,7 @@
*(__be32 *)(cf->data + 0) = cpu_to_be32(readl(&mb->data[0]));
*(__be32 *)(cf->data + 4) = cpu_to_be32(readl(&mb->data[1]));
-
+ rx_time = FLEXCAN_MB_CNT_TIMESTAMP(reg_ctrl);
/* mark as read */
writel(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
readl(®s->timer);
@@ -492,6 +494,7 @@
struct net_device_stats *stats = &dev->stats;
struct can_frame *cf;
struct sk_buff *skb;
+ struct skb_shared_hwtstamps *hwts;
skb = alloc_can_skb(dev, &cf);
if (unlikely(!skb)) {
@@ -499,9 +502,15 @@
return 0;
}
+ skb->tstamp=ktime_get_real(); //get most accurate time, don't wait for netif_receive_skb assignment
+ hwts = skb_hwtstamps(skb);
+ memset(hwts, 0, sizeof(*hwts));
flexcan_read_fifo(dev, cf);
+ hwts->hwtstamp = ns_to_ktime(rx_time);
+ hwts->syststamp = skb->tstamp;
netif_receive_skb(skb);
+ //dev_info(dev->dev.parent, "hwtstamp = %06d\n", rx_time); //timestamp from registers is OK here
stats->rx_packets++;
stats->rx_bytes += cf->can_dlc;
@@ -847,11 +856,26 @@
return 0;
}
+static int flexcan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ switch (cmd)
+ {
+ case SIOCSHWTSTAMP:
+ return 0;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ break;
+ }
+
+ return EINVAL;
+}
static const struct net_device_ops flexcan_netdev_ops = {
.ndo_open = flexcan_open,
.ndo_stop = flexcan_close,
.ndo_start_xmit = flexcan_start_xmit,
+ .ndo_do_ioctl = flexcan_ioctl
};
static int __devinit register_flexcandev(struct net_device *dev)
Martin
> Best regards,
> Oliver
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-can" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
---
Tato zpráva neobsahuje viry ani jiný škodlivý kód - avast! Antivirus je aktivní.
http://www.avast.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Flexcan - timestamp from message buffer to userspace
2013-10-22 12:22 ` Martin Kozusky
@ 2013-10-22 19:36 ` Oliver Hartkopp
0 siblings, 0 replies; 12+ messages in thread
From: Oliver Hartkopp @ 2013-10-22 19:36 UTC (permalink / raw)
To: Martin Kozusky; +Cc: linux-can
On 22.10.2013 14:22, Martin Kozusky wrote:
> Then I noticed, that I have ctrmsg used in recvmsg
> msg.msg_control = &ctrlmsg
> msg.msg_controllen = sizeof(ctrlmsg);
>
> defined as
> char ctrlmsg[CMSG_SPACE(sizeof(struct timeval)) + CMSG_SPACE(sizeof(__u32))];
> (yes, copied from candump when I was starting :)
>
OMG!
What a shame. It's the classic situation not seeing a bug and a guy passing by
your place is pointing at the problem on the monitor :-)
> I tried to use definition from
> http://lxr.free-electrons.com/source/Documentation/networking/timestamping/timestamping.c
>
>
> struct {
> struct cmsghdr cm;
> char control[512];
> } ctrlmsg;
>
> and wow, it's working now :)
\o/
> I have all 3 timestamps available and correct. And I can also use
> SO_TIMESTAMPING and SO_TIMESTAMP together
Me too.
>
> I also added support for the call of ioctl/SIOCSHWTSTAMP to the flexcan driver
> (although it does nothing and later I removed this call from the program and
> just use setsockopt/SO_TIMESTAMPING)
Yes. I can see the HW timestamp from the PCAN USB driver directly now - after
enabling the HW timestamping flags in the TIMESTAMPING sockopt().
>
> this is my patch for flexcan.c, I could also add support for hwtstamp to error
> frames, but I don't need that now.
This would be a good idea to implement this for error messages too.
I assume this was the reason to implement the ioctl() to configure if the
driver should do the work of evaluating the extra timestamps.
Btw. we know how to deal with the API for now. I was searching for a monotonic
SW timestamp that is not affected by any system time adjustments.
Maybe SOF_TIMESTAMPING_SYS_HARDWARE could be used for this, when a HW
timestamp is not available anyway.
Alternatively a fourth element could be added to the existing timestamps in
struct scm_timestamping {
struct timespec systime;
struct timespec hwtimetrans;
struct timespec hwtimeraw;
struct timespec monotonic; /* ??? */
};
Let's see ...
Thanks,
Oliver
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2013-10-22 19:36 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-18 9:56 Flexcan - timestamp from message buffer to userspace Martin Kozusky
2013-10-18 10:55 ` Martin Kozusky
2013-10-18 14:42 ` Oliver Hartkopp
2013-10-21 6:54 ` Martin Kozusky
2013-10-21 8:00 ` Wolfgang Grandegger
2013-10-21 8:11 ` Wolfgang Grandegger
2013-10-21 8:54 ` Martin Kozusky
2013-10-21 9:51 ` Martin Kozusky
2013-10-21 11:23 ` Wolfgang Grandegger
2013-10-21 16:29 ` Oliver Hartkopp
2013-10-22 12:22 ` Martin Kozusky
2013-10-22 19:36 ` Oliver Hartkopp
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox