SocketCAN
SocketCAN är en uppsättning CAN- drivrutiner med öppen källkod och en nätverksstack som Volkswagen Research bidragit med till Linux-kärnan . SocketCAN var tidigare känt som Low Level CAN Framework (LLCF).
Traditionella CAN-drivrutiner för Linux är baserade på modellen med karaktärsenheter. Vanligtvis tillåter de bara att skicka till och ta emot från CAN-styrenheten. Konventionella implementeringar av denna klass av enhetsdrivrutiner tillåter bara en enda process att komma åt enheten, vilket innebär att alla andra processer blockeras under tiden. Dessutom skiljer dessa drivrutiner vanligtvis alla något i gränssnittet som presenteras för applikationen, vilket kväver portabiliteten. SocketCAN-konceptet använder å andra sidan modellen av nätverksenheter, vilket gör att flera applikationer kan komma åt en CAN-enhet samtidigt. Dessutom kan en enda applikation komma åt flera CAN-nätverk parallellt.
SocketCAN-konceptet utökar Berkeley sockets API i Linux genom att introducera en ny protokollfamilj, PF_CAN, som samexisterar med andra protokollfamiljer, såsom PF_INET för Internet Protocol . Kommunikationen med CAN-bussen sker därför analogt med användningen av Internetprotokollet via uttag. Grundläggande komponenter i SocketCAN är nätverksenhetsdrivrutinerna för olika CAN-styrenheter och implementeringen av CAN-protokollfamiljen. Protokollfamiljen, PF_CAN, tillhandahåller strukturerna för att möjliggöra olika protokoll på bussen: Raw-sockets för direkt CAN-kommunikation och transportprotokoll för punkt-till-punkt-anslutningar. Dessutom tillhandahåller sändningshanteraren som är en del av CAN-protokollfamiljen funktioner t.ex. för att sända CAN-meddelanden periodiskt eller realisera komplexa meddelandefilter. Sedan Linux-kärnan version 5.10 inkluderar protokollfamiljen även en ISO-TP -implementering, CAN_ISOTP.
Patchar för CAN lades till i 2.6.25 Linux-kärnan . Under tiden lades en del styrenhetsdrivrutiner till och arbetet pågår med att lägga till drivrutiner för en mängd olika kontroller.
Användande
Applikationen ställer först in sin åtkomst till CAN-gränssnittet genom att initiera en socket (ungefär som i TCP/IP-kommunikation), och sedan binda den socket till ett gränssnitt (eller alla gränssnitt, om applikationen så önskar). När den är bunden kan uttaget sedan användas som ett UDP- uttag via läs
, skriv
, etc...
Python lade till stöd för SocketCAN i version 3.3. Ett bibliotek med öppen källkod python-can ger SocketCAN-stöd för Python 2 och Python 3 [ cirkulär referens ] .
Installation av en CAN-enhet kräver att can_dev-modulen laddas och IP-länken konfigureras för att specificera CAN-bussens bithastighet, till exempel:
$ modprobe can_dev $ modprobe can $ modprobe can_raw $ sudo ip link set can0 type can bitrate 500000 $ sudo ip link set up can0
Det finns också en virtuell CAN-drivrutin för teständamål som kan laddas och skapas i Linux med kommandona nedan.
$ modprobe can $ modprobe can_raw $ modprobe vcan $ sudo ip-länk lägg till dev vcan0 typ vcan $ sudo ip-länk ställ in vcan0 $ ip-länk visa vcan0 3: vcan0: <NOARP,UP,LOWER_UP> mtu 16 qdisc noqueue state OKÄND länk/kan
Följande kodsnutt är ett fungerande exempel på SocketCAN API, som skickar ett paket med det råa gränssnittet. Den är baserad på anteckningarna som dokumenteras i Linux-kärnan .
0
0
#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 ) { fel ( "Fel vid öppning av socket" ) ; returnera -1 ; } strcpy ( ifr . ifr_name , ifname ); ioctl ( s , SIOCGIFINDEX , & ifr ); addr . can_family = AF_CAN ; addr . can_ifindex = ifr . ifr_ifindex ; printf ( "%s vid index %d \n " , ifname , ifr . ifr_ifindex ); if ( bind ( s , ( struct sockaddr * ) & addr , sizeof ( addr )) == -1 ) { perror ( "Fel i socket bind" ); returnera -2 ; } ram . kan_id = 0x123 ; ram . can_dlc = 2 ; ram . data [ ] = 0x11 ; ram . data [ 1 ] = 0x22 ; nbytes = skriv ( s , & frame , sizeof ( struct can_frame )); printf ( "Skrev %d bytes \n " , nbytes ); återvända ; }
Paketet kan analyseras på vcan0-gränssnittet med hjälp av candump-verktyget som är en del av SocketCAN can-utils-paketet.
användare@server:~/can-utils $ ./candump vcan0 vcan0 123 [2] 11 22
- ^ "hartkopp/can-isotp" . 14 maj 2021 – via GitHub.
- ^ "Ärende 10141: SocketCan-stöd - Python-spårare" . bugs.python.org .
- ^ SocketCAN
-
^ Kan visas online från Linux Kernel Documentation eller i
linux/Documentation/networking/can.txt
i de senaste källträden - ^ can-utils https://github.com/linux-can/can-utils/
externa länkar
- SocketCAN / Linux CAN-projektwebbplats
- Användarutrymmesverktyg för SocketCAN
- Användarutrymmesbibliotek för SocketCAN
- Linux CAN-dokumentation
- Linux CAN sändlista
- Linux CAN e-postarkiv (gmane) Linux CAN e-postarkiv (marc)