みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

raspberrypi3 yoctoでavahi

avahiを使うと、DHCPなどでIPアドレスが一定しない環境でも、hostname.localのように固定的な名前でネットワーク越しにアクセスできるようになる。

avahi自体はzeroconfのLinux向けの実装のことらしい。これが、yocto環境でも使えるということなので、試してみたが、ちょっとハマった。

問題

local.confに次のように追加してbitbakeを実行した。

IMAGE_INSTALL_append = " avahi"

すると次のようなエラーがでた。

ERROR: rpi-basic-image-1.0-r0 do_rootfs: avahi not found in the feeds (raspberrypi3 cortexa7t2hf-neon-vfpv4 cortexa7t2hf-neon cortexa7t2hf-vfp cortexa7hf-neon-vfpv4 cortexa7hf-neon cortexa7hf-vfp armv7vet2hf-neon-vfpv4 armv7vehf-neon-vfpv4 armv7vet2hf-neon armv7vehf-neon armv7vet2hf-vfp armv7vehf-vfp armv7at2hf-vfp armv7ahf-vfp armv6thf-vfp armv6hf-vfp armv5tehf-vfp armv5ehf-vfp armv5thf-vfp armv5hf-vfp noarch any all) in /home/XXXXXXX/work/yocto/rpi-morty/build/tmp/deploy/rpm.
ERROR: rpi-basic-image-1.0-r0 do_rootfs: This is often caused by an empty package declared in a recipe's PACKAGES variable. (Empty packages are not constructed unless ALLOW_EMPTY_<pkg> = '1' is used.)
ERROR: rpi-basic-image-1.0-r0 do_rootfs: Function failed: do_rootfs
ERROR: Logfile of failure stored in: /home/XXXXXXX/work/yocto/rpi-morty/build/tmp/work/raspberrypi3-poky-linux-gnueabi/rpi-basic-image/1.0-r0/temp/log.do_rootfs.30111
ERROR: Task (/home/XXXXXXX/work/yocto/rpi-morty/poky/meta-raspberrypi/recipes-core/images/rpi-basic-image.bb:do_rootfs) failed with exit code '1'

つまり、avahiのパッケージはないということらしい。レシピはあるのに。

正解

local.confに次のように追加すると、解決する。

IMAGE_INSTALL_append = " avahi-daemon"

raspberrypi3では次のようにアクセスが可能になる。

$ ping raspberrypi3.local

便利だ。

blockdiagを試す

テキストから図を生成するツールの一つにblockdiagがある。 次のような特徴を持つ。

パケット図の生成は他のツールを使用していた時に、微妙に困ったのでこれは良さそう。 また、日本人が開発していることも都合が良さそう。日本語への対応もある。

plantumlやgraphvizとかぶっているところもあるが、たとえば、ブロック図ではgraphvizに比べてノードシェイプの種類やスタック属性が書けるなど、比較的こちらのほうがやりたいことに近いかもしれない。

インストール

$ sudo pip install blockdiag actdiag seqdiag nwdiag

ブロック図

blockdiag {
    A -> B -> C 
}

実行方法

$ blockdiag simple.diag -Tsvg 

emacsとの連携

blockdiag-mode

blockdiag-modeがmelpaからインストールできる。

M-x list-packages -> blockdiag-modeを検索しInstallする。

プレビュー

blockdiagのプレビューは次のようなelispで行う。

(defun blockdiag-buffer ()
  (interactive)
  (let ((blockdiag-output "/tmp/blockdiag-buffer.png")
        (current-file (buffer-file-name (current-buffer))))
    (call-process "blockdiag" nil nil t "-o" blockdiag-output current-file)
    (switch-to-buffer-other-window
     (get-buffer-create "*blockdiag*"))
    (erase-buffer)
    (insert-file blockdiag-output)
    (image-mode)))
  
(push '("*blockdiag*") popwin:special-display-config)

出典はここ

pandocから使用する

フィルタを入手

matthiasbeyerさんのpandoc-paper-templateから使用させてもらう。

$ ~/bin
$ wget https://raw.githubusercontent.com/matthiasbeyer/pandoc-paper-template/master/scripts/blockdiag-filter.py
$ chmod +x blockdiag-filter.py

日本語対応パッチ

labelなどに日本語を食わすと「UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 」とエラーを吐くので、パッチを当てる。

--- blockdiag-filter.py.orig 2016-11-01 13:06:12.199636652 +0900
+++ blockdiag-filter.py   2017-04-12 09:17:00.707985814 +0900
@@ -13,7 +13,7 @@
 from pandocfilters import toJSONFilter, Str, Para, Image, attributes
 
 def sha1(x):
-  return hashlib.sha1(x).hexdigest()
+  return hashlib.sha1(x.encode('utf-8')).hexdigest()
 
 imagedir = "blockdiag-images"
 
@@ -22,7 +22,7 @@
 
 def save(data):
     fd, name = tempfile.mkstemp()
-    os.write(fd, data)
+    os.write(fd, data.encode('utf-8'))
     os.close(fd)
     return name
 

使用方法

次のように使用する。

$ pandoc -F blockdiag-filter.py [PANDOC-OPTIONS] [FILE-NAME ...]

次のようなマークダウンから

```rackdiag
rackdiag {
    7U;
    1: MAC
    2: IP
    3: TCP
    3: UDP
}
```

このようになる。

rackdiag {
    7U;
    1: MAC
    2: IP
    3: TCP
    3: UDP
}

ラズベリーパイゼロでyocto

日本でもようやくラズベリーパイゼロ(RPi0)が入手しやすくなったので、あきばお〜の店頭で入手してみた。

RPi0はmeta-raspberrypiでも対応済みなので、早速bitbakeをしてみる。

今回購入したのはベースキットなので、ピンヘッダからケーブルから一通りついているので、モニタやらキーボードを接続することもできるが、ピンヘッダを実装してUARTでシリアルコンソールからログインする。

ベース環境の取得

$ git clone git://git.yoctoproject.org/poky.git -b morty
$ cd poky
$ git clone git://git.yoctoproject.org/meta-raspberrypi -b morty

使用するのはmortyブランチ。

oe-init-build-envの読み込み

下記を実行する。

$ cd ~/rpi0
$ source poky/oe-init-build-env

これにより、クロスコンパイルに必要な環境変数が設定され、ビルドディレクトリに移動される。

meta-raspberrypiをビルド対象に追加

次のコマンドを実行する。

$ bitbake-layers add-layer ../poky/meta-raspberrypi

local.confの修正

次の行をlocal.confの先頭の方に追加する。

MACHINE ?= "raspberrypi0"

MACHINEはraspberrypi0に設定

動作確認

bitbakeの実行

$ bitbake rpi-basic-image

成功すると次のように表示される。

Parsing recipes: 100% |##########################################| Time: 0:00:27
Parsing of 884 .bb files complete (0 cached, 884 parsed). 1338 targets, 73 skipped, 0 masked, 0 errors.
NOTE: There are 1 recipes to be removed from sysroot raspberrypi0, removing...
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION        = "1.32.0"
BUILD_SYS         = "x86_64-linux"
NATIVELSBSTRING   = "universal"
TARGET_SYS        = "arm-poky-linux-gnueabi"
MACHINE           = "raspberrypi0"
DISTRO            = "poky"
DISTRO_VERSION    = "2.2.1"
TUNE_FEATURES     = "arm armv6  vfp arm1176jzfs callconvention-hard"
TARGET_FPU        = "hard"
meta              
meta-poky         
meta-yocto-bsp    = "morty:924e576b8930fd2268d85f0b151e5f68a3c2afce"
meta-raspberrypi  = "morty:5de45f285e15770300f5b496ff16dec5c6c44e4a"

Initialising tasks: 100% |#######################################| Time: 0:00:05
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 2163 tasks of which 2128 didn't need to be rerun and all succeeded.

SDカードの作成

$ sudo dd if=tmp/deploy/images/raspberrypi0/rpi-basic-image-raspberrypi0.rpi-sdimg of=/dev/sdb bs=40M

/dev/sdbはSDカードのデバイス。環境により変更が必要な場合がある。

実行

Poky (Yocto Project Reference Distro) 2.2.1 raspberrypi0 /dev/ttyAMA0           
                                                                                
raspberrypi0 login: 

若干、うちのUSB-TTL変換ケーブルの動作が怪しかったが、無事起動した。 minicomを後から起動すると調子が良いみたいだった。

bash-history-sqliteを使用する

GUI上でBashを使用していると、bash_historyが各端末ごとで共有できず、最後に閉じた端末の履歴のみが保存される。 このため、全てのBashを閉じてしまうと、最後に閉じた端末以外の履歴をさかのぼることができなくなる。

bash-history-sqliteを使用すると、GUI上で動作する全てBashの履歴がSqlite3の1つのDBに保存されるようになる。

ただし、hisotryコマンドを置き換えるものではなく、dbhistry(dbhsit)、dbexecというコマンドが使用できるようになる。

試しにalias history=dbhistとしてみたが、調子が悪い(履歴が保存されない)のでやめた。

依存パッケージのインストール

次のコマンドを使用するためインストールする。

sqlite3以外はすでに導入済みだと思われる。

$ sudo apt-get install -y wget sqlite3 gawk bash

導入方法

ダウンロード

$ git clone https://github.com/thenewwazoo/bash-history-sqlite.git
$ cd bash-history-sqlite

インストール

READMEには

Check out the repo, and add the contents of bash-profile.stub to the end of your ~/.bash_profile.

と書いてあるが、Ubuntu.bash_profileがなく、さらにbash-profile.stubの内容が正しくないため、次のようにする。

$ cat << 'EOF' >> ~/.bashrc

HISTDB="${HOME}/.hist.db"
source ~/.bash-history-sqlite.sh
EOF

次に

Place the bash-history-sqlite.sh script in your $HOME with filename .bash-history-sqlite.sh.

にしたがって、を下記を実行する。

$ mv ./bash-history-sqlite.sh ~/.bash-history-sqlite.sh

実行

履歴の確認

履歴の確認はdbhistory(dbhist)で行なう。

$ dbhist
       1    echo $HISTDB
       2    dbhist
       3    dbhist
       4    dbhist
       5    exit
       6    history
       7    emacs ~/.bashrc
       8    exit
       9    ls
      10    history

検索もできる。

$ dbhist git
     127    git status
     128    git log
     129    git branch
     130    git checkout -b debug
     131    git status

検索はsqlite3のLIKE句の構文を使用できる。

$ dbhist git%status
     108    git status
     119    git status
     125    git status
     127    git status
     131    git status
     138    git status

履歴の実行

過去のコマンドの実行(!123相当)はdbexecで行なう。

$ dbexec 123

meta-raspberrypi mortyでcore-image-satoが起動できない時の対処 その2

先日の記事の続き。

vc4graphicsを有効化した状態でこれをcocopar 5 インチIPSハイビジョンLCD ディスプレイで動かそうとすると、画面が真っ黒になった。

調査したところ、cocoparのLCDのようにEDIDを取得できないデバイスの場合KMSの初期化で弾かれてしまい、画面が表示されなくなることがわかった。

このような場合は、EDIDをどうにかごまかしてカーネルに教えてやることによって、この状況を回避することができる。

800x480の解像度を設定するためのEDIDファイルをカーネルに指定して、core-image-satoを動作させることができるようにmeta-hdmi5inch-rpiを更新した。

ベース環境の取得

$ git clone git://git.yoctoproject.org/poky.git -b morty
$ cd poky
$ git clone git://git.yoctoproject.org/meta-raspberrypi -b morty
$ git clone https://github.com/mickey-happygolucky/meta-hdmi5inch-rpi.git -b morty

今回はmortyブランチで作業する。

oe-init-build-envの読み込み

下記を実行する。

$ cd ~/rpi3
$ source poky/oe-init-build-env

これにより、クロスコンパイルに必要な環境変数が設定され、ビルドディレクトリに移動される。

meta-raspberrypiをビルド対象に追加

次のコマンドを実行する。

$ bitbake-layers add-layer ../poky/meta-raspberrypi
$ bitbake-layers add-layer ../poky/meta-hdmi5inch-rpi

local.confの修正

次の行をlocal.confの先頭の方に追加する。

MACHINE ?= "raspberrypi3"
MACHINE_FEATURES += "vc4graphics"
IMAGE_INSTALL_append = " xf86-input-evdev"
MACHINE_EXTRA_RRECOMMENDS += "linux-firmware-edid-800x480"

COCOPAR_5INCH_HDMI = "1"
KERNEL_DEVICETREE_append = "overlays/ads7846-overlay.dtb"

DL_DIR ?= "${HOME}/work/yocto/downloads"

DL_DIRの行は必要はないが、ダウンロードしたファイルを複数のビルドディレクトリから使いまわせるようにするために設定している。

COCOPAR_5INCH_HDMI = "1"LCDを有効化、overlays/ads7846-overlay.dtbでタッチパネルを有効化している。

xf86-input-evdevがないとマウス(タッチ)が反応しない。

動作確認

bitbakeの実行

$ bitbake core-image-sato

SDカードの作成

$ sudo dd if=./tmp/deploy/images/raspberrypi3/core-image-sato-raspberrypi3.rpi-sdimg of=/dev/sdb bs=40M

/dev/sdbはSDカードのデバイス。環境により変更が必要な場合がある。

実行

mortyのsatoが表示された。

f:id:mickey_happygolucky:20170208013857j:plain

yocto /lib/firmware以下へのファイルの追加

通常のレシピによるインストールではrootfsに反映されない

以前は、各レシピでdo_installFILES_%{PN}/lib/firmwareにファイルを追加すれば、 問題なくrootfsに反映されていたが、oe-coreにlinux-firmware_git.bbが導入されてから、状況は一変した。

linux-firmware以外のレシピからインストールされたファイルが、rootfsに反映されなくなった。

解決策

自分で作成したファームウェア/lib/firmware以下にインストールするにはlinux-firmware_git.bbappendを作成し次のようにPACKAGEを追加する。

FILESEXTRAPATHS_prepend := "${THISDIR}/files:"

SRC_URI_append = " file://myfirm.bin"
PACKAGES =+ "${PN}-myfirm"

FILES_${PN}-myfirm = "  \
 /lib/firmware/myfirm.bin"

do_install_append() {
   install -d ${D}/lib/firmware
   install -m 0644 ${WORKDIR}/myfirm.bin ${D}/lib/firmware/myfirm.bin
}

追加したパッケージはlocal.confもしくはraspberrypi.confなどのconfファイルからMACHINE_EXTRA_RRECOMMENDSなどで追加する必要がある。 bbやbbappendからの追加はうまく行かない。

local.confへ次の行を追加する。

MACHINE_EXTRA_RRECOMMENDS += "linux-firmware-myfirm"

これで/lib/firmware/myfirm.binがインストールされる。

linux-firmwareについて

通常/lib/firmwareに配置されるファイルはプロプライエタリバイナリファイルであるため、オープンソースではないライセンスが付与されている。 yoctoprojectでは、これらを一元に管理するためにlinux-firmwareのレシピですべてを管理するようにしたと推測されるが、経緯は詳しく調べていない。

とはいえ、/lib/firmwareにファイルを追加する場合は、注意が必要である。

meta-raspberrypi mortyでcore-image-satoが起動できない時の対処

素の状態でbitbake core-image-satoで作成したイメージを起動すると、 真っ黒い画面にマウスカーソルのみが表示されるという状態になる。

シリアルコンソールでログインし、/var/log/Xsession.logを表示したところ下記のようになっていた。

$cat Xsession.log 
...(省略)...

** (process:498): WARNING **: Failed to register client: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.SessionManager was not provided by any .service files
Error: No calibratable devices found.
Couldn't open libGL.so.1: libGL.so.1: cannot open shared object file: No such file or directory
Couldn't open libGL.so.1: libGL.so.1: cannot open shared object file: No such file or directory
Couldn't open libGL.so.1: libGL.so.1: cannot open shared object file: No such file or directory
Couldn't open libGL.so.1: libGL.so.1: cannot open shared object file: No such file or directory

libGL.so.1が見つからないらしい。実際にファイルを確認して見ると存在しなかった。

libGL.so.1をどうにかしてみる

libGL.so.1はmesa-glの持ち物であるため、local.confに下記を追加し再度挑戦してみる。

IMAGE_INSTALL_append = " mesa-gl"

これでも/usr/lib/libGL.so.1はインストールされず。

bitbakeした結果を手動でrootfsへコピーしたところ、エラーの状態には変化があった。 しかし、状態は変わらず。

Couldn't open libGL.so.1: libxcb-glx.so.0: cannot open shared object file: No such file or directory
Couldn't open libGL.so.1: libxcb-glx.so.0: cannot open shared object file: No such file or directory
Couldn't open libGL.so.1: libxcb-glx.so.0: cannot open shared object file: No such file or directory
Couldn't open libGL.so.1: libxcb-glx.so.0: cannot open shared object file: No such file or directory

libxcb-glxはX11上でのOpenGLの実行に使用するライブラリなので、vc4graphicsが必須なのではなかろうか。

vc4graphicsを有効にしてみる

local.confに下記を追加。

MACHINE_FEATURES += "vc4graphics"

その後bitbake core-image-satoを実行。

ラズベリーパイ3を起動してみると、画面が表示された!

しかし、マウスカーソルが全く反応しない。

次のように、マウスとの接続に問題がないかを確認してみる。

# cat /dev/input/mouse0 
��H�%���
                 �
��#            �  �
      
        (�(�(�(�(��(�(�8����������

マウスを動かすとゴミが表示されるので、デバイスは問題なく動作している。

X11がデータを解釈できていないということ。

なので、evdev関連のモジュールに不足がないかを確認。

local.confに下記を追加してみる。

IMAGE_INSTALL_append = " xf86-input-evdev"

これで、core-image-satoを作成しなおして、起動すると。。。

動いた!

まとめ

最近のmeta-raspberrypiでX11を動作する場合は、vc4graphicsの有効化が必須らしい。 というか、無効の場合はあまりデバッグされていないのではないか。

また、vc4graphics有効化状態でもxf86-input-evdevを明示的に追加しないとマウスが動かない。

しばらくしたら修正されそうだが。2017/2/2時点ではこのような状態。