РозеткаCAN
SocketCAN — это набор с открытым исходным кодом драйверов CAN и сетевой стек, предоставленный Volkswagen Research для ядра Linux . SocketCAN ранее назывался 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]
2.6.25 Патчи для CAN были добавлены в ядро Linux . Тем временем были добавлены некоторые драйверы контроллеров, и продолжается работа по добавлению драйверов для различных контроллеров.
Использование
[ редактировать ]Приложение сначала настраивает доступ к интерфейсу 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
Следующий фрагмент кода представляет собой рабочий пример API SocketCAN, который отправляет пакет с использованием необработанного интерфейса. Он основан на примечаниях, задокументированных в ядре Linux . [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>
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 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, (struct sockaddr *)&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(struct can_frame));
printf("Wrote %d bytes\n", nbytes);
return 0;
}
Пакет можно проанализировать на интерфейсе vcan0 с помощью утилиты candump, которая является частью can-utils SocketCAN. [5] упаковка.
user@server:~/can-utils $ ./candump vcan0
vcan0 123 [2] 11 22
Ссылки
[ редактировать ]- ^ "харткопп/кан-изотп" . 14 мая 2021 г. – через GitHub.
- ^ «Проблема 10141: поддержка SocketCan — трекер Python» . bugs.python.org .
- ^ РозеткаCAN
- ^ Можно просмотреть онлайн в документации по ядру Linux или в
linux/Documentation/networking/can.txt
в самых последних исходных деревьях - ^ can-utils https://github.com/linux-can/can-utils/