ラズパイに USB 接続した同一デバイスを判別できるようにする【その1ーシリアル】


今回は、ラズベリーパイに USB で接続したデバイスを判別しやすくします。
通常だと接続しても ttyUSB* のような表示しか出ませんが、任意の名称で表示できるようにします。
ttyUSB0 → SerialCable1 のように dev ディレクトリでの表示名を変更できます。
作業としては udev 用の新たなルールファイルを作成します。udev の詳細は こちら

作業環境
・Raspberry Pi 3B
・Raspberry Pi OS Lite Legacy (buster)
・FT232RL × 2台(同一デバイス)
ラズベリーパイの基本的なセットアップは完了しているものと想定します。

[手順1]USBを接続した際の変化を確認する

まず未接続の状態で dev ディレクトリを見てみます。

ls /dev

FT232RL 未接続時は以下の状態です。

次に1台目の FT232RL を接続します。ttyUSB0 が見えました。

続けて2台目の FT232RL を接続します。ttyUSB1 が追加されました。

このように、デバイスを接続すると dev ディレクトリにデバイスファイルが追加されます。

[手順2]接続デバイスの固有情報を確認する

冒頭にも記述していますが任意の名称を設定するために udev 用のルールファイルが必要です。
ルールファイル内にデバイスを特定する固有の キー 情報を記述する必要があるので、まずはデバイスの情報を確認します。

udevadm info -q all -n /dev/ttyUSB0

上記コマンドで以下のようなデバイス情報が表示されます。(例:Sandisk USB フラッシュメモリ)

pi@raspberrypi:~$ udevadm info -q all -n /dev/sda
P: /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/host0/target0:0:0/0:0:0:0/block/sda
N: sda
L: 0
S: disk/by-path/platform-3f980000.usb-usb-0:1.2:1.0-scsi-0:0:0:0
S: disk/by-id/usb-SanDisk_Ultra_Fit_4C530000021118120214-0:0
S: disk/by-uuid/e1d2d53c-ba70-402f-820c-27162be4a94c
E: DEVPATH=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/host0/target0:0:0/0:0:0:0/block/sda
E: DEVNAME=/dev/sda
E: DEVTYPE=disk
E: MAJOR=8
E: MINOR=0
E: SUBSYSTEM=block
E: USEC_INITIALIZED=610442091
E: ID_VENDOR=SanDisk
E: ID_VENDOR_ENC=SanDisk\x20
E: ID_VENDOR_ID=0781
E: ID_MODEL=Ultra_Fit
E: ID_MODEL_ENC=Ultra\x20Fit\x20\x20\x20\x20\x20\x20\x20
E: ID_MODEL_ID=5583
E: ID_REVISION=1.00
E: ID_SERIAL=SanDisk_Ultra_Fit_4C530000021118120214-0:0
E: ID_SERIAL_SHORT=4C530000021118120214
E: ID_TYPE=disk
E: ID_INSTANCE=0:0
E: ID_BUS=usb
E: ID_USB_INTERFACES=:080650:
E: ID_USB_INTERFACE_NUM=00
E: ID_USB_DRIVER=usb-storage
E: ID_PATH=platform-3f980000.usb-usb-0:1.2:1.0-scsi-0:0:0:0
E: ID_PATH_TAG=platform-3f980000_usb-usb-0_1_2_1_0-scsi-0_0_0_0
E: ID_FS_UUID=e1d2d53c-ba70-402f-820c-27162be4a94c
E: ID_FS_UUID_ENC=e1d2d53c-ba70-402f-820c-27162be4a94c
E: ID_FS_VERSION=1.0
E: ID_FS_TYPE=ext4
E: ID_FS_USAGE=filesystem
E: DEVLINKS=/dev/disk/by-path/platform-3f980000.usb-usb-0:1.2:1.0-scsi-0:0:0:0 /dev/disk/by-id/usb-SanDisk_Ultra_Fit_4C530000021118120214-0:0 /dev/disk/by-uuid/e1d2d53c-ba70-402f-820c-27162be4a94c
E: TAGS=:systemd:
E: CURRENT_TAGS=:systemd:

pi@raspberrypi:~$

[手順3]接続時ルールを作成する

早速 udev 用のルールファイルを作成します。
今回は SUBSYSTEM , ID_SERIAL_SHORT の2つをキーとして使用します。
作成したルールファイルは /etc/udev/rules.d に格納します。

下記コマンドを実行して rules ファイルを作成します。

sudo nano /etc/udev/rules.d/99-usb-serial.rules

今回は既にあるファイル名と被らないように、99- で作成しました。
ルールファイルはファイル名の辞書順に実行されます。

下記のように 99-usb-serial.rules に記述して保存します。
SYMLINK に任意の名称を記述してください。
MODE はパーミッションの設定です。MODE の詳細は こちら

SUBSYSTEM=="tty",ENV{ID_SERIAL_SHORT}=="先ほど調べた[ID_SERIAL_SHORT]の値",SYMLINK+="USB-test1",MODE="0666"

[手順4]ルールが適用されているか確認する

下記コマンドで udev にルールファイルを再読み込みさせます。

sudo udevadm trigger
または
sudo /etc/init.d/udev reload

再読み込み後、デバイスファイル名が SYMLINK で指定した値になっています。
ならない場合はラズベリーパイを再起動してみてください。

同様にもう一方のデバイスルールも設定します。99-usb-serial.rules に追記して構いません。
追記後に再読み込みすると以下のように反映されます。

このように各デバイスファイルに名前を付けることができました。
作業中のデバイスが一目でわかります。

[まとめ]

・udevのルールを作成することで作業中のデバイスが判別しやすくなります。
・今回はキーにシリアル番号(ID_SERIAL_SHORT)を使いましたが、作業環境によって使用するキーを変えるとより使い勝手がよくなります。
 例えば、ID_PATH_TAG をキーとして使うと、USB ポートで指定してデバイスを特定できます。(その2で紹介)
・そのほかにも、特定のデバイスを接続したときにスクリプトを実行する等の様々なルール設定が可能です。