はじめに
YoctoでZephyrをビルドできるっぽいことは知っていたが、試したことがなかったのでやってみる。
使用するバージョンはhardknott
構築手順
ソース取得
下記のコマンドでソースを取得する。
$ mkdir -p mb-hardknott && cd mb-hardknott $ git clone git://git.yoctoproject.org/poky.git -b hardknott
環境変数設定
$ source poky/oe-init-build-env build
自動的にビルドディレクトリに移動される。 これで、bitbake関連のツールが使用可能になる。
レイヤ追加
下記のコマンドでビルド対象にmeta-arm
とmeta-zephyr
を追加する。
$ bitbake-layers layerindex-fetch meta-arm meta-zephyr
複数のレイヤを一度に指定することもできる。
レイヤ | 目的 |
---|---|
meta-arm | MACHINEでmicrobit-v1を使用するため |
meta-zephyr | Zephyrをビルドするため |
local.confの修正
MACHINEをmicrobit-v1
に設定する。
MACHINE = "microbit-v1" DL_DIR ?= "${TOPDIR}/../downloads"
ビルド
hello worldをビルドしてみる。
$ bitbake zephyr-helloworld
build/tmp/deploy/images/microbit-v1
以下にビルド結果のelfが配置される。
- zephyr-helloworld-image-microbit-v1.elf
- zephyr-helloworld-image-microbit-v1.qemuboot.conf
- zephyr-helloworld-microbit-v1-20210826075435.qemuboot.conf
- zephyr-helloworld.elf
プログラム本体はzephyr-helloworld.elf
。
Linuxをビルド
ためしにcore-image-baseをビルドしようとしてみる。
$ bitbake-layers show-layers NOTE: Starting bitbake server... layer path priority ========================================================================== meta /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta 5 meta-poky /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-poky 5 meta-yocto-bsp /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-yocto-bsp 5 meta-arm-toolchain /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-arm/meta-arm-toolchain 5 meta-oe /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-openembedded/meta-oe 6 meta-python /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-openembedded/meta-python 7 meta-arm /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-arm/meta-arm 5 meta-zephyr /home/mickey/work/yocto/x86-hardknott/mb-hardknott/poky/meta-zephyr 6 mickey@yocto-build:~/work/yocto/x86-hardknott/mb-hardknott/build$ vim ./conf/local.conf mickey@yocto-build:~/work/yocto/x86-hardknott/mb-hardknott/build$ bitbake core-image-base Loading cache: 100% | | ETA: --:--:-- Loaded 0 entries from dependency cache. Parsing recipes: 100% |###############################################################| Time: 0:00:34 Parsing of 2123 .bb files complete (0 cached, 2123 parsed). 3398 targets, 180 skipped, 0 masked, 0 errors. NOTE: Resolving any missing task queue dependencies ERROR: Nothing PROVIDES 'virtual/kernel' linux-yocto PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE) linux-dummy PROVIDES virtual/kernel but was skipped: incompatible with host arm-poky-eabi (not in COMPATIBLE_HOST) linux-yocto-rt PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE) linux-yocto-tiny PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE) linux-arm64-ack PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE) linux-yocto-dev PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE) linux-yocto PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE) linux-yocto-tiny PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE) linux-yocto-rt PROVIDES virtual/kernel but was skipped: incompatible with machine microbit-v1 (not in COMPATIBLE_MACHINE) ERROR: Required build target 'core-image-base' has no buildable providers. Missing or unbuildable dependency chain was: ['core-image-base', 'virtual/kernel'] Summary: There were 2 ERROR messages shown, returning a non-zero exit code.
非対応のマシンということでちゃんとエラーになった。
エミュレータ(qemu)で実行
下記のようにするとqemuでプログラムを実行することができる。
$ runqemu (... snip ...) *** Booting Zephyr OS build zephyr-v2.5.0 *** Hello World! qemu_cortex_m0
ssh越しなどで、うまく文字列が表示されない場合は下記のようにオプションを渡して、シリアルの出力先を標準出力などに変えてやると、うまく行くことがある。
$ runqemu qemux86 qemuparams="-serial mon:stdio"
実機に書き込む
micro:bitの実機にプログラムを書き込む場合は、elfからbinary形式に変換する必要がある。
$ cd tmp/deploy/images/microbit-v1 $ arm-none-eabi-objcopy zephyr-helloworld.elf zephyr-helloworld.bin -O binary
micro:bitをUbuntu 20.04のマシンににUSBで接続すると、/media/mickey/MICROBIT/
として見えるようになる。
変換したbinary形式のファイルを下記のようにmicro:bitにコピーすると自動的リセットがかかり、新しいプログラムが読み込まれる。
cp ./zephyr-helloworld.bin /media/mickey/MICROBIT/
micro:bitのUSB-UARTは/dev/ttyACM0
として見えているので、minicomなどで開く。
minicom -D /dev/ttyACM0
この状態でmicro:bitのリセットボタンを押すと下記のように出力される。
*�*** Booting Zephyr OS build zephyr-v2.5.0 *** Hello World! qemu_cortex_m0
リセット直後の出力にゴミが入るが、プログラムは正しく動いているようだ。
バイナリファイルについて
実際のところ、bitbakeの結果としてzephyr.binも出来上がっている。
しかし、zephyr-hellworld.bbから読み込まれるzephyr-sample.inc
で定義されているdo_deploy
タスクが
下記のようにelfのみをコピーするようになっているので、binは放置されているようだ。
do_deploy () { install -D ${B}/zephyr/${ZEPHYR_MAKE_OUTPUT} ${DEPLOYDIR}/${PN}.elf }
まとめ
Yocto Projectを使用してZephyrのmicro:bit向けバイナリをビルドすることができた。 生成されたバイナリはqemuでも実機でも動作することが確認できた。
実際Zephyrを直接ビルドするよりも、bitbakeのほうが時間かかる。 bitbakeでツールチェインやzephyrのカーネルなど、すべて構築されるのでそこはメリットと言えるかもしれない。