はじめに (対象読者・この記事でわかること)
この記事は、Linux/Ubuntuの基本的な知識があり、シリアル通信を利用する開発者やシステム管理者を対象としています。この記事を読むことで、Ubuntuでのシリアルポートの識別方法、デバイスファイルの命名規則、ポート番号の割り当て順序を理解し、複数のシリアルデバイスを正確に識別・利用できるようになります。また、udevルールを使用してデバイス名を固定する方法も学べます。これにより、システム起動ごとに変わるポート番号の問題を解決し、安定した通信環境を構築できます。
前提知識
この記事を読み進める上で、以下の知識があるとスムーズです。 - Linux/Ubuntuの基本的なコマンド操作 - シリアル通信の基本的な概念 - テキストエディタの基本的な操作
Ubuntuでのシリアルポート割り当ての問題点
Ubuntuでは、シリアルポートに接続されたデバイスが認識されると、自動的にデバイスファイル(/dev/ttySや/dev/ttyUSBなど)が作成されます。しかし、複数のシリアルデバイスを接続した場合、そのデバイスファイルの名前(特に番号部分)が毎回同じとは限りません。これは、システムがデバイスを検出する順序やUSBポートの接続順に依存するためです。
この問題は、特定のポートに依存したアプリケーションを実行している場合や、複数のデバイスを管理する際に予期せぬ動作を引き起こす可能性があります。例えば、スクリプトが特定のポート名(/dev/ttyUSB0)をハードコーディングしている場合、デバイスの接続順序が変わるとそのポート番号が変わってしまい、通信に失敗してしまいます。
本記事では、この問題の原因と、udevルールを使用してデバイス名を固定する具体的な解決策について解説します。
シリアルデバイスの識別と名前固定の具体的な手順
ステップ1:現在のシリアルデバイスの確認
まず、システムに接続されているシリアルデバイスを確認します。以下のコマンドを使用します。
Bashls /dev/ttyS* ls /dev/ttyUSB* ls /dev/ttyACM*
これにより、現在認識されているシリアルデバイスの一覧が表示されます。また、dmesgコマンドを使用して、システム起動時に検出されたデバイス情報を確認することもできます。
Bashdmesg | grep -i "serial"
ステップ2:デバイス情報の特定
udevルールを作成するには、各デバイスを一意に識別できる情報が必要です。udevadmコマンドを使用して、デバイスの詳細情報を取得します。
Bashudevadm info -a -n /dev/ttyUSB0
このコマンドは、指定したデバイスに関するudevの属性情報を表示します。特に「ATTRS{idVendor}」や「ATTRS{idProduct}」などのUSBデバイス固有の情報に注目します。
ステップ3:udevルールの作成
デバイスを一意に識別できる情報が分かったら、udevルールを作成します。以下のコマンドでルールファイルを作成します。
Bashsudo nano /etc/udev/rules.d/99-serial-devices.rules
ファイル内に以下のようなルールを追加します。例えば、特定のベンダーIDとプロダクトIDを持つUSBシリアルデバイスを/my-serial-deviceという名前で固定する場合:
SUBSYSTEM=="tty", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", SYMLINK+="my-serial-device"
このルールは、ベンダーIDが1234でプロダクトIDが5678のUSBシリアルデバイスが接続された場合、/dev/my-serial-deviceというシンボリックリンクを作成するものです。複数のデバイスを識別する場合は、複数のルールを追加します。
ステップ4:udevルールの適用
作成したルールを適用するには、以下のコマンドを実行します。
Bashsudo udevadm control --reload-rules sudo udevadm trigger
これにより、新しいルールがシステムに適用され、接続されているデバイスにもルールが適用されます。
ステップ5:デバイス名の確認
再度デバイス一覧を確認し、作成したシンボリックリンクが正しく作成されているか確認します。
Bashls -l /dev/my-serial-device
ハマった点やエラー解決
udevルールを作成する際によく遭遇する問題とその解決策を以下に示します。
問題1:ルールが適用されない
作成したルールが適用されない場合、以下の点を確認してください。 - ルールファイルのパーミッションが正しいか(通常は644) - ルール構文に誤りがないか(特に引用符やバックスラッシュのエスケープ) - デバイスの属性情報が正しく取得されているか
解決策として、udevadm testコマンドを使用してルールのテストが可能です。
Bashsudo udevadm test /sys/class/tty/ttyUSB0
問題2:複数のデバイスが同じ名前で競合する
複数の同じ種類のデバイスを使用する場合、シンボリックリンク名が競合することがあります。この場合、デバイスのシリアル番号などのより詳細な情報を使用してルールを特定化します。
SUBSYSTEM=="tty", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", ATTRS{serial}=="ABC123", SYMLINK+="my-serial-device-1"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", ATTRS{serial}=="DEF456", SYMLINK+="my-serial-device-2"
問題3:システム再起動後も設定が保持されない
udevルールはシステム再起動後も保持されるはずですが、設定が保持されない場合は、ルールファイルの保存場所やパーミッションを再確認してください。また、initramfsの更新が必要な場合もあります。
Bashsudo update-initramfs -u
解決策
上記の問題に対する解決策をまとめると、以下のようになります。
1. ルール構文の正確性を確認し、必要に応じてudevadm testでテストする
2. デバイスの固有情報(シリアル番号など)を使用してルールを特定化する
3. ルールファイルのパーミッションと保存場所を確認する
4. 必要に応じてinitramfsを更新する
まとめ
本記事では、Ubuntuでのシリアル通信ポート番号の割り当て順序と、udevルールを使用したデバイス名の固定方法について解説しました。複数のシリアルデバイスを使用する際には、システム起動ごとに変わるポート番号の問題が発生することがありますが、udevルールを正しく設定することで、安定したデバイス名を確保できます。これにより、アプリケーションの設定を簡略化し、システムの信頼性を向上させることができます。今後は、シリアル通信のセキュリティ対策やパフォーマンスチューニングについても記事にする予定です。
参考資料
