FreeBSDでUSBデバイスを使う際、それが同じ用途のデバイスであるとUSBポートの差し替えとか認識される順序によっては/dev/デバイス名○の数字の部分が変わってしまう。ヘタにデバイス名をアテにして設定しているとデバイス名が変わることで困ってしまう。そこで特定のUSBデバイスを接続したらそれに応じたデバイス名になるよう固定する。
参考: https://habr.com/ru/post/200330/
まず、USBデバイスの情報を表示した。# usbconfig dump_device_desc
中略
ugen1.2: <Linux 4.19.68-sunxi with musb-hdrc Gadget Serial v2.4> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (2mA)
bLength = 0x0012
bDescriptorType = 0x0001
bcdUSB = 0x0200
bDeviceClass = 0x0002 <Communication device>
bDeviceSubClass = 0x0000
bDeviceProtocol = 0x0000
bMaxPacketSize0 = 0x0040
idVendor = 0x0525
idProduct = 0xa4a7
bcdDevice = 0x0419
iManufacturer = 0x0001 <Linux 4.19.68-sunxi with musb-hdrc>
iProduct = 0x0002 <Gadget Serial v2.4>
iSerialNumber = 0x0000 <no string>
bNumConfigurations = 0x0001
中略
ugen2.3: <u-blox AG - www.u-blox.com u-blox 7 - GPS/GNSS Receiver> at usbus2, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA)
bLength = 0x0012
bDescriptorType = 0x0001
bcdUSB = 0x0110
bDeviceClass = 0x0002 <Communication device>
bDeviceSubClass = 0x0000
bDeviceProtocol = 0x0000
bMaxPacketSize0 = 0x0040
idVendor = 0x1546
idProduct = 0x01a7
bcdDevice = 0x0100
iManufacturer = 0x0001 <u-blox AG - www.u-blox.com>
iProduct = 0x0002 <u-blox 7 - GPS/GNSS Receiver>
iSerialNumber = 0x0000 <no string>
bNumConfigurations = 0x0001
ugen1.2がUSBシリアル接続のデバイス(Linuxシングルボードコンピュータ)
ugen2.3がUSBシリアル接続のGPSモジュール
/etc/devd.confで使える変数 $device-nameは /dev/デバイス名 の「デバイス名」部分が入るのだろうと思っていたが、シリアルデバイスの一部(全部?)はデバイス名がttyU*ではなく、umodem*になるっぽい。/devにはそんなデバイス無いのにね。(「がとらぼ」で試した範囲では)
なので、umodemをttyUに置換して それを指定したデバイス名にシンボリックリンクする。
1 2 3 4 5 6 7 | #!/bin/sh
# $1 置換前デバイス名 devd.confの$device-nameが入る前提
# $2 $device-nameのデバイス名で数字が付いていない部分下の例ではumodem
# $3 $device-nameのデバイス名の置換後
# $4 シンボリックリンク先 目的のデバイス名
/bin/ln -s $(echo /dev/$1 | /usr/bin/sed "s/$2/$3/g") $4
|
# chmod +x /usr/local/bin/ln_dev.sh
実行可能にしておく。
/etc/devd.conf (ファイル最後に追加)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | //USBシリアル通信デバイス (シングルボードコンピュータ)
attach 100 {
match "vendor" "0x0525";
match "product" "0xa4a7";
match "release" "0x0419";
action "/usr/local/etc/ln_dev.sh $device-name umodem ttyU /dev/hoge0";
};
detach 100 {
match "vendor" "0x0525";
match "product" "0xa4a7";
match "release" "0x0419";
action "/bin/rm /dev/hoge0";
};
//USB GPS module
attach 100 {
match "vendor" "0x1546";
match "product" "0x01a7";
match "release" "0x0100";
action "/usr/local/etc/ln_dev.sh $device-name umodem ttyU /dev/gps0";
};
detach 100 {
match "vendor" "0x1546";
match "product" "0x01a7";
match "release" "0x0100";
action "/bin/rm /dev/gps0";
};
|
attachがデバイス接続時。detachがデバイスの接続が切れたときに使用される。
先にusbconfigで見た内容のidVendorがdev.confで指定するvendorに対応する。同様にidProductがproductに、bcdDeviceがreleaseに対応する。上の例では3つがマッチした場合にactionするようにしたが、3つでなければならないわけではない。マッチさせる条件が多い方がより確実だろうけど、シリアル番号のようなものがあるなら例えばベンダー名とシリアルの2つで確実にユニークなデバイスとして識別できるかもしれない。
ただ、今回の機器は2つともiSerialNumber: 0x0000 <no string>でデバイス識別には役立ちそうになかったのでmatch条件にはしていない。
上の例ではシングルボードコンピュータは/dev/hoge0、GPSモジュールは/dev/gps0となる。それぞれ最後の0は上のようにdevd.confで指定したから付くというだけであって、数字を付けなければならないというものではない。今後GPSモジュールを追加で接続するならgps1とかgps2とかにするという目論見での命名。
# service devd restart
devdを再起動。
これで、USBデバイスのケーブルを抜き差ししたりシステムを再起動したりで/dev/ttyU0だとか/etc/ttyU1だとかの数字が変わっても、その内容から識別してデバイス名のシンボリックリンクが作られるので安心。