SocketCAN es un conjunto de controladores CAN de código abierto y una pila de red aportados por Volkswagen Research al kernel de Linux . SocketCAN era conocido anteriormente como Low Level CAN Framework (LLCF).

Los controladores CAN tradicionales para Linux se basan en el modelo de dispositivos de caracteres. Normalmente, solo permiten enviar y recibir datos del controlador CAN. Las implementaciones convencionales de este tipo de controlador solo permiten que un único proceso acceda al dispositivo, lo que significa que todos los demás procesos se bloquean mientras tanto. Además, estos controladores suelen presentar interfaces ligeramente diferentes para la aplicación, lo que limita la portabilidad. El concepto SocketCAN, por otro lado, utiliza el modelo de dispositivos de red, lo que permite que múltiples aplicaciones accedan a un mismo dispositivo CAN simultáneamente. Asimismo, una sola aplicación puede acceder a múltiples redes CAN en paralelo.
El concepto SocketCAN extiende la API de sockets de Berkeley en Linux mediante la introducción de una nueva familia de protocolos, PF_CAN, que coexiste con otras familias de protocolos, como PF_INET para el Protocolo de Internet . La comunicación con el bus CAN se realiza, por lo tanto, de forma análoga al uso del Protocolo de Internet a través de sockets. Los componentes fundamentales de SocketCAN son los controladores de dispositivos de red para diferentes controladores CAN y la implementación de la familia de protocolos CAN. La familia de protocolos PF_CAN proporciona las estructuras para habilitar diferentes protocolos en el bus: sockets sin procesar para la comunicación CAN directa y protocolos de transporte para conexiones punto a punto. Además, el gestor de difusión, que forma parte de la familia de protocolos CAN, proporciona funciones, por ejemplo, para enviar mensajes CAN periódicamente o realizar filtros de mensajes complejos. Desde la versión 5.10 del kernel de Linux, la familia de protocolos también incluye una implementación ISO-TP , CAN_ISOTP. [ 1 ]
Se añadieron parches para CAN en el kernel de Linux 2.6.25 . Mientras tanto, se añadieron algunos controladores y se está trabajando para añadir controladores para una variedad de controladores.
Uso
La aplicación primero establece su acceso a la interfaz CAN inicializando un socket (de forma similar a las comunicaciones TCP/IP), y luego vincula ese socket a una interfaz (o a todas las interfaces, si la aplicación así lo desea). Una vez vinculado, el socket se puede usar como un socket UDPread a través de , write, etc.
Python agregó soporte para SocketCAN en la versión 3.3. [ 2 ] Una biblioteca de código abierto python-can proporciona soporte para SocketCAN para Python 2 y Python 3 [ 3 ] .
La instalación de un dispositivo CAN requiere cargar el módulo can_dev y configurar el enlace IP para especificar la velocidad de bits del bus CAN, por ejemplo:
$ modprobe can_dev $ modprobe can $ modprobe can_raw $ sudo ip link set can0 type can bitrate 500000 $ sudo ip link set up can0 También existe un controlador CAN virtual para fines de prueba que se puede cargar y crear en Linux con los siguientes comandos.
$ 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/canEl siguiente fragmento de código es un ejemplo funcional de la API SocketCAN, que envía un paquete utilizando la interfaz sin procesar. Se basa en las notas documentadas en el kernel de Linux . [ 4 ]
#include <stdio.h> #include <stdlib.h> #include <string.h>#include <net/if.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h>#include <linux/can.h> #include <linux/can/raw.h>int main ( void ) { int s ; int nbytes ; struct sockaddr_can addr ; struct can_frame frame ; struct ifreq ifr ;const char * ifname = "vcan0" ;if (( s = socket ( PF_CAN , SOCK_RAW , CAN_RAW )) == -1 ) { perror ( "Error al abrir el 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 en el índice %d \n " , ifname , ifr . ifr_ifindex );if ( bind ( s , ( struct sockaddr * ) & addr , sizeof ( addr )) == -1 ) { perror ( "Error en la vinculación del socket" ); return -2 ; }frame.can_id = 0x123 ; frame.can_dlc = 2 ; frame.data [ 0 ] = 0x11 ; frame.data [ 1 ] = 0x22 ;nbytes = write ( s , & frame , sizeof ( struct can_frame ));printf ( "Se escribieron %d bytes \n " , nbytes ); return 0 ; }El paquete se puede analizar en la interfaz vcan0 utilizando la utilidad candump que forma parte del paquete SocketCAN can-utils [ 5 ] .
usuario@servidor:~/can-utils $ ./candump vcan0 vcan0 123 [2] 11 22Referencias
- ↑ «hartkopp/can-isotp» . 14 de mayo de 2021 – vía GitHub.
- ↑ "Problema 10141: Compatibilidad con SocketCan - Rastreador de Python" . bugs.python.org .
- ↑ SocketCAN
- ↑ Disponible en línea en la documentación del kernel de Linux o en
linux/Documentation/networking/can.txtlos árboles de código fuente más recientes. - ↑ can-utils https://github.com/linux-can/can-utils/
Enlaces externos
- Sitio del proyecto SocketCAN / Linux CAN
- Herramientas de espacio de usuario para SocketCAN
- Biblioteca de espacio de usuario para SocketCAN
- Documentación de Linux CAN
- Lista de correo de Linux CAN
- Archivo de correo CAN de Linux (gmane) Archivo de correo CAN de Linux (marc)
- controladores Linux
- Autobús CAN