USBシリアルCOMポートが消える:再列挙、ドライババインド、ポート番号、CDCブリッジのデバッグ

USBシリアルCOMポートの消滅、ポート番号変更、再列挙、CDC ACMブリッジのリセット、ドライババインド失敗、古いハンドルを使い続けるアプリのトラブルシューティング方法を解説します。

USBシリアルCOMポート消失, COMポート見つからない, CDC ACM, USBシリアルブリッジ, 再列挙, ドライババインド, USB診断

USBシリアルデバイスはあらゆるところにあります。Arduinoボード、産業用コントローラ、モデム、GPS受信機、テスト治具、デバッグプローブ、PLCツール、バーコードデバイス、独自CDC ACMファームウェア。COMポートが消えると、USB serial COM port disappearsCOM port missing Device ManagerUSB serial re-enumeratesCDC ACM device disconnectsCOM port changes after reconnect で検索される羽目に。アプリの側は「ポートを開けない」としか言わないのが普通です。

Bus Scopeが効くのは、COMポート消滅の原因レイヤーがまったく異なるからです。USB列挙/ディスクリプタ問題/ドライババインド/デバイスリセット/古いアプリハンドル/ラインコーディングリクエスト失敗/WindowsのCOM番号再採番——いずれも候補になります。

COMポートはUSBデバイスそのものではない

COMポートは、USBデバイスが列挙しシリアルドライバがバインドされた「後」に作られるOS抽象です。USBデバイスが一度も列挙しなければCOMポートは出ません。USBデバイスは列挙したのにCDCインターフェースが落ちればCOMポートは依然として現れないかもしれません。

レイヤーを分けて確認します。

  • USBデバイスはアタッチしたか?
  • ディスクリプタは正しく読まれたか?
  • コンフィギュレーションは完了したか?
  • CDCインターフェースは現れたか?
  • ドライバはバインドしたか?
  • OSはCOMポートを割り当てたか?
  • アプリは正しい現在のポートを開いたか?

再列挙はポート番号を変える

Windowsは、シリアル番号/USBパス/VID/PID/インターフェース識別子が変わったデバイスには新しいCOM番号を割り当てることがあります。ブートローダーモードにリセットされたデバイスは、別COMポートになるかCOMポート自体を失うことがあります。

症状:

  • デバイスがCOM8だったのに今はCOM11
  • アプリが古いCOMポートを覚えている
  • 別のUSBポートに差し替えると割り当てが変わる
  • ブートローダーは別ポートを使う
  • ファームウェア更新後にデバイスが不明デバイスとして現れる

バストレースはデバイス識別子が変わったかどうかを示してくれます。

CDC ACMコントロールリクエスト

CDCシリアルデバイスはクラスリクエストを受けることがあります。

  • SET_LINE_CODING
  • GET_LINE_CODING
  • SET_CONTROL_LINE_STATE
  • SEND_BREAK

ファームウェアがこれらをストール/誤処理すると、ポートは開いてもデータが流れない/ドライババインドが失敗する/ということが起きます。

接続時だけでなく「ポートを開いた後」をキャプチャしましょう。アプリがCOMポートを開いてドライバがラインコーディングやDTR/RTSを送る段階で多くが失敗します。

古いアプリハンドル

USBが正しく再列挙しても、アプリが古いハンドルやキャッシュ済みCOMポートリストを使い続けていることがあります。バス上は新デバイスが見えていますが、アプリはポートを解放も再取得もしていないため失敗します。

これはUSBバスの失敗ではなく、アプリ/デバイス管理挙動の問題です。

デバッグチェックリスト

次の流れで作業すると、原因に早くたどり着けます。

  1. 接続時からキャプチャする
  2. デバイスディスクリプタとコンフィギュレーションディスクリプタを確認する
  3. CDCインターフェースディスクリプタを確認する
  4. アプリがCOMポートを開く瞬間をキャプチャする
  5. CDCクラスリクエストを確認する
  6. ラインコーディング後にリセット/切断がないか確認する
  7. 再接続前後のデバイス識別子を比較する
  8. COM番号が変わったかを確認する
  9. アプリが古いポート名を使っていないか確認する
  10. USB証拠とOSポート割り当てメモの両方を保全する

最終的な診断

USBシリアルCOMポートの消滅は、列挙失敗/CDCディスクリプタ失敗/ドライババインド失敗/新識別子での再列挙/ラインコーディング失敗/負荷時リセット/アプリ側状態不整合のどれかであり得ます。

Bus ScopeはUSB側の物語を可視化するので、COMポート症状をアタッチ/ディスクリプタ/CDCリクエスト/リセット/実際のデバイス識別子に紐づけられます。