SocketCAN

Last updated

SocketCAN is a set of open source CAN drivers and a networking stack contributed by Volkswagen Research to the Linux kernel. Formerly known as Low Level CAN Framework (LLCF).

Contents

Typical CAN communication layers. With SocketCAN (left) or conventional (right). Socketcan.png
Typical CAN communication layers. With SocketCAN (left) or conventional (right).

Traditional CAN drivers for Linux are based on the model of character devices. Typically they only allow sending to and receiving from the CAN controller. Conventional implementations of this class of device driver only allow a single process to access the device, which means that all other processes are blocked in the meantime. In addition, these drivers typically all differ slightly in the interface presented to the application, stifling portability. The SocketCAN concept on the other hand uses the model of network devices, which allows multiple applications to access one CAN device simultaneously. Also, a single application is able to access multiple CAN networks in parallel.

The SocketCAN concept extends the Berkeley sockets API in Linux by introducing a new protocol family, PF_CAN, that coexists with other protocol families like PF_INET for the Internet Protocol. The communication with the CAN bus is therefore done analogously to the use of the Internet Protocol via sockets. Fundamental components of SocketCAN are the network device drivers for different CAN controllers and the implementation of the CAN protocol family. The protocol family, PF_CAN, provides the structures to enable different protocols on the bus: Raw sockets for direct CAN communication and transport protocols for point-to-point connections. Moreover the broadcast manager which is part of the CAN protocol family provides functions e.g. for sending CAN messages periodically or realize complex message filters. Since Linux kernel Version 5.10 the protocol family also includes an ISO-TP implementation, CAN_ISOTP. [1]

Patches for CAN were added in the 2.6.25 Linux kernel. Meanwhile some controller drivers were added and work is going on to add drivers for a variety of controllers.

Usage

The application first sets up its access to the CAN interface by initialising a socket (much like in TCP/IP communications), then binding that socket to an interface (or all interfaces, if the application so desires). Once bound, the socket can then be used like a UDP socket via read, write, etc...

Python added support for SocketCAN in version 3.3. [2] An open source library python-can provides SocketCAN support for Python 2 and Python 3 [3] [ circular reference ].

Installing a CAN device requires loading the can_dev module and configuring the IP link to specify the CAN bus bitrate, for example:

$ modprobe can_dev $ modprobe can $ modprobe can_raw $ sudo ip link set can0 type can bitrate 500000$ sudo ip link set up can0 

There is also a virtual CAN driver for testing purposes which can be loaded and created in Linux with the commands below.

$ modprobe can $ modprobe can_raw $ modprobe vcan $ sudo ip link add dev vcan0 type vcan $ sudo ip link set up vcan0 $ ip link show vcan0 3: vcan0: <NOARP,UP,LOWER_UP> mtu 16 qdisc noqueue state UNKNOWN     link/can

The following code snippet is a working example of the SocketCAN API, that sends a packet using the raw interface. It is based on the notes documented in the Linux Kernel. [4]

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<net/if.h>#include<sys/types.h>#include<sys/socket.h>#include<sys/ioctl.h>#include<linux/can.h>#include<linux/can/raw.h>intmain(void){ints;intnbytes;structsockaddr_canaddr;structcan_frameframe;structifreqifr;constchar*ifname="vcan0";if((s=socket(PF_CAN,SOCK_RAW,CAN_RAW))==-1){perror("Error while opening socket");return-1;}strcpy(ifr.ifr_name,ifname);ioctl(s,SIOCGIFINDEX,&ifr);addr.can_family=AF_CAN;addr.can_ifindex=ifr.ifr_ifindex;printf("%s at index %d\n",ifname,ifr.ifr_ifindex);if(bind(s,(structsockaddr*)&addr,sizeof(addr))==-1){perror("Error in socket bind");return-2;}frame.can_id=0x123;frame.can_dlc=2;frame.data[0]=0x11;frame.data[1]=0x22;nbytes=write(s,&frame,sizeof(structcan_frame));printf("Wrote %d bytes\n",nbytes);return0;}

The packet can be analyzed on the vcan0 interface using the candump utility which is part of the SocketCAN can-utils [5] package.

user@server:~/can-utils $ ./candump vcan0   vcan0  123  [2] 11 22

Related Research Articles

In computing, a device driver is a computer program that operates or controls a particular type of device that is attached to a computer or automaton. A driver provides a software interface to hardware devices, enabling operating systems and other computer programs to access hardware functions without needing to know precise details about the hardware being used.

Berkeley sockets is an application programming interface (API) for Internet sockets and Unix domain sockets, used for inter-process communication (IPC). It is commonly implemented as a library of linkable modules. It originated with the 4.2BSD Unix operating system, which was released in 1983.

In computing, specifically in Unix and Unix-like operating systems, a raw device is a special kind of logical device associated with a character device file that allows a storage device such as a hard disk drive to be accessed directly, bypassing the operating system's caches and buffers. Applications like a database management system can use raw devices directly, enabling them to manage how data is cached, rather than deferring this task to the operating system.

Video4Linux is a collection of device drivers and an API for supporting realtime video capture on Linux systems. It supports many USB webcams, TV tuners, and related devices, standardizing their output, so programmers can easily add video support to their applications.

Netfilter is a framework provided by the Linux kernel that allows various networking-related operations to be implemented in the form of customized handlers. Netfilter offers various functions and operations for packet filtering, network address translation, and port translation, which provide the functionality required for directing packets through a network and prohibiting packets from reaching sensitive locations within a network.

The Direct Rendering Manager (DRM) is a subsystem of the Linux kernel responsible for interfacing with GPUs of modern video cards. DRM exposes an API that user-space programs can use to send commands and data to the GPU and perform operations such as configuring the mode setting of the display. DRM was first developed as the kernel-space component of the X Server Direct Rendering Infrastructure, but since then it has been used by other graphic stack alternatives such as Wayland.

The proc filesystem (procfs) is a special filesystem in Unix-like operating systems that presents information about processes and other system information in a hierarchical file-like structure, providing a more convenient and standardized method for dynamically accessing process data held in the kernel than traditional tracing methods or direct access to kernel memory. Typically, it is mapped to a mount point named /proc at boot time. The proc file system acts as an interface to internal data structures about running processes in the kernel. In Linux, it can also be used to obtain information about the kernel and to change certain kernel parameters at runtime (sysctl).

Linux kernel interfaces An overview and comparison of the Linux kernal APIs and ABIs.

The Linux kernel provides several interfaces to user-space applications that are used for different purposes and that have different properties by design. There are two types of application programming interface (API) in the Linux kernel that are not to be confused: the "kernel–user space" API and the "kernel internal" API.

The functions getaddrinfo and getnameinfo convert domain names, hostnames, and IP addresses between human-readable text representations and structured binary formats for the operating system's networking API. Both functions are contained in the POSIX standard application programming interface (API).

In computer networking, STREAMS is the native framework in Unix System V for implementing character device drivers, network protocols, and inter-process communication. In this framework, a stream is a chain of coroutines that pass messages between a program and a device driver. STREAMS originated in Version 8 Research Unix, as Streams.

The Netlink socket family is a Linux kernel interface used for inter-process communication (IPC) between both the kernel and userspace processes, and between different userspace processes, in a way similar to the Unix domain sockets. Similarly to the Unix domain sockets, and unlike INET sockets, Netlink communication cannot traverse host boundaries. However, while the Unix domain sockets use the file system namespace, Netlink processes are usually addressed by process identifiers (PIDs).

evdev

evdev is a generic input event interface in the Linux kernel and FreeBSD. It generalizes raw input events from device drivers and makes them available through character devices in the /dev/input/ directory.

A Bluetooth stack is software that is an implementation of the Bluetooth protocol stack.

select is a system call and application programming interface (API) in Unix-like and POSIX-compliant operating systems for examining the status of file descriptors of open input/output channels. The select system call is similar to the poll facility introduced in UNIX System V and later operating systems. However, with the c10k problem, both select and poll have been superseded by the likes of kqueue, epoll, /dev/poll and I/O completion ports.

TI-RTOS is an embedded tools ecosystem created and offered by Texas Instruments (TI) for use in a wide range of their embedded system processors. It includes a real-time operating system (RTOS) component named TI-RTOS Kernel along with added components that support device drivers, networking connectivity stacks, power management, file systems, instrumentation, and inter-processor communications like DSP/BIOS Link. It is free and open-source software, released under one of the BSD licenses.

Network block device

On Linux, network block device (NBD) is a network protocol that can be used to forward a block device from one machine to a second machine. As an example, a local machine can access a hard disk drive that is attached to another computer.

NuttX is a real-time operating system (RTOS) with an emphasis on technical standards compliance and small size. Scalable from 8-bit to 64-bit microcontroller environments, the main governing standards in NuttX are from the Portable Operating System Interface (POSIX) and the American National Standards Institute (ANSI). Further standard application programming interfaces (APIs) from Unix and other common RTOSes are adopted for functions unavailable under these standards, or inappropriate for deeply embedded environments, such as the fork system call.

Launch Time is a new concept for handling Ethernet packets proposed for the Linux kernel. It is an attempt to add some isochronous capability to the kernel by hinting at what time a packet should be sent out. When sending a packet to socket, an additional bit (MSG_LAUNCHTIME) is specified in the "sendto" flags field. If this bit is set, then the buffer passed to the socket includes the desired send time or "launch time". The sendto syscall will shave off the launchtime from the packet and add it to the msghdr passed to the lower layers of the network stack.

can4linux is an Open Source CAN Linux-Kernel device driver. Development started in the mid-1990s for the Philips 82C200 CAN controller stand alone chip on an ISA Board AT-CAN-MINI. In 1995 the first version was created to use the CAN bus with Linux for laboratory automation as a project of the Linux Lab Project at FU Berlin.

The bio(4) pseudo-device driver and the bioctl(8) utility implement a generic RAID volume management interface in OpenBSD and NetBSD. The idea behind this software is similar to ifconfig, where a single utility from the operating system can be used to control any RAID controller using a generic interface, instead of having to rely on many proprietary and custom RAID management utilities specific for each given hardware RAID manufacturer. Features include monitoring of the health status of the arrays, controlling identification through blinking the LEDs and managing of sound alarms, and specifying hot spare disks. Additionally, the softraid configuration in OpenBSD is delegated to bioctl as well; whereas the initial creation of volumes and configuration of hardware RAID is left to card BIOS as non-essential after the operating system has already been booted. Interfacing between the kernel and userland is performed through the ioctl system call through the /dev/bio pseudo-device.

References

  1. "hartkopp/can-isotp". May 14, 2021 via GitHub.
  2. "Issue 10141: SocketCan support - Python tracker". bugs.python.org.
  3. SocketCAN
  4. Viewable online from Linux Kernel Documentation or in linux/Documentation/networking/can.txt in most recent source trees
  5. can-utils https://github.com/linux-can/can-utils/