SocketCANは、フォルクスワーゲン・リサーチがLinuxカーネルに提供したオープンソースの CANドライバとネットワークスタックのセットです。SocketCANは以前はLow Level CAN Framework(LLCF)として知られていました。

Linux向けの従来のCANドライバは、キャラクタデバイスモデルに基づいています。通常、CANコントローラとの送受信のみが可能です。このクラスのデバイスドライバの従来の実装では、デバイスへのアクセスは1つのプロセスのみに制限されており、その間、他のすべてのプロセスはブロックされます。さらに、これらのドライバはアプリケーションに提示されるインターフェースがそれぞれわずかに異なるため、移植性が損なわれます。一方、SocketCANのコンセプトはネットワークデバイスモデルを採用しており、複数のアプリケーションが1つのCANデバイスに同時にアクセスできます。また、1つのアプリケーションから複数のCANネットワークに並行してアクセスすることも可能です。
SocketCANのコンセプトは、インターネットプロトコル用のPF_INETなど、他のプロトコルファミリと共存する新しいプロトコルファミリPF_CANを導入することで、LinuxのBerkeleyソケット APIを拡張します。したがって、CANバスとの通信は、ソケットを介したインターネットプロトコルの使用と同様に行われます。SocketCANの基本コンポーネントは、さまざまなCANコントローラ用のネットワークデバイスドライバと、CANプロトコルファミリの実装です。プロトコルファミリPF_CANは、バス上でさまざまなプロトコルを有効にする構造を提供します。直接CAN通信用のRawソケットと、ポイントツーポイント接続用のトランスポートプロトコルです。さらに、CANプロトコルファミリの一部であるブロードキャストマネージャは、CANメッセージを定期的に送信したり、複雑なメッセージフィルタを実現したりする機能を提供します。Linuxカーネルバージョン5.10以降、プロトコルファミリにはISO-TP実装であるCAN_ISOTPも含まれています。[1]
CAN用のパッチはLinuxカーネル2.6.25に追加されました。同時に、いくつかのコントローラードライバーが追加され、様々なコントローラー用のドライバーを追加する作業が進行中です。[要出典]
使用法
アプリケーションはまず、TCP/IP通信と同様にソケットを初期化し、CANインターフェースへのアクセスを設定します。次に、そのソケットをインターフェース(またはアプリケーションの必要に応じてすべてのインターフェース)にバインドします。バインドが完了すると、ソケットは、、などを介してUDPソケットのように使用できるようになり
ます。readwrite
Pythonはバージョン3.3でSocketCANのサポートを追加しました。[2]オープンソースライブラリpython-canはPython 2とPython 3にSocketCANのサポートを提供します[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の動作例であり、rawインターフェースを用いてパケットを送信します。これは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 ( "ソケットを開くときにエラーが発生しました" ); return -1 ; }
strcpy ( ifr . ifr_name , ifname ); ioctl ( s , SIOCGIFINDEX , & ifr ); addr . can_family = AF_CAN ; addr . can_ifindex = ifr . ifr_ifindex ;
printf ( "%s、インデックス %d \n " 、ifname 、ifr . ifr_ifindex );
if ( bind ( s , ( structsockaddr * ) & addr , sizeof ( addr )) == -1 ) { perror ( "ソケットバインドエラー" ) ; return -2 ; }
フレーム.can_id = 0x123 ;フレーム.can_dlc = 2 ;フレーム.data [ 0 ] = 0x11 ;フレーム.data [ 1 ] = 0x22 ;
nbytes = write ( s 、& frame 、sizeof ( struct can_frame ));
printf ( "%d バイト書き込みました\n " , nbytes ); 0を返します; }
パケットは、SocketCAN can-utils [5]パッケージの一部であるcandumpユーティリティを使用してvcan0インターフェース上で分析できます。
ユーザー@サーバー:~/can-utils $ ./candump vcan0
vcan0 123 [2] 11 22
参考文献
- ^ “ハートコップ/can-isotp”. 2021 年 5 月 14 日 – GitHub 経由。
- ^ 「問題 10141: SocketCan サポート - Python トラッカー」。bugs.python.org。
- ^ ソケットCAN
- ^ Linuxカーネルドキュメントまたは
linux/Documentation/networking/can.txt最新のソースツリーからオンラインで閲覧可能 - ^ can-utils https://github.com/linux-can/can-utils/
外部リンク
- SocketCAN / Linux CAN プロジェクトサイト
- SocketCANのユーザー空間ツール
- SocketCAN用ユーザー空間ライブラリ
- Linux CANドキュメント
- Linux CAN メーリングリスト
- Linux CAN メール アーカイブ (gmane) Linux CAN メール アーカイブ (marc)