2017年10月8日日曜日

Raspberry Pi の画面出力先を古いスマホにしてみた.【DispmanX VNC】


早い話が Raspberry Pi で VNCサーバーを起てて,Android の VNCクライアントでアクセスしたというお話.
DIY的にスマホ分解して HDMI入力できるようにしたよって話ではないので,目的が違う人はごめんなさい.

それでは,早速本題に.
まず,画面出力先に使用したのは,引き出しで数年間眠っていたこいつ.


せっかくなので当時の写真を紹介する.
時計が2011年を指していて,時代の流れを感じる.

その昔,WillcomでX PLATE(写真右)とセットで売られていたDell Streak 001DL(写真左)だ.

(当時の記事)
WM×LI: X PLATE × DELL Streak セットに機種変してきた
WM×LI: Dell Streak (001DL) をSIMフリー化した
WM×LI: Dell Streak(001DL)用にイオンSIMを買ってきた。

その頃は,SIMフリー化して,イオンSIMを挿して使ってたけど,今となっては何の役にも立たない代物.
こいつが今回の主役だ.

この産廃寸前の Dell Streak に VNCクライアントアプリをインストールする.
Android 2.2 でもきちんと動作する,アプリに感謝!!!



次に,Raspberry PiにVNCサーバーを設定する.
Raspberry Pi 用の VNCサーバーは有名なものとして以下の3つがあるが,

・X11VNC
・TightVNC server
・DispmanX VNC

デスクトップだけでなく,ディスプレイ出力画面そのものを映して欲しいので,今回はDispmanX VNCを採用した.

インストールするために,GitHubからソースをダウンロードする.
# git clone https://github.com/hanzelpeter/dispmanx_vnc.git /opt/dispmanxvnc

Cloning into '/opt/dispmanxvnc'...
remote: Counting objects: 50, done.
remote: Total 50 (delta 0), reused 1 (delta 0), pack-reused 49
Unpacking objects: 100% (50/50), done.

次にソースファイルをビルド.
# cd /opt/dispmanxvnc
# make

gcc -O3 main.c -o dispmanx_vncserver -DHAVE_LIBBCM_HOST -DUSE_EXTERNAL_LIBBCM_HOST
-DUSE_VCHIQ_ARM -Wno-psabi -I/opt/vc/include/ -I/opt/vc/include/interface/vcos/pth
reads -I/opt/vc/include/interface/vmcs_host/linux -L/opt/vc/lib/ -lGLESv2 -lEGL -l
openmaxil -lbcm_host -lvcos -lvchiq_arm -lpthread -lrt -lvncserver

【2018.1.14追記】
Raspbianを最新(stretch 2017.11.29版)にアップデートしたら,以下のメッセージが表示されmakeが通らなくなった.
/usr/bin/ld: -lGLESv2 が見つかりません
/usr/bin/ld: -lEGL が見つかりません
collect2: error: ld returned 1 exit status
Makefile:12: ターゲット 'dispmanx_vncserver' のレシピで失敗しました
make: *** [dispmanx_vncserver] エラー 1

どうやら,libGLESv2とかlibEGLが無い様子.コンパイルオプションを見ればわかるが,保存場所は/opt/vc/libっぽいので,調べてみる.
# cd /opt/vc/lib
# ls -l
合計 2908
-rw-r--r-- 1 root root 245356 10月 30 19:38 libEGL_static.a
-rw-r--r-- 1 root root 100008 10月 30 19:38 libGLESv2_static.a
-rw-r--r-- 1 root root  99516 10月 30 19:36 libbcm_host.so
-rw-r--r-- 1 root root 202072 10月 30 19:36 libbrcmEGL.so
-rw-r--r-- 1 root root 105768 10月 30 19:36 libbrcmGLESv2.so
-rw-r--r-- 1 root root  99208  9月 22  2016 libbrcmOpenVG.so
-rw-r--r-- 1 root root  78552 10月 30 19:36 libbrcmWFC.so
-rw-r--r-- 1 root root 364540 10月 30 19:36 libcontainers.so
-rw-r--r-- 1 root root  15932  7月  3  2017 libdebug_sym.so
-rw-r--r-- 1 root root  13254 10月 30 19:38 libdebug_sym_static.a
-rw-r--r-- 1 root root  52108  7月  3  2017 libdtovl.so
-rw-r--r-- 1 root root 344732  9月 22  2016 libelftoolchain.so
-rw-r--r-- 1 root root  13548 10月 30 19:38 libkhrn_client.a
-rw-r--r-- 1 root root 450476 10月 30 19:38 libkhrn_static.a
-rw-r--r-- 1 root root  15368 10月 30 19:36 libmmal.so
-rw-r--r-- 1 root root  68884 10月 30 19:36 libmmal_components.so
-rw-r--r-- 1 root root  82144 10月 30 19:36 libmmal_core.so
-rw-r--r-- 1 root root  90800 10月 30 19:36 libmmal_util.so
-rw-r--r-- 1 root root  44468 10月 30 19:36 libmmal_vc_client.so
-rw-r--r-- 1 root root  33208 10月 30 19:36 libopenmaxil.so
-rw-r--r-- 1 root root   3264 10月 30 19:38 libvcfiled_check.a
-rw-r--r-- 1 root root  30288 10月 30 19:36 libvchiq_arm.so
-rw-r--r-- 1 root root 140520 10月 30 19:38 libvchostif.a
-rw-r--r-- 1 root root  28462 10月 30 19:38 libvcilcs.a
-rw-r--r-- 1 root root 173108 10月 30 19:36 libvcos.so
-rw-r--r-- 1 root root  22240 10月 30 19:36 libvcsm.so
drwxr-xr-x 2 root root   4096 11月 29 10:28 pkgconfig
drwxr-xr-x 3 root root   4096 11月 29 10:22 plugins

明らかに上の2つ.(libEGL_static.aとlibGLESv2_static.a)が怪しい.staticとか付けんな!笑
こういうときは常套手段.フォルダ内でシンボリックリンクを貼ってやる.
# ln -s libEGL_static.a libEGL.a
# ln -s libGLESv2_static.a libGLESv2.a

再びビルドすると今度は成功
# cd /opt/dispmanxvnc
# make

gcc -O3 main.c -o dispmanx_vncserver -DHAVE_LIBBCM_HOST -DUSE_EXTERNAL_LIBBCM_HOST
-DUSE_VCHIQ_ARM -Wno-psabi -I/opt/vc/include/ -I/opt/vc/include/interface/vcos/pth
reads -I/opt/vc/include/interface/vmcs_host/linux -L/opt/vc/lib/ -lGLESv2 -lEGL -l
openmaxil -lbcm_host -lvcos -lvchiq_arm -lpthread -lrt -lvncserver

ビルドが完了したら起動する.起動情報も一緒に表示される.
# /opt/dispmanxvnc/dispmanx_vncserver

Open display[0]...
Display is 720 x 480
Server bpp:16
Server bigEndian:0
Server redShift:0
Server blueShift:10
Server greeShift:5
08/10/2017 21:29:12 Listening for VNC connections on TCP port 5900
08/10/2017 21:29:12 Listening for VNC connections on TCP6 port 5900
open /dev/uinput returned 6.
First write returned 1116.
ioctl UI_DEV_CREATE returned 0.


そして先程,Dell Streak にインストールした VNCクライアントアプリから接続してやる.
ポート番号もデフォルトの5900番なので,特に難しい設定は必要なく,簡単に接続できた.

また,サーバー側では丁寧にコネクティングの状況も追加で表示してくれる.
08/10/2017 21:32:37   other clients:
08/10/2017 21:32:37 Normal socket connection
08/10/2017 21:32:37 Client Protocol Version 3.8 y1=448
08/10/2017 21:32:37 Protocol version sent 3.8, using 3.8 
08/10/2017 21:32:37 rfbProcessClientSecurityType: executing handler for type 1
08/10/2017 21:32:37 rfbProcessClientSecurityType: returning securityResult for client
 rfb version >= 3.8 
08/10/2017 21:32:37 Pixel format for client 192.168.200.101:
08/10/2017 21:32:37   32 bpp, depth 24, little endian
08/10/2017 21:32:37   true colour: max r 255 g 255 b 255, shift r 16 g 8 b 0 
08/10/2017 21:32:39 Enabling LastRect protocol extension for client 192.168.200.101
08/10/2017 21:32:39 Enabling NewFBSize protocol extension for client 192.168.200.101
08/10/2017 21:32:39 Using ZRLE encoding for client 192.168.200.101


最後に DispmanX VNC の自動起動を設定する.例のごとく,systemdの設定ファイルを新規で作成してやる.
# vim /etc/systemd/system/dispmanxvnc.service
-----
Description=DispmanX VNC Server
After=network.target remote-fs.target nss-lookup.target

[Service]
ExecStart=/opt/dispmanxvnc/dispmanx_vncserver
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target

保存したら,systemctl enable コマンドで有効化する.
# systemctl enable dispmanxvnc.service
Created symlink /etc/systemd/system/multi-user.target.wants/dispmanxvnc.service
 → /etc/systemd/system/dispmanxvnc.service.

再起動して問題なく,VNCクライアントから接続できるようになれば,今回のミッション完了.
Raspberry Piの画面出力用に車載モニタでも買ってきて,机に取り付けようかと思っていたが,こいつでしばらくの間は満足できそうだ.

【追記】
このままだと,何も操作しないまま一定時間経つとRaspberry Piのコンソール画面が真っ暗になってしまうので,以下のブートオプション?を追加する.
# vim /boot/cmdline.txt
-----
consoleblank=0


0 件のコメント:

コメントを投稿