ラズベリーパイとLCD-USB7XW/BとLCD-USB10XB-T (後編: Part 1)

Linuxではまだ使える?

Windows 10ではもうサポート外となってしまった外付けのUSB液晶モニタ、『LCD-USB7XW/B』と『LCD-USB10XB-T』、Linuxだと『udlfb』か『udl』というカーネルドライバーがUSB 2.0のDisplayLinkのディスプレイチップをサポートしているという事なので、どうにか手持ちのラズベリーパイ (Rpi2 B+) に繋げてみたいと思います。

因みに、手持ちのラズベリーパイにはリリースのRaspbian (ラズビアン) Busterのデスクトップ版が入っていて、Linuxのカーネルバージョンは4.19.75でした。

LCD-USB7XW/BとラズビアンLinux

※「ラズビアン」はラズベリーパイ本家公認のDebian(デビアン) Linuxです。


『udlfb』カーネルドライバ

udlfb』は『USB DisplayLink Frame Buffer』の略で、 LCD-USB7XW/Bや、LCD-USB10XB-Tなどに使われているDisplay Link社のUSB2.0接続のグラフィック・チップ用のLinuxカーネルドライバーです。

英語になりますが、Linuxのカーネル4.19のソースコードのドキュメント にudlfbこのドライバーの説明があります (👉linux/Documentation/fb/udlfb.txt)。

説明によるとudlfドライバが接続されたデバイスを正常に認識した場合は、モニターの全画面を緑色に表示する仕様になっています。 なのでXウインドウが起動する前の段階に、画面が緑色になったかどうかで、モニターがラズベリーパイに認識されたかどうかが確認できます。


『udl』カーネルドライバ

udlドライバはudlfbを新しく書き直したDRMドライバーらしいのですが、しっかりとしたドキュメントもなく、ソースコードの linux/drivers/gpu/drm/udl にあるソースコード内のコメントも無きに等しい量です。 コード内のコピーライトの日付を見る限りではには開発が始まっているみたいですが、それでも何故か情報量が少ないです😔😔。


設定の流れ

当初はudlfb/udlドライバーを有効にすれば良いのだと甘く見ていましたが、LCD-USB7XW/BとLCD-USB10XB-Tに関しては、それだけではラズベリーパイに繋げてもモニターとしては認識されず、USBのモードを切り替えたりといったステップが必要でした。

これで、ラズベリーパイのHDMIを使わずにUSBモニターの一画面だけを使うのであれば、X.orgサーバーの設定を少し変更するだけでXウインドウとして使えたのですが、HDMIとUSBモニターの2画面両方を使うのにはウインドウ・マネージャーの設定もいじったりとかなり手こずりました。

結論としては、2画面両方をセットアップするのには以降の5ステップが必要でした:

  1. カーネルドライバの確認と読み込みテスト
  2. usb_modeswitchでモードの切り替え
  3. sr_modのモジュールの無効化
  4. X-Windowsの設定
  5. ウインドウ・マネージャーの設定

はじめる前に

この記事では、テストにリリースのRaspbian Busterを使いましたが、今後のリリースで、もしかしたら、ラズベリーパイの設定を何も変更せずにLCD-USB7XW/BやLCD-USB10XB-Tが自動認識される様にシステムが大幅に改善される可能性が絶対無いとは言えないので、設定をいじる前に一度、USBモニターを手持ちのラズベリーパイに接続してから起動してみて、モニターが自動的に認識されるか試してみた方が良いかもしれません。

もしも、USBモニターの全画面が緑色になった場合はudlfbドライバーが設定された状態なのでステップ-4へ進んで下さい。 もちろん、設定をいじる前にXウインドウがUSBモニター上で起動した場合はもうこの記事の意味が無いですねw。


ステップ-1: カーネルドライバの確認と読み込みテスト

udlfb/udlドライバーはカーネルドライバーなので、Linuxのカーネルの設定がこれらのドライバーをサポードしている必要があります。

結果を先に書きますが、(現在)最新のラズビアン(Raspbian Buster)ではudlfbとudlの両方がすでに有効化されているので最近のラズビアンを使っている場合はこのままステップ2へ進んで問題ありません(👉ステップ-2へ)。 でも、もしも何かの不都合がある場合はステップ-1.1から順に確認して行く事をお勧めします。


ステップ-1.1: udlfb/udlドライバの確認

まずはラズビアンを起動させて、コンソール又はターミナル・ウインドウから次の2行のコマンドを実行して使っているLinuxカーネルがudlfb/udlのドライバーをサポートしているかを確認します:

pi@raspberrypi:~ $ sudo modprobe configs
pi@raspberrypi:~ $ zcat /proc/config.gz | grep UDL

一行目はカーネルがIKCONFIG (In-Kernel Config)という機能をカーネルモージュールとして読み込むコマンドになります。 もしも、一行目でエラーが出てしまう場合は使っているLinuxカーネルがIKCONFIGモジュールをサポートしていないか、IKCONFIGの機能がモジュールとしてではなく標準で既にカーネルに組み込まれている可能性があります。

前者の場合はIKCONFIGの機能が無効なので次のステップに進んで、後者の場合は二行目のコマンドでエラーは出ないはずなのでこのまま読み進めて下さい。

IKCONFモジュールが読み込まれると、稼働中のカーネルの設定が/proc/config.gzというgz圧縮されているテキストファイルから確認出来る様になります。

二行目のコマンドはそのファイルをzcatコマンドで展開して画面出力、でも、行数が多いので、出力をパイプ(|)でgrepコマンドに渡して"UDL"という文字を含む行だけを表示させます。


udlfbドライバー

上の2行目のコマンドを実行した後の表示に

CONFIG_FB_UDL=m

という行が含まれる場合はudlfbドライバーはモジュールとして設定されています。

CONFIG_FB_UDLはudlfbドライバー用のカーネル設定で:

CONFIG_FB_UDL=y

という行が含まれる場合はudlfbドライバーはカーネルの一部として組み込まれているので、モジュールとして読み込む必要はありません。

でも、

#CONFIG_FB_UDL is not set

という行が含まれる場合はudlfbドライバーが無効になっているので有効になっている別のカーネルを使うか、新たにドライバーを有効に設定したカーネルをコンパイルし直す必要があります。 👉カーネルのコンパイルに関してはネット検索などで沢山説明しているページが出てくるはずなのでそちらを参照して下さい。。。


udlドライバー

CONFIG_DRM_UDLはudlドライバー用の設定で、udlfbドライバーの場合と同様に上の2行目のコマンドを実行した後に、

  • 『CONFIG_DRM_UDL=m』という行が含まれていればudlドライバーはモジュールとして、
  • 『CONFIG_DRM_UDL=y』という行が含まれていればudlドライバーはカーネルの一部として、
  • 『#CONFIG_DRM_UDL is not set』という行が含まれていればudlドライバーは無効として

設定されています。

udlfbとudlのドライバー両方又はどちらかがモジュールとして設定されている場合は次のステップで実際にモジュール化されたドライバーが読み込めるか確認しておます。

ドライバー両方がカーネルの一部として設定されいる場合は👉ステップ-2へ


ステップ-1.2: 手動でドライバーモジュールを読み込む

USB機器の場合は、ドライバーに機器特有のID (Vender IDとProducr ID)が登録されていれば各当するドライバーモジュールが自動で読み込まれる設定になっていますが、何らかの理由で読み込めるモジュールが存在しなかったりでエラーになるケースもあるので実際にモジュール化されたudlfb/udlドライバーが読み込めるか手動で確認しておきます。

因みに、ドライバーが読み込まれたかは、lsmodコマンドで現在有効になっているカーネルモジュールをリストして確認できます:

pi@raspberrypi:~ $ lsmod

でも、これだと読み込まれているカーネルモジュール全てがリストされて長いので

pi@raspberrypi:~ $ lsmod | grep udl

でudlのキーワードを含む行だけにリストを絞ります。

次は手持ちのラズベリーパイでudlfbのドライバーを手動で読み込んだ後に上のコマンドを実行した後の出力の例です:

udlfb                  24576  0
syscopyarea            16384  1 udlfb
sysfillrect            16384  1 udlfb
sysimgblt              16384  1 udlfb
fb_sys_fops            16384  1 udlfb

もしも、lsmodの返す出力に『udlfb』又は『udl』が含まれる場合は既にそのドライバーモジュールが読み込まれているという事になります。

実際にudlfbドライバーをカーネルモジュールとして読み込むのにはmodprobeコマンドで:

pi@raspberrypi:~ $ sudo modprobe udlfb

同様にudlドライバーを読み込むのには:

pi@raspberrypi:~ $ sudo modprobe udl

モジュールが正常に読み込まれた場合は出力が返ってきませんが、不都合があった場合はエラーメッセージが出力されます。udlfb/udlモジュールの読み込みに問題が無ければ次のステップへ進みます。

エラーがあった場合はメッセージの内容を元に不都合を修正しないといけないのですが、対処方などはケースbyケースだと思うので詳しくは説明できませんが、個人でカーネルをビルドした場合はビルドの設定やモジュールのインストールの工程をもう一度確認したり、ラズビアンのパーッケージからのカーネルを使っている場合はアップデートや必要なパッケージが全部インストールされているか再確認すると良いと思います。


ステップ-2: usb_switchmodeでモードの切り替え

LCD-USB7XW/BやLCD-USB10XB-TなどのWindowsドライバー自動インストール機能付きのDisplayLinkベースのUSB2.0モニターは、初めに記憶媒体として認識されてしまうので『usb_switchmode』というコマンドでUSBモニターとして認識される様にUSBのConfigurationモードを切り替える必要があります。


ステップ-2.1: usb_switchmodeが既にインストールされているか確認

ラズビアンや他のデビアン互換のLinux場合だと今の処、usb_switchmodeは『usb-modeswitch』というパッケージに含まれているので、dpkgコマンドでusb-modeswitchパッケージがインストールされているか確認します。 (現在) 最新のラズビアン(Raspbian Buster)のデスクトップ版にはこのパッケージは既にインストールされています。:

pi@raspberrypi:~ $ dpkg -l usb-modeswitch

パッケージが正常にインストールされている場合は次の例の様に:

Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version         Architecture Description
+++-==============-===============-============-===========================================================
ii  usb-modeswitch 2.5.2+repack0-2 armhf        mode switching tool for controlling "flip flop" USB devices

一番最後の行の左端に『ii』と出力されます。 『ii』とは違う出力の場合はパッケージマネジャーでこのパッケージがインストールする様に設定されていないか、まだインストールが完了していない可能性が高いのでパッケージのインストール状態を再確認する必要があります。

もしも、次の様な出力が返って来た場合は

dpkg-query: no packages found matching usb-modeswitch

各当するパッケージの名前が変更になった可能性が高いので、変更された新しい名前を調べるか、usb_switchmodeをソースコードからインストールする必要があるかもしれません。


ステップ-2.2: usb_switchmodeの設定

usb_switchmodeがインストールされている事が確認出来たら『/etc/usb_modeswitch.d/』のディレクトリにUSBモニターのVender IDとProducr IDを使って

<Vender ID>:<Producr ID>

といった名前で設定ファイルを作ります。


アイ・オー・データ社のVender IDは「17e9」、LCD-USB7XW/BのProducr IDが「0153」、LCD-USB10XTのProducr ID「0156」なので:

  • LCD-USB7XW/B用には「17e9:0153」
  • LCD-USB10XTには「17e9:0156」

という設定ファイルを作って、ファイルの内容は次の様にします。

/etc/usb_modeswitch.d/17e9:0153

I-O DATA LCD-USB7X
TargetVendor=0x17e9
TargetProduct=0x0153
Configuration=1

/etc/usb_modeswitch.d/17e9:0156

I-O DATA LCD-USB10XT
TargetVendor=0x17e9
TargetProduct=0x0156
Configuration=1

[追記 ()] 公開時に書き忘れていましたが、以下の40-usb_modeswitch.rulesの変更も必要になります:

/lib/udev/rules.d/40-usb_modeswitch.rulesに次の内容を追加しますが、ベンダーIDとプロダクトIDで順番になっているので、既に登録されいる行の「ATTR{idVendor}=="」に続くベンダーIDが17e9よりも小さい番号から大きい番号になる間の行に追加します。

# io-data LCD-USB7X
ATTRS{idVendor}=="17e9", ATTRS{idProduct}=="0153", RUN+="usb_modeswitch '%b/%k'"

# io-data LCD-USB10XT
ATTRS{idVendor}=="17e9", ATTRS{idProduct}=="0156", RUN+="usb_modeswitch '%b/%k'"

例として手持ちのラズベリーパイでは/lib/udev/rules.d/40-usb_modeswitch.rules 内のベンダーID1782の行の下に追加しました。

# Spreadtrum SC7702 (Variant)
ATTR{idVendor}=="1782", ATTR{idProduct}=="0023", RUN+="usb_modeswitch '/%k'"

  [ここに上の内容を追加]

ステップ-3: sr_modのモジュールの無効化

前ステップでusb_modeswitchの設定をする事でラズベリーパイに繋げられたLCD-USB7XW/BやLCD-USB10XB-TがUSBモニターとして認識されるモードに自動的に切り替わる様になります。

でもそれだけだと、切り替わるタイミングに長めのラグがあって、起動時にXウインドウが自動的に立ち上がる設定になっているラズビアンだと切り替わるタイミングがXウインドウが立ち上がった後になってしまいます。 この場合、USBモニターはXウインドウとしては設定されず、緑の画面のままになってしまいます (udlfbドライバー使用時)。

色々と検索をしていた処、過去にモーバイル・モデムにもWindowsドライバー自動インストール機能付きのモデムがあったみたいで どこかの掲示板(すみません、URLをなくしました。。) 本家ラズベリーパイのフォーラムに「SCSIのCD-ROMドライバー・モジュールの『sr_mod』を無効にしてモデムを有効にする」という話があったので同じ様に「sr_mod」モジュールを無効にした処、Xウインドウが立ち上がる前にUSBモデムのドライバーが読み込まれる様になりました。

「sr_mod」モジュールを無効にする場合は /etc/modprove/raspi-blocklist.conf /etc/modprobe.d/raspi-blacklist.confに次の一行を加えます。 既に同じ内容の行がある場合は重複して加える必要はありません。

sr_mod

ステップ-4: X-Windowsの設定 (プレビュー)

ここまでの説明が長くなってしまったのでステップ-4以降はPart-2で紹介したいと思いますが、この時点だと、ラズベリーパイのHDMI出力は使わずにUSBモニターの一画面だけをメイン画面として使うのであれば、X.orgサーバーの設定を少し変更するだけでXウインドウとして使用可能なので紹介しておきます。

ラズベリーパイのHDMIは標準だと/dev/fb0のデバイスファイルに関連付けられるので、ラズベリーパイのHDMIを無効にしなければ、USBモニターは/dev/fb1のデバイスファイルに関連付けられます。

なので、Xウインドウ画面として使いたい場合はX.Orgの設定に/dev/fb1用の項目を加える必要があります。

/usr/share/X11/xorg.conf.d/99-fbturbo.conf のファイルにある、次の様な「Option "fdev" "/dev/fb0"」という行を含むデバイス・セクション (Section "Device")の前に

Section "Device"
        Identifier      "Allwinner A10/A13 FBDEV"
        Driver          "fbturbo"
        Option          "fbdev" "/dev/fb0"
        Option          "SwapbuffersWait" "true"
EndSection

次の内容を追加します:

Section "Device"
        Identifier      "DisplayLink"
        Driver          "fbturbo"
        Option          "fbdev" "/dev/fb1"
        Option          "ShadowFB" "off"
       Option          "SwapbuffersWait" "true"
EndSection

これで、起動時にLCD-USB7XW/BやLCD-USB10XB-Tが繋がっていれば、優先的にXウインドウのメイン画面として設定され、繋がっていない場合はラズベリーパイのHDMIがメイン画面として設定されます。

Part2に続きます。。




コメント

  1. 今まさに参考にさせてもらってます。
    Part2、楽しみに待ってます。

    返信削除
    返信
    1. 空き時間で書いているので直ぐとは言えませんが頑張ってみます。

      後、実際に再現できたか教えてもらえたら幸です。

      削除
    2. usb_switchmodeの設定を入れたところ、
      ちゃんと画面表示できました!

      初コメの時点で表示されなかったので、
      part2が必要なんだと思ってました。
      2画面同時使用の際にまた参考にさせていただきますね。

      ちなみにraspberry pi zeroでやりました。
      記載の通り電力不足が悩ましいです。
      ありがとうございました!

      削除
    3. 報告ありがとうございます。

      Pi Zeroだと消費電力が比較的少ないと思うので、電源の5Vアダプターは2Aとか3Aの電流を供給出来る物を使って、電源用のmicroUSBのケーブルも2Aとか3A対応の太い線が使われているケーブルを使っているか確認してみてはどうでしょう?

      (まだ確認していませんが)電源付きのハブで動かせると良いのですがね。。

      削除
  2. /etc/modprove/raspi-blocklist.conf

    /etc/modprobe.d/raspi-blacklist.conf
    だと思います!

    返信削除
    返信
    1. そうです。指摘ありがとうございます。

      ブログは他のマシンで編集していて、手動でコピーなのでこんな結果に。。

      削除
    2. 惜しいです。
      【誤】modprove.d
      【正】modprobe.d
      ディレクトリもでした。

      削除
    3. 度々の指摘、ありがとうございます🙇‍♂️🙇‍♂️。修正を加えさせてもらいました。

      削除
  3. FYI:「ステップ-2.2: usb_switchmodeの設定」で/lib/udev/rules.d/40-usb_modeswitch.rules の変更についての部分が抜けていたので先ほど修正しました。

    返信削除
  4. はじめまして。
    LCD-USB10XB-Tを入手したので参考にさせていただいております。
    突然ですが、どうしても原因がわからず行き詰まっているのでここで質問させていただきます。
    本文の通りに、USBモニタ単体での使用、HDMIとUSBモニタの併用のいずれの設定を行った場合も数度はUSBモニタにも出力されるのですが、再起動するとUSBモニタが緑一色の画面に戻ってしまいます。また、このときHDMI出力の方もGUIに入れなくなってしまいます。
    動作環境はラズパイ3b+でOSはrasbianを入れています。
    当方ラズパイ初心者で勉強中ですので、必要な情報が不足しているかもしれませんが、解決法がもしわかるようであればご教授いただけると幸いです。
    よろしくお願いいたします。

    返信削除
    返信
    1. gitlineさん、コメントありがとうございます。
      今週末時間があると思うので新しい記事で補足の説明を付け加えてみたいと思います (もしかしたら数日ずれ込むかもしれませんが。。)。

      削除

コメントを投稿