Linux上でのUSBデバイスのポート識別
課題
SonyのワンボードマイコンSpresenseと、衛星信号測位基板Allystar HD9310(旧基板)とでは、ともにUSB UARTドライバとしてSilicon Labs. CP210xを利用しています。Raspberry PiなどのLinux上では、両者とも/dev/ttyUSBx
(xには数値が入ります)なるデバイスで認識されます。
この両者を接続した状態で再起動すると、/dev/ttyUSB0
と/dev/ttyUSB1
の2つのデバイスが現れますが、タイミングによりどちらがSpresenseになるかわかりません。
多くの方々は、idVendor
とidProduct
とで自動識別されるようにudev
という仕組みを設定されていますが、この両者はともに10c4
とea60
であり、そのままではSpresenseとHD9310とを区別ができません。この両者をLinux上で個別に認識する方法を考えました。
調査
例えば、Raspberry Piにより/dev/ttyUSB0
として認識されたデバイスは何か、もう一方の/dev/ttyUSB1
として認識されたデバイスは何か、そして、その両者の違いを観察します。そのために、次のようなコマンドを実行します。
udevadm info -a -n /dev/ttyUSB0
この結果を、例えばttyUSB0.txt
なるファイルにリダイレクトし、/dev/ttyUSB1
についても同様にファイルに保存して、diff
コマンドなどにより両者の相違を探ります。あるいは、
udevadm monitor --environment --udev
を実行して、デバイスをUSBポートから抜き差ししてもよいでしょう。
私の使っているルールファイル
結局、私は次のようにしました。Spresenseを利用するためには/dev/ttyDCR
(DCRとはdisaster and crisis management reportのことで、私はこのSpresenseをみちびきの災害・機器管理通報サービスの受信に用いています)にて、HD9310を利用するためには/dev/ttyHD9310
にアクセスすればよく、便利です。
# u-blox ZED-F9P
KERNEL=="ttyACM*",\
ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a9",\
SYMLINK+="ttyF9P"
# ES920LR
KERNEL=="ttyUSB*",\
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001",\
SYMLINK+="ttyES920LR"
# Allystar HD9310
KERNEL=="ttyUSB*",\
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60",\
ATTRS{product}=="CP2104*",\
SYMLINK+="ttyHD9310"
# Sony Spresense
KERNEL=="ttyUSB*",\
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60",\
ATTRS{product}=="CP2102N*",\
SYMLINK+="ttyDCR"
# EOF
このルールファイルを/etc/udev/rules.d/00-spresense-hd9310.rules
などのファイルに保存して、/etdc/udev/rules.d/
ディレクトリにおき、次のコマンドを実行すると、自動的に、例えば、/dev/ttyUSB0
などのデバイスファイルに/dev/ttyDCR
などのリンクが作成されます。
udevadm control --reload-rules && udevadm trigger
このルールファイルには、私のよく利用するu-blox ZED-F9Pのものや、EASEL ES920LRのものも記述しています。