みつきんのメモ

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

yocto raspberrypi3でmorty

ちょっと時間が経ってしまったが、yocto 2.2(morty)がリリースされたので、raspberrypi3で動かしてみる。

ベース環境の取得

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

meta-raspberrypiはまだブランチがないのでmasterを使用する。

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

下記を実行する。

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

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

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

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

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

local.confの修正

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

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

動作確認

bitbakeの実行

$ bitbake rpi-basic-image

DISTRO_VERSIONが2.2になっていることがわかる。

Build Configuration:
BB_VERSION        = "1.32.0"
BUILD_SYS         = "x86_64-linux"
NATIVELSBSTRING   = "Ubuntu-16.10"
TARGET_SYS        = "arm-poky-linux-gnueabi"
MACHINE           = "raspberrypi3"
DISTRO            = "poky"
DISTRO_VERSION    = "2.2"
TUNE_FEATURES     = "arm armv7ve vfp thumb neon vfpv4 callconvention-hard cortexa7"
TARGET_FPU        = "hard"
meta              
meta-poky         
meta-yocto-bsp    = "morty:dc8508f609974cc99606b9042bfa7f870ce80228"
meta-raspberrypi  = "master:17a6933adfc7bdf4e7e18dcc9d59e35718620fd4"

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

Summary: There was 1 WARNING message shown.

SDカードの作成

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

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

実行

f:id:mickey_happygolucky:20161115235426j:plain

無事起動した。

yocto meta-raspberrypiでVC4 graphics driverを試す

このように、RaspbianではVC4のgalliumドライバが使用できていたのだが、 最近、meta-raspberrypiでもこの対応が入ったので試してみる。

local.confにMACHINE_FEATURES += "vc4graphics"の行を追加することで、galliumドライバが有効になり、X11環境からOpenGLを使用できるようになる。

これによって、いままで使用できなかった、GLUTやGLFWが使用できるようになる。(かもしれない)

今回はes2gear_x11で歯車を表示するところまで確認する。

ベース環境の取得

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

特にポリシーはないが、今回はmasterブランチで作業する。

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

下記を実行する。

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

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

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

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

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

local.confの修正

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

MACHINE ?= "raspberrypi3"
MACHINE_FEATURES += "vc4graphics"
IMAGE_INSTALL_append = " mesa-demos"

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

mesa-demosを追加インストールしているは、歯車を表示するため。

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

動作確認

bitbakeの実行

今回はX11OpenGLが使用できるようになったかを確かめたいので、core-image-satoを作成する。

$ 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カードのデバイス。環境により変更が必要な場合がある。

実行

Linux起動後、ターミナルを起動しes2gears_x11を実行してみる。

歯車が表示された。

raspberrypi3 yoctoでSSD1306 OLEDディスプレイを動かす

アマゾンで安価に入手できるOLEDディスプレイを購入した。

I2Cで、VCC、GND、SCL、SDAの4本のみの結線で使用できる。 制御用のICはSSD1306とのこと。

このデバイスはArduinoなどの電子工作用となっているが、意外とラズベリーパイでの動作報告が見当たらない。 そこでこれを動かしてやろうと考えた。

Linuxにはssd1307fb.cというドライバがあり、これがSSD1306にも対応している。

しかし、実際に動かそうとすると意外と問題があり、カーネル4.4ではLEDが光らなかったり、表示位置がずれていたりしたので、それらは力技で直した。

yoctoの基本環境およびmeta-raspberrypi

基本環境のダウンロード

$ mkdir ~/rpi3
$ cd ~/rpi3
$ git clone git://git.yoctoproject.org/poky.git
$ cd ~/rpi3/poky
$ git clone git://git.yoctoproject.org/meta-raspberrypi

meta-rpi-ssd1306

meta-rpi-ssd1306をダウンロード。

$ cd ~/rpi3/poky
$ git clone https://github.com/mickey-happygolucky/meta-rpi-ssd1306.git

環境変数を設定

下記を実行してbitbakeの実行に必要な環境変数を設定する。

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

ビルド対象に追加

bitbake-layerでビルド対象に追加。

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

local.conf

今回は、SSD1306のディスプレイをコンソールとして使用するために次の行を追加する。

MACHINE ?= "raspberrypi3"

ENABLE_I2C = "1"
KERNEL_DEVICETREE_append = " overlays/ssd1306fb.dtbo"

OLED_CONSOLE = "1"

bitbake実行

$ bitbake rpi-basic-image

イメージの書き込み

meta-raspberrypiではrpi-sdimgとしてSDカードのイメージが生成されるので、これをddコマンドで書き込む。

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

/dev/sdbは環境によってはsdbだったりsdcだったりするので適宜変更する。 内蔵HDDの追加など行ってなければ大抵はsdbとなる。

動作確認

f:id:mickey_happygolucky:20161007024414j:plain

OLEDにコンソールが表示されている。

raspberrypi3 yoctoでkernel4.8を試す

インターフェース11月号の記事で、linuxカーネルのバージョン4.8からラズベリーパイ3の64ビットが対応されるという情報があった。 筆者が紹介したカーネルは、Electron752さんが4.5および4.6のカーネルに64ビット対応したものだったので、今回はもともと64ビット対応されているというカーネル4.8を試してみようと思う。

ただし、バニラカーネルだと自前でコンフィグレーションなどが必要になるので、ラズベリーパイのカーネルrpi-4.8.yブランチを使用する。

使用するブランチ

meta-raspberrpyはkrogothブランチを持っていないため、pokyのmasterブランチを追従している。 masterブランチはバージョンの移り変わりが激しく、時間が経つと再現性が乏しくなるという欠点がある。 そのため、なるべくその時点の最新のリリースバージョンのブランチ(今はkrogoth)を使用するのだが、最近masterブランチが破壊的な修正が入ってしまった。その影響で現時点(10/3)ではkrogothのpoky(oe-core)とmasterのmeta-raspberrypiの組み合わせではビルドできなくなっている。 これは非常に残念なので、meta-raspberrypiにはkrogothブランチを切って欲しいと思う。 特定のコミットでcheckoutするという回避策もあるにはあるのだが。

今回は、このような事情からpoky(oe-core)もraspberrypiもmasterブランチで作業する。

環境のダウンロード

poky

次のコマンドを実行し、pokyの環境をダウンロードする。作業は~/rpi3で行う。

$ mkdir ~/rpi3
$ cd ~/rpi3
$ git clone git://git.yoctoproject.org/poky.git

先述の通りmasterブランチで作業する。

meta-raspberrypi

meta-raspberrypiをダウンロードする。

$ cd ~/rpi3/poky
$ git clone git://git.yoctoproject.org/meta-raspberrypi

こちらもmasterブランチで作業する。

meta-rpi3-aarch64

インターフェース2016年11月号でも紹介させてもらった64ビット環境を作成するためのレイヤをダウンロードする。 ここでは、カーネル4.8に対応したrpi-4.8.yブランチを取得する。

$ git clone https://github.com/mickey-happygolucky/meta-rpi3-aarch64.git -b rpi-4.8.y

ビルド環境の設定

同じみのoe-init-build-envを読み込み、bitbakeに必要な環境変数などの設定を行う。 meta-rpi3-aarch64はコンフィグレーションファイルのテンプレートを提供しているので、次のようにする。

$ TEMPLATECONF=meta-rpi3-aarch64/conf/template source poky/oe-init-build-env build64

これで、local.confbblayers.confが設定済みの状態で作成される。

自動的にbuild64ディレクトリに移動される。

bitbakeの実行

bitbakeを実行しイメージを作成する。

$ bitbake rpi-basic-image

SDカードの作成

ddコマンドでSDカードにイメージを書き込む。

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

/dev/sdbはSDカードのデバイス。各自環境によって変化する可能性があるので注意。

実行

f:id:mickey_happygolucky:20161003235046j:plain

カーネルが4.8でaarch64になっている。

raspberrypi3 yocto PiTFT3.5を赤く染める(SDKの作成)

先日の記事の最後で、「前回の記事で作成したfirst_window.cのコンパイル結果を実行すると、PiTFT35が赤く染まる」と書いたが、具体的な手順について解説する。

まずはじめに環境を整える必要がある。

  1. PiTFT35の手順でmeta-pitft35-rpiのビルド環境を作成
  2. rpi-fbcpの手順でmeta-rpi-fbcpの環境を作成

次にrpi-fbcpの環境をベースにSDKを作成する。

SDKの作成

bitbakeではLinuxイメージを作成するためにクロスコンパイルを行っているが、それとは別に作成されたLinuxの上で動作するアプリケーションを作成するためのクロスコンパイラ(ツールチェイン)を作成することができる。

次の手順で作成する。

$ cd ~/rpi3
$ source poky/oe-init-build-env build_pitft35
$ bitbake core-image-sato -c populate_sdk

SDKインストーラpoky-glibc-x86_64-core-image-sato-cortexa7hf-neon-vfpv4-toolchain-2.1.1.shbuild_pitft35/tmp/deploy/sdkにできあがる。

これを実行し、インストールする。

$ cd tmp/deploy/sdk
$ ./poky-glibc-x86_64-core-image-sato-cortexa7hf-neon-vfpv4-toolchain-2.1.1.sh
Poky (Yocto Project Reference Distro) SDK installer version 2.1.1
=================================================================
Enter target directory for SDK (default: /opt/poky/2.1.1): 
You are about to install the SDK to "/opt/poky/2.1.1". Proceed[Y/n]? 

デフォルトの設定では/opt/poky/2.1.1SDKがインストールされる。

SDKの使用

bitbake実行したシェルとは別のシェルを開いて、次のコマンドを実行する。

$ source /opt/poky/2.1.1/environment-setup-cortexa7hf-neon-vfpv4-poky-linux-gnueabi

これでクロスコンパイルのために必要な設定が環境変数に設定される。たとえば、次のようにしてみると、クロスコンパイル用のコンパイラおよびビルドオプションが確認できる。

$ echo $CC
arm-poky-linux-gnueabi-gcc -march=armv7ve -marm -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=/opt/poky/2.1.1/sysroots/cortexa7hf-neon-vfpv4-poky-linux-gnueabi

上記はC言語のためのコマンドで、C++の場合は次のようにする。

$ echo $CXX
arm-poky-linux-gnueabi-g++ -march=armv7ve -marm -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=/opt/poky/2.1.1/sysroots/cortexa7hf-neon-vfpv4-poky-linux-gnueabi

sourceコマンドによる環境変数の読み込みは、すでに読み込まれているシェルの上で実行するとエラーになる。

hello world

例えば、hello worldのプログラムを作成し、コンパイルを実行してみる。

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("hello world\n");
    return 0;
}
$ $CC ./hello.c -ohello

$CC環境変数が展開されarm-poky-linux-gnueabi-gccコマンドによりコンパイルが実行され、helloというファイルがされる。

次のようにして、生成されたファイルを確認する。

$ file ./hello
./hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=add3753e8732c8cec29a4b0203819bdc78aed85c, not stripped

ARMのバイナリが生成されていることがわかる。

このhelloファイルをラズベリーパイ上で実行すると、hello worldと文字が出力される。

コンパイル済みバイナリをラズベリーパイへコピー

方法はいくつかあるが、筆者がよく行うのは次の2つのうちどちらか。

  1. SDカードをPCにマウントし、/home/rootなどの適当な場所へコピーする。
  2. LAN環境へ接続し、scpコマンドで転送する。

環境が出来上がってしまえばscpのほうが手軽だと思う。

PiTFT3.5を赤く染める

PiTFTを赤く染める手順をSDKがインストールされた後の手順から示す。

ソースのダウンロード

先日のOpenGLESソースコードをダウンロードする。

作業は~/fisrt_windowで行う。

$ mkdir ~/first_window
$ cd ~/first_window
$ git clone https://gist.github.com/1650444ca53d819474c9c69ed2604abb.git

ビルド

sourceでSDK環境変数を読み込み、ビルドを実行する。

$ cd 1650444ca53d819474c9c69ed2604abb
$ source /opt/poky/2.1.1/environment-setup-cortexa7hf-neon-vfpv4-poky-linux-gnueabi
$ cmake .
$ make

出来上がったfirst_windowファイルをfbcpのLinuxイメージを書き込んだラズベリーパイの上で実行すると、PiTFT3.5が赤く染まる。

f:id:mickey_happygolucky:20160919153814j:plain

raspberrypi3 yoctoでfbcp

PiTFTなどSPI接続のLCDではGPUを使用した描画処理は行えない。 そのためOpenGLESなどのアプリケーションはPiTFTでは使用できない。

しかし、fbcpを使用するとこの問題が解決できる。

fbcpは「Framebuffer Copy」のことで、GPUに描画されているデータをSPI側のフレームバッファにコピーするというアプリケーション。

実装を見ると、dispmanxでLCDバイス(HDMIへの出力)を開いて、必要に応じて縮小し/dev/fb1に転送している。 このアプリケーションは、実はすでに有名なようでちょっと筆者としては出遅れた感がある。

以前、PiTFT3.5でQML(Quick2)アプリケーションが実行できない理由の時に「2.2インチや2.8インチのPiTFTではGPUを使用せずにOpenGLを描画することができる」というところでリンクを紹介したがこの内容も実はfbcpを使用することだった。 リンク先で「The 3.5" PiTFT (480x320) is NOT recommended for this project 」とされていたので深追いしなかったが、実は意外と使えるということが今回の実験でわかった。

とりあえず、yoctoprojectで使用できるようにmeta-rpi-fbcpを作成した。

環境の作成

raspberrypi3 yoctoでPiTFT35の環境をベースに作業を行う。

meta-rpi-fbcpのダウンロード

gitでmeta-rpi-fbcpを取得する。

$ cd ~/rpi3/poky
$ git clone https://github.com/mickey-happygolucky/meta-rpi-fbcp.git

ビルド環境の設定

oe-init-build-envを読み込む。

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

自動的にbuild_fbcpに移動される。

レイヤの設定

ビルド対象にはすでに、meta-raspberrypimeta-pitft35-rpiは追加されているので、次のコマンドでmeta-rpi-fbcpを追加する。

$ bitbake-layers add-layer ../poky/meta-rpi-fbcp

conf/local.conf

local.confからRPI_PITFT35 = "1"の行を削除し、RPI_PITFT35_FBCP = "1"を追加する。

カーネル4.1の場合だと次のようになる。

MACHINE ?= "raspberrypi3"
DL_DIR ?= "${TOPDIR}/../downloads"

KERNEL_DEVICETREE_append = " overlays/pitft35-resistive-overlay.dtb"
RPI_PITFT35_FBCP = "1"

設定が衝突するため、RPI_PITFT35 = "1"RPI_PITFT35_FBCP = "1"は同時に指定できない。

動作確認

この環境では、PiTFT35のタッチパネルは無効化される。 今回は、X11環境で動作を確認する。

ビルド

$ 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カードデバイスは環境によって変化することがあるのでfdisk -lなどで確認すること。

このままではただsatoのGUI環境が表示されるだけなので、fbcpなしの環境と比較するとタッチパネルが無効化されただけのように見えるが、

前回の記事で作成したfirst_window.cコンパイル結果を実行すると、PiTFT35が赤く染まるようになっている。

raspberrypi3 yoctoでPiTFT35

以前PiTFT35をyoctoで動作させるためにmeta-pitft35-rpiを作成した^1が、 最近のmeta-raspberrypiでは動作しなくなっていた。

一度、リポジトリの方に問い合わせが来たが、その人がうちのパッチをまとめて(勝手に)meta-raspberrypiにPRを送っていた。 meta-raspberrypiに取り込まれるならもうmeta-pitft35-rpiも用済みかと思ってしばらく放置していたのだが、そのパッチ取り込まれるようすがなく、送ったPRの内容を確認すると結構いい加減な対応だったので、 とりあえずmeta-pitft35-rpiをRPi3(というかカーネル4.1、4.4)に対応させることにした。

ついでにcore-image-satoではキャリブレーションデータが固定だったので、イメージを書き込んで初回など、キャリブレーションデータが存在しない場合、OS起動時にキャリブレーションが実行されるように修正した。

使用方法は変更なし。

環境の作成

作業は~/rpi3で行う。

pokyとmeta-raspberrypiのダウンロード

pokyのブランチはkrogothを使用する。 meta-raspberrypiはkrogothブランチがないので、masterブランチを使用する。

$ mkdir ~/rpi3
$ cd ~/rpi3
$ git clone git://git.yoctoproject.org/poky.git -b krogoth
$ cd ~/rpi3/poky
$ git clone git://git.yoctoproject.org/meta-raspberrypi

meta-pitft35-rpiのダウンロード

meta-pitft35-rpiをダウンロードする。

$ git clone https://github.com/mickey-happygolucky/meta-pitft35-rpi.git

ビルド環境の設定

次のコマンドでoe-init-build-envを読み込む。

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

自動的ににbuild_pitft35に移動される。

レイヤの設定

bitbake-layersコマンドでビルド対象にmeta-raspberrypimeta-pitft35-rpiを追加。

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

conf/local.conf

エディタでconf/local.confを修正する。 カーネル4.1と4.4で若干異なる。

カーネル4.1

バージョン4.1のカーネルを使用する場合はlocal.confに次を追加する。

MACHINE ?= "raspberrypi3"
DL_DIR ?= "${TOPDIR}/../downloads"

KERNEL_DEVICETREE_append = " overlays/pitft35-resistive-overlay.dtb"
RPI_PITFT35 = "1"

PiTFT35のための設定はKERNEL_DEVICETREE_appendRPI_PITFT35MACHINEでRPi3向けのイメージを指定。 DL_DIRはbitbake時にダウンロードされるデータを格納するディレクトリの指定。 デフォルトではビルドディレクトリごとにダウンロードされるが、階層をひとつ上げることで他のビルドディレクトリと共用している。

カーネル4.4

バージョン4.4のカーネルを使用する場合はlocal.confに次を追加する。

MACHINE ?= "raspberrypi3"
DL_DIR ?= "${TOPDIR}/../downloads"

PREFERRED_VERSION_linux-raspberrypi = "4.4.%"

KERNEL_DEVICETREE_append = " overlays/pitft35-resistive-overlay.dtb"
RPI_PITFT35 = "1"

PREFERRED_VERSION_linux-raspberrypiカーネルバージョンを指定している。 それ以外は4.1と同じ。

動作確認

コンソール環境とX11環境を作成

コンソール環境

次でビルド。

$ bitbake rpi-basic-image

次でSDカードに書き込み

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

/dev/sdbはSDカードデバイスの指定で環境によっては/dev/sdcとかになるのでfdisk -lなどで確認する必要がある。

X11環境

ビルド。

$ bitbake core-image-sato

SDカードに書き込み

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