スズハドットコム

IT関連や3Dプリンタの記事、たまに生活のメモを書いていきます。

USBケーブル1本でRaspberry Piとシリアルコンソール接続する

Wi-Fi環境のない場所でパソコンからRaspberry Pi Zero 2 Wに接続したかったので調べました。
USB-シリアル変換ケーブルも使わず、USB A - microB ケーブルだけでRaspberry Pi Zero 2 Wとパソコンを接続します。
※設定作業時はRaspberry Pi Zero 2 Wにディスプレイ・キーボードを接続するか、SSH接続する必要があります。

もくじ


環境

  • Raspberry Pi Zero 2 W
  • Raspberry Pi OS Lite 32-bit (2024-03-15)
  • Windows11 PC
  • Tera Term v4

LiteじゃないRaspberry Pi OSでも同じように動作するはずです。たぶん。

下準備

Raspberry Pi ImagerでmicroSDにOSを書き込みます。
このあとの設定作業をSSH接続でおこなう場合は、オプションでWi-Fi接続設定とSSH有効化のチェックを忘れずに。

Raspberry PiにmicroSDをさして起動します。

Raspberry Piにディスプレイ・キーボードを接続して直接ログインするか、SSH接続します。
(今回はSSH接続してます。)

/boot/firmware/config.txt の編集

/boot/firmware/config.txt の末尾に「dtoverlay=dwc2」を追加します。

$ sudo vi /boot/firmware/config.txt
(中略)
[all]
dtoverlay=dwc2

/boot/firmware/cmdline.txt の編集

/boot/firmware/cmdline.txt の「rootwait」より後に「modules-load=dwc2,g_serial」を追加します。「rootwait」の直後に記載せよという記事が多いですが、「rootwait」より後ならどこでも大丈夫かと思います。
なお、このファイルは1行で書かれており、改行してはいけません。

$ sudo vi /boot/firmware/cmdline.txt
console=serial0,115200 (中略) rootwait cfg80211.ieee80211_regdom=JP modules-load=dwc2,g_serial

再起動

再起動して設定反映します。

$ sudo reboot

serial-getty@ttyGS0.service の有効化

serial-getty@ttyGS0.service の状態を確認します。デフォルトでは有効ではないはずです。

$ systemctl status serial-getty@ttyGS0.service
○ serial-getty@ttyGS0.service - Serial Getty on ttyGS0
     Loaded: loaded (/lib/systemd/system/serial-getty@.service; disabled; preset: enabled)
     Active: inactive (dead)

サービスを有効化&起動します。

$ sudo systemctl enable serial-getty@ttyGS0.service
Created symlink /etc/systemd/system/getty.target.wants/serial-getty@ttyGS0.service → /lib/systemd/system/serial-gettservice.
$ sudo systemctl start serial-getty@ttyGS0.service

起動確認します。状態がactiveになりました。

$ systemctl status serial-getty@ttyGS0.service
● serial-getty@ttyGS0.service - Serial Getty on ttyGS0
     Loaded: loaded (/lib/systemd/system/serial-getty@.service; enabled; preset: enabled)
     Active: active (running) since Fri 2024-05-31 00:40:40 JST; 2s ago

シリアルコンソール接続

USBケーブルでパソコンと接続します。
2つあるUSBのうち内側のポートを使います。

ちなみに、外側のポートに電源を繋がずパソコンからの給電だけの状態でも普通に動作しました。

Windowsのデバイスマネージャを開くと、USBシリアルデバイス (COM5)として認識されていました。
※番号は環境次第です。必ずCOM5になる訳ではありません。

TeraTermを開き、「シリアル接続」で先ほど確認したCOMポートを選択して接続します。

無事シリアルコンソール接続できました。
これで、USBケーブルでRaspberry Pi Zero 2 Wとパソコンを接続すれば、外出先だろうが屋外だろうがどこでも操作可能です。

※シリアル接続直後は真っ黒な画面ですが、Enterキー等を一度押すとログインプロンプトが見えます。

設定の意味を確認する

/boot/firmware/config.txt の「dtoverlay=dwc2」

dtoverlayはデバイスツリーオーバーレイの設定です。

デバイスツリーオーバーレイの話をする前にデバイスツリーとは何なのか?を説明すると、
デバイスツリーはシステムのハードウェア構成を表現するデータ構造で、ブートローダ等がOSにハードウェア情報を伝達するために利用します。OSはこのデータを基にデバイスを識別し、必要なドライバモジュールをロードします。
https://www.lineo.co.jp/blog/linux/devicetree-1.html#2より要約引用)

このデバイスツリー情報を変更するには通常は再起動が必要なのですが、再起動することなくデバイスの追加やプロパティの変更などを可能にしようという仕組みがデバイスツリーオーバーレイです。

よって、/boot/firmware/config.txt に「dtoverlay=dwc2」を記載するのは、デバイスツリーオーバーレイで「dwc2」デバイスを追加する指定ということになります。

「dwc2」は何なのか?というと、OTG USB 2.0コントローラです。
Synopsys社のDesignWare CoreというIP(回路設計データ)からdwcという名前になっているようです。(頑張って調べたけどあんまり自信なし)

/boot/firmware/cmdline.txt の「modules-load=dwc2,g_serial」

cmdline.txt は、システム起動時のカーネルパラメータを定義するファイルです。
その中に記載される modules-load は文字通りロードするカーネルモジュールの指定です。

dwc2は、先ほども登場したOTG USB 2.0コントローラです。
g_serialはLinux USB gadget driverと呼ばれるものの一つで、USBをシリアルポートとして動作させます。
これらのカーネルモジュールをロードしています。

serial-getty@ttyGS0.service

g_serialにより使えるようになったシリアルポートは/dev/ttyGS0 として認識されます。
そこにgetty(ttyを管理するプログラム)を紐づけるのがこのサービスです。
これにより、ttyGS0に接続した際にログインプロンプトが表示されるようになります。

その他

(試していませんが)cmdline.txtでg_serialのかわりにg_etherを指定すると、イーサネットとして動作します。
Windows側にはUSB Ethernet/RNDIS Gadgetドライバが必要ですが、Windows10以降であれば標準で入っていそうです。

CUIでコマンドを叩くだけならシリアル接続で十分では?と思いますが、
・ファイル転送したい
・VNCでデスクトップ画面を操作したい
・Raspberry PiからPCを経由してインターネット接続(インターネット共有)したい
といった要求があればシリアル接続ではできないので、やってみる価値はありそうです。