============================================================================ can-sockets.txt : general socketCAN API documentation See can-raw.txt and can-bcm.txt for in-depth documentation on RAW and BCM sockets. Part of the documentation for the socketCAN subsystem This file contains: S. How to use Socket CAN S.1 Timestamps ============================================================================ S. How to use Socket CAN ------------------------ Like TCP/IP, you first need to open a socket for communicating over a CAN network. Since Socket CAN implements a new protocol family, you need to pass PF_CAN as the first argument to the socket(2) system call. Currently, there are two CAN protocols to choose from, the raw socket protocol and the broadcast manager (BCM). So to open a socket, you would write s = socket(PF_CAN, SOCK_RAW, CAN_RAW); and s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM); respectively. After the successful creation of the socket, you would normally use the bind(2) system call to bind the socket to a CAN interface (which is different from TCP/IP due to different addressing - see overview.txt, chapter 3). After binding (CAN_RAW) or connecting (CAN_BCM) the socket, you can read(2) and write(2) from/to the socket or use send(2), sendto(2), sendmsg(2) and the recv* counterpart operations on the socket as usual. There are also CAN specific socket options described below. The basic CAN frame structure and the sockaddr structure are defined in include/linux/can.h: struct can_frame { canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ __u8 can_dlc; /* data length code: 0 .. 8 */ __u8 data[8] __attribute__((aligned(8))); }; The alignment of the (linear) payload data[] to a 64bit boundary allows the user to define own structs and unions to easily access the CAN payload. There is no given byteorder on the CAN bus by default. A read(2) system call on a CAN_RAW socket transfers a struct can_frame to the user space. The sockaddr_can structure has an interface index like the PF_PACKET socket, that also binds to a specific interface: struct sockaddr_can { sa_family_t can_family; int can_ifindex; union { /* transport protocol class address info (e.g. ISOTP) */ struct { canid_t rx_id, tx_id; } tp; /* reserved for future CAN protocols address information */ } can_addr; }; To determine the interface index an appropriate ioctl() has to be used (example for CAN_RAW sockets without error checking): int s; struct sockaddr_can addr; struct ifreq ifr; s = socket(PF_CAN, SOCK_RAW, CAN_RAW); strcpy(ifr.ifr_name, "can0" ); ioctl(s, SIOCGIFINDEX, &ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; bind(s, (struct sockaddr *)&addr, sizeof(addr)); (..) To bind a socket to all(!) CAN interfaces the interface index must be 0 (zero). In this case the socket receives CAN frames from every enabled CAN interface. To determine the originating CAN interface the system call recvfrom(2) may be used instead of read(2). To send on a socket that is bound to 'any' interface sendto(2) is needed to specify the outgoing interface. Reading CAN frames from a bound CAN_RAW socket (see above) consists of reading a struct can_frame: struct can_frame frame; nbytes = read(s, &frame, sizeof(struct can_frame)); if (nbytes < 0) { perror("can raw socket read"); return 1; } /* paranoid check ... */ if (nbytes < sizeof(struct can_frame)) { fprintf(stderr, "read: incomplete CAN frame\n"); return 1; } /* do something with the received CAN frame */ Writing CAN frames can be done similarly, with the write(2) system call: nbytes = write(s, &frame, sizeof(struct can_frame)); When the CAN interface is bound to 'any' existing CAN interface (addr.can_ifindex = 0) it is recommended to use recvfrom(2) if the information about the originating CAN interface is needed: struct sockaddr_can addr; struct ifreq ifr; socklen_t len = sizeof(addr); struct can_frame frame; nbytes = recvfrom(s, &frame, sizeof(struct can_frame), 0, (struct sockaddr*)&addr, &len); /* get interface name of the received CAN frame */ ifr.ifr_ifindex = addr.can_ifindex; ioctl(s, SIOCGIFNAME, &ifr); printf("Received a CAN frame from interface %s", ifr.ifr_name); To write CAN frames on sockets bound to 'any' CAN interface the outgoing interface has to be defined certainly. strcpy(ifr.ifr_name, "can0"); ioctl(s, SIOCGIFINDEX, &ifr); addr.can_ifindex = ifr.ifr_ifindex; addr.can_family = AF_CAN; nbytes = sendto(s, &frame, sizeof(struct can_frame), 0, (struct sockaddr*)&addr, sizeof(addr)); S.1 Timestamps For applications in the CAN environment it is often of interest an accurate timestamp of the instant a message from CAN bus has been received. Such a timestamp can be read with ioctl(2) after reading a message from the socket. Example: struct timeval tv; ioctl(s, SIOCGSTAMP, &tv); The timestamp on Linux has a resolution of one microsecond and it is set automatically at the reception of a CAN frame. Alternatively the timestamp can be obtained as a control message (cmsg) using the recvmsg() system call. After enabling the timestamps in the cmsg's by const int timestamp = 1; setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, ×tamp, sizeof(timestamp)); the data structures filled by recvmsg() need to be parsed for cmsg->cmsg_type == SO_TIMESTAMP to get the timestamp. See cmsg() manpage.