GniazdoCAN
SocketCAN to zestaw sterowników CAN typu open source i stos sieciowy wniesiony przez Volkswagen Research do jądra Linuksa . SocketCAN był wcześniej znany jako Low Level CAN Framework (LLCF).
Tradycyjne sterowniki CAN dla systemu Linux oparte są na modelu urządzeń znakowych. Zazwyczaj pozwalają tylko na wysyłanie i odbieranie ze sterownika CAN. Konwencjonalne implementacje sterowników urządzeń tej klasy umożliwiają tylko jednemu procesowi dostęp do urządzenia, co oznacza, że wszystkie inne procesy są w międzyczasie blokowane. Ponadto wszystkie te sterowniki zwykle różnią się nieznacznie interfejsem aplikacji, co ogranicza przenośność. Z drugiej strony koncepcja SocketCAN wykorzystuje model urządzeń sieciowych, który umożliwia wielu aplikacjom równoczesny dostęp do jednego urządzenia CAN. Ponadto pojedyncza aplikacja może równolegle uzyskiwać dostęp do wielu sieci CAN.
Koncepcja SocketCAN rozszerza interfejs API gniazd Berkeley w systemie Linux, wprowadzając nową rodzinę protokołów, PF_CAN, która współistnieje z innymi rodzinami protokołów, takimi jak PF_INET dla protokołu internetowego . Komunikacja z magistralą CAN odbywa się więc analogicznie jak przy wykorzystaniu protokołu internetowego poprzez gniazda. Podstawowymi komponentami SocketCAN są sterowniki urządzeń sieciowych dla różnych kontrolerów CAN oraz implementacja rodziny protokołów CAN. Rodzina protokołów PF_CAN zapewnia struktury umożliwiające różne protokoły na magistrali: Raw Sockets do bezpośredniej komunikacji CAN i protokoły transportowe do połączeń punkt-punkt. Ponadto menedżer transmisji, który jest częścią rodziny protokołów CAN, udostępnia funkcje np. okresowego wysyłania komunikatów CAN lub realizowania złożonych filtrów komunikatów. Od Jądro Linuksa w wersji 5.10 rodzina protokołów obejmuje również implementację ISO-TP , CAN_ISOTP.
jądrze Linuksa 2.6.25 dodano łatki dla CAN . W międzyczasie dodano kilka sterowników kontrolerów i trwają prace nad dodaniem sterowników dla różnych kontrolerów.
Stosowanie
Aplikacja najpierw konfiguruje swój dostęp do interfejsu CAN poprzez inicjalizację gniazda (podobnie jak w komunikacji TCP/IP), a następnie powiązanie tego gniazda z interfejsem (lub wszystkimi interfejsami, jeśli aplikacja sobie tego życzy). Po związaniu gniazdo może być następnie używane jak UDP poprzez odczyt
, zapis
itp.
Python dodał obsługę SocketCAN w wersji 3.3. Biblioteka open source python-can zapewnia obsługę SocketCAN dla Pythona 2 i Pythona 3 [ odwołanie cykliczne ] .
Instalacja urządzenia CAN wymaga załadowania modułu can_dev i skonfigurowania łącza IP w celu określenia szybkości transmisji magistrali CAN, na przykład:
$ modprobe can_dev $ modprobe can $ modprobe can_raw $ zestaw sudo ip can0 typ can bitrate 500000 $ sudo konfiguracja łącza ip can0
Istnieje również wirtualny sterownik CAN do celów testowych, który można załadować i utworzyć w systemie Linux za pomocą poniższych poleceń.
$ modprobe can $ modprobe can_raw $ modprobe vcan $ sudo ip link add dev vcan0 typ vcan $ sudo ip link set up vcan0 $ ip link show vcan0 3: vcan0: <NOARP,UP,LOWER_UP> mtu 16 qdisc noqueue stan UNKNOWN link/can
Poniższy fragment kodu to działający przykład interfejsu API SocketCAN, który wysyła pakiet przy użyciu surowego interfejsu. Opiera się na uwagach udokumentowanych w Linux Kernel .
#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 nbajtów ; struktura
sockaddr_can adres ; struct can_frame ramka ; struct ifreq ifr ; const char * ifname = "vcan0" ; if (( s = socket ( PF_CAN , SOCK_RAW , CAN_RAW )) == -1 ) { perror ( "Błąd podczas otwierania gniazda" ); powrót -1 ; }
strcpy ( jeśli . nazwa_jeśli , jeśli nazwa ); ioctl ( s , SIOCGIFINDEX , & ifr ); adres . can_family = AF_CAN ; adres . can_ifindex = ifr . ifr_ifindex ; printf ( " %s w indeksie %d \n " , ifname , ifr.ifr_ifindex ) ;
if ( bind ( s , ( struct sockaddr * ) & addr , sizeof ( addr )) == -1 ) { perror ( "Błąd w powiązaniu gniazda" ); powrót -2 ; } ramka . can_id = 0x123 ; rama . can_dlc = 2 ; rama . dane 0
0
[ ] = 0x11 ; rama . dane [ 1 ] = 0x22 ; nbajtów = write ( s , & ramka , sizeof ( struct can_frame )); printf ( "Zapisano %d bajtów \n " , nbajtów ); powrót ; }
Pakiet można przeanalizować na interfejsie vcan0 za pomocą narzędzia candump, które jest częścią pakietu can-utils SocketCAN.
użytkownik@serwer:~/can-utils $ ./candump vcan0 vcan0 123 [2] 11 22
- Bibliografia _ _ 14 maja 2021 r. – przez GitHub.
- ^ „Problem 10141: Obsługa SocketCan - śledzenie Pythona” . bugs.python.org .
- Bibliografia _
-
^ Można przeglądać online z Linux Kernel Documentation lub w
linux/Documentation/networking/can.txt
w najnowszych drzewach źródeł - ^ can-utils https://github.com/linux-can/can-utils/
Linki zewnętrzne
- Witryna projektu SocketCAN / Linux CAN
- Narzędzia przestrzeni użytkownika dla SocketCAN
- Biblioteka przestrzeni użytkownika dla SocketCAN
- Dokumentacja CAN Linuksa
- Lista mailingowa Linux CAN
- Archiwum poczty CAN systemu Linux (gmane) Archiwum poczty CAN systemu Linux (marc)