SocketCAN - это набор драйверов CAN с открытым исходным кодом и сетевой стек, предоставленный Volkswagen Research для ядра Linux . Ранее известный как CAN Framework низкого уровня (LLCF).
Традиционные драйверы CAN для Linux основаны на модели символьных устройств. Обычно они разрешают только отправку и получение от CAN-контроллера. Обычные реализации этого класса драйверов устройства разрешают доступ к устройству только одному процессу, что означает, что все остальные процессы в это время блокируются. Кроме того, все эти драйверы обычно немного отличаются интерфейсом, представленным для приложения, что затрудняет переносимость. С другой стороны, концепция SocketCAN использует модель сетевых устройств, которая позволяет нескольким приложениям одновременно обращаться к одному устройству CAN. Кроме того, одно приложение может иметь параллельный доступ к нескольким сетям CAN.
Концепция SocketCAN расширяет API сокетов Беркли в Linux, представляя новое семейство протоколов PF_CAN, которое сосуществует с другими семействами протоколов, такими как PF_INET для Интернет-протокола.. Таким образом, связь с шиной CAN осуществляется аналогично использованию Интернет-протокола через сокеты. Основными компонентами SocketCAN являются драйверы сетевых устройств для различных контроллеров CAN и реализация семейства протоколов CAN. Семейство протоколов PF_CAN предоставляет структуры для включения различных протоколов на шине: необработанные сокеты для прямой связи CAN и транспортные протоколы для соединений точка-точка. Кроме того, диспетчер вещания, который является частью семейства протоколов CAN, предоставляет функции, например, для периодической отправки сообщений CAN или реализации сложных фильтров сообщений. Начиная с версии ядра Linux 5.10, семейство протоколов также включает реализацию ISO-TP CAN_ISOTP. [1]
Патчи для CAN были добавлены в ядро Linux 2.6.25 . Тем временем были добавлены некоторые драйверы контроллеров, и продолжается работа по добавлению драйверов для различных контроллеров.
Использование [ править ]
Приложение сначала устанавливает свой доступ к интерфейсу CAN, инициализируя сокет (во многом как в связи TCP / IP), а затем привязывая этот сокет к интерфейсу (или ко всем интерфейсам, если приложение того пожелает). После привязки сокет можно использовать как сокет UDP через read
, write
и т. Д.
Python добавил поддержку SocketCAN в версии 3.3. [2] Библиотека с открытым исходным кодом python-can обеспечивает поддержку SocketCAN для Python 2 и Python 3 [3] [ круговая ссылка ] .
Для установки CAN-устройства требуется загрузить модуль can_dev и настроить IP-канал для указания битрейта CAN-шины, например:
$ modprobe can_dev $ modprobe can $ modprobe can_raw $ sudo ip link set can0 type can bitrate 500000 $ sudo ip link set up can0
Существует также виртуальный драйвер CAN для тестирования, который можно загрузить и создать в Linux с помощью приведенных ниже команд.
$ 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
Следующий фрагмент кода представляет собой рабочий пример SocketCAN API, который отправляет пакет с использованием необработанного интерфейса. Он основан на примечаниях, задокументированных в ядре Linux . [4]
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <net / if.h>#include <sys / types.h># включить <sys / socket.h>#include <sys / ioctl.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 ; структура ifreq IFR ;const char * ifname = "vcan0" ;если (( s = розетка ( PF_CAN , SOCK_RAW , CAN_RAW )) == -1 ) { PError ( "Ошибка при открытии сокета" ); возврат -1 ; }зЬгср ( IFR . ifr_name , IFNAME ); ioctl ( s , SIOCGIFINDEX , & ifr );адр . can_family = AF_CAN ; адр . can_ifindex = IFR . ifr_ifindex ;Printf ( "% s с индексом% d \ п " , имя_интерфейса , IFR . ifr_ifindex );if ( bind ( s , ( struct sockaddr * ) & addr , sizeof ( addr )) == -1 ) { perror ( "Ошибка привязки сокета" ); возврат -2 ; }рамка . can_id = 0x123 ; рамка . can_dlc = 2 ; рамка . данные [ 0 ] = 0x11 ; рамка . данные [ 1 ] = 0x22 ;nbytes = write ( s , & frame , sizeof ( struct can_frame ));printf ( "Записано% d байт \ n " , nбайт );возврат 0 ; }
Пакет можно проанализировать на интерфейсе vcan0 с помощью утилиты candump, которая является частью пакета SocketCAN can-utils [5] .
пользователь @ сервер: ~ / can-utils $ ./candump vcan0 vcan0 123 [2] 11 22
Ссылки [ править ]
- ^ https://github.com/hartkopp/can-isotp
- ^ http://bugs.python.org/issue10141
- ^ SocketCAN
- ^ Доступно для просмотра в Интернете из документации ядра Linux или
linux/Documentation/networking/can.txt
в самых последних деревьях исходных текстов. - ^ can-utils https://github.com/linux-can/can-utils/