BCM and SO_TIMESTAMP

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

BCM and SO_TIMESTAMP

uwsch
Hello,

although I have been working with CAN-bus during the last 15 years, I am an absolute newbie concernig socket-can and linux. I did a lot of learning by doing (and reading/programming/testing) during the last few weeks. But now it seams that I am stuck. I have collected some questions which I was not able to answer by reading and testing. So I hope that someone at this forum can answer my questions or give me at least a hint where to find some additional information.

First, I made a program that basically logged the CAN messages (which I selected before using can_filter). I used the RAW socket
socket(PF_CAN, SOCK_RAW, CAN_RAW); 
 with a bind to any interface. I actually use two interfaces can0 and can1.
Reading the messages and the timestamps was done with:
nbytes = read(s, &msg, sizeof(msg));
ioctl(s, SIOCGSTAMP, &tv)
I faced the problem, that some timestamps were similar (which I could not believe). I found out that the timestamp did not provide the time when every single message had arrived, but it only said when the last message in the Rx-queue was received. This is a problem, when there are several messages queued and every timestamp read operation gives back the time of the last message in that queue.
That is why I changed strategy and tested the hardware timestamps using:
nbytes_can = recvmsg(*SOCKET_CAN, &msg, 0);
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg && (cmsg->cmsg_level == SOL_SOCKET); cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_type == SO_TIMESTAMP)
    tv_recCANMSG = *(struct timeval *) CMSG_DATA(cmsg);
}
This solved the problem of similar timestamps for the moment. But then I wanted to play with the Broadcast Manager (BCM) to be able to use the advantages of simple CAN-id-filtering and downsampling of receive messages. But using the BCM, I got the former version of timestamping back. Now I wonder if it is possible to use the BCM together with the hardware timestamps. I did not find anything about that combination. Although, I read about the idea to get the hardware timestamps together with the CAN data with only one syscall. Was this idea realized already or is it still an open point? How can I use hardware timestamps together with the BCM?

Another question that I want do know about is the order of the timestamps. I defined two sockets for the BCM. One for can0 and the other for can1. When I read the sockets alternating I have to consider the differences within the timestamps. That means for instance, that I must stop reading can1 until the timestamp of can0 reaches the one that can1 already had before. Otherwise I woud write timestamps that are not increasing monotonically. This waiting mechanism works fine - but reading the socket for can1 several times in a trot I get timestamps which are not growing monotonically (see the three marked lines):

   0.530082 2  409             Rx   d 8 E7 E7 E7 E7 E7 E7 E7 E7
   0.530320 2  40A             Rx   d 8 E7 E7 E7 E7 E7 E7 E7 E7
   0.531033 2  40D             Rx   d 8 E7 E7 E7 E7 E7 E7 E7 E7
   0.581885 1  114             Rx   d 8 F4 F4 F4 F4 F4 F4 F4 F4
>>>0.629789 2  408             Rx   d 8 E9 E9 E9 E9 E9 E9 E9 E9
>>>0.710016 2  409             Rx   d 8 E9 E9 E9 E9 E9 E9 E9 E9
>>>0.630239 2  40A             Rx   d 8 E9 E9 E9 E9 E9 E9 E9 E9
   0.630915 2  40D             Rx   d 8 E9 E9 E9 E9 E9 E9 E9 E9
   0.729832 2  408             Rx   d 8 EB EB EB EB EB EB EB EB

How can that be explained? Why are the timestamps for one socket not in chronological order? Can one force chronological order for the timestamps somehow? Would the timestamps be sorted if I would switch back to one socket for both interfaces?

I hope that someone found the time and energy to read up to this line - and I also hope, that there is even energy left to send me an answer.

Thank you in advance,
Best regards,

Uwe