Jump to content

SocketCAN: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
→‎External links: link to english overview
Redhatter (talk | contribs)
Added some further notes about CAN, and an example based on the in-kernel documentation.
Line 1: Line 1:
'''SocketCAN''' is a set of [[open source]] [[Controller_Area_Network|CAN]] drivers and a networking stack contributed by [[Volkswagen|Volkswagen Research]] to the [[Linux kernel]]. Formerly known as ''Low Level CAN Framework'' (LLCF).
'''SocketCAN''' is a set of [[open source]] [[Controller_Area_Network|CAN]] drivers and a networking stack contributed by [[Volkswagen|Volkswagen Research]] to the [[Linux kernel]]. Formerly known as ''Low Level CAN Framework'' (LLCF).


Established CAN drivers are based on the model of character devices. Typically they only allow sending to and receiving from the CAN controller. Most of the implementations for this device class only allow a single process on the device which means that all other processes are blocked in the meantime as known from accessing a device via the serial interface. The SocketCAN concept on the other hand uses the model of network devices, which allows multiple applications to access to one CAN device simultanously. Equally single application are able to access multiple CAN networks in parallel.
Established CAN drivers are based on the model of character devices. Typically they only allow sending to and receiving from the CAN controller. Most of the implementations for this device class only allow a single process on the device which means that all other processes are blocked in the meantime as known from accessing a device via the serial interface. 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 to one CAN device simultaneously. Equally single application are able to access multiple CAN networks in parallel.


The SocketCAN concept introduces 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 done analogue 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 provide 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.
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 done analogue 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 provide 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.


Patches about CAN were added in the 2.6.25 [[Linux Kernel]] but there are still some missing parts like controller drivers.
Patches about CAN were added in the 2.6.25 [[Linux Kernel]] but there are still some missing parts like controller drivers.

== 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 [[User_Datagram_Protocol|UDP]] socket via <code>read</code>, <code>write</code>, etc...

The following is a simple (incomplete) example, that sends a packet, then reads back a packet using the raw interface. It is based on the notes documented in the [[Linux Kernel]]<ref>viewable online from [http://svn.berlios.de/wsvn/socketcan/trunk/kernel/2.6/Documentation/networking/can.txt SocketCAN WebSVN] or in <code>linux/Documentation/networking/can.txt</code> in most recent source trees</ref>.

<source lang="c">
#include <linux/can.h>
#include <linux/can/raw.h>
#include <string.h>

/* ... */

/* Somewhere in your app */

/* Create the socket */
int skt = socket( PF_CAN, SOCK_RAW, CAN_RAW );

/* Locate the interface you wish to use */
struct ifreq ifr;
strcpy(ifr.ifr_name, "can0");
ioctl(s, SIOCGIFINDEX, &ifr); /* ifr.ifr_ifindex gets filled
* with that device's index */
/* Select that CAN interface, and bind the socket to it. */
struct sockaddr_can addr;
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
bind( skt, (struct sockaddr*)&addr, sizeof(addr) );

/* Send a message to the CAN bus */
struct can_frame frame;
frame.can_id = 0x123;
strcpy( &frame.data, "foo" );
frame.can_dlc = strlen( &frame.data );
int bytes_sent = write( skt, &frame, sizeof(frame) );

/* Read a message back from the CAN bus */
int bytes_read = read( skt, &frame, sizeof(frame) );
</source>

== References ==

<references/>


== External links ==
== External links ==

Revision as of 01:35, 15 December 2008

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).

Established CAN drivers are based on the model of character devices. Typically they only allow sending to and receiving from the CAN controller. Most of the implementations for this device class only allow a single process on the device which means that all other processes are blocked in the meantime as known from accessing a device via the serial interface. 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 to one CAN device simultaneously. Equally single application are 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 done analogue 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 provide 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.

Patches about CAN were added in the 2.6.25 Linux Kernel but there are still some missing parts like controller drivers.

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...

The following is a simple (incomplete) example, that sends a packet, then reads back a packet using the raw interface. It is based on the notes documented in the Linux Kernel[1].

#include <linux/can.h>
#include <linux/can/raw.h>
#include <string.h>

/* ... */

/* Somewhere in your app */

   /* Create the socket */
   int skt = socket( PF_CAN, SOCK_RAW, CAN_RAW );

   /* Locate the interface you wish to use */
   struct ifreq ifr;
   strcpy(ifr.ifr_name, "can0");
   ioctl(s, SIOCGIFINDEX, &ifr); /* ifr.ifr_ifindex gets filled 
                                  * with that device's index */
   
   /* Select that CAN interface, and bind the socket to it. */
   struct sockaddr_can addr;
   addr.can_family = AF_CAN;
   addr.can_ifindex = ifr.ifr_ifindex;
   bind( skt, (struct sockaddr*)&addr, sizeof(addr) );

   /* Send a message to the CAN bus */
   struct can_frame frame;
   frame.can_id = 0x123;
   strcpy( &frame.data, "foo" );
   frame.can_dlc = strlen( &frame.data );
   int bytes_sent = write( skt, &frame, sizeof(frame) );

   /* Read a message back from the CAN bus */
   int bytes_read = read( skt, &frame, sizeof(frame) );

References

  1. ^ viewable online from SocketCAN WebSVN or in linux/Documentation/networking/can.txt in most recent source trees