MicroPython Zephyrポートのビルドを試してみる

# はじめに

[MicroPython Zephyrポートのドキュメント和訳](https://micropython-docs-ja.readthedocs.io/ja/latest/zephyr/quickref.html)の和訳を進めながら Zephar ポートのビルドを試してみました。

# Zephyr とは

[Wikipedia](https://ja.wikipedia.org/wiki/Zephyr_(%E3%82%AA%E3%83%9A%E3%83%AC%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0))参照。

# ビルド環境の準備

ビルド方法については[ここ](https://github.com/micropython/micropython/blob/master/ports/zephyr/README.md)に記載がありますが、まずは Zephar の開発環境を用意します。

[ここ](https://docs.zephyrproject.org/latest/develop/getting_started/index.html)に記載のとおり、ホストOSに合わせて Zephyr の環境をインストールします。

ここで注意するのは、[ここ](https://github.com/micropython/micropython/blob/master/ports/zephyr/README.md)にも記載されているとおり、Zephyr の v3.1.0 にすることです。最新をインストールしたら MicroPython ビルドでエラーになりました。

# サポートされているボード

この記事の執筆時点でサポートされているボードは以下のものです。

* [96Boards Carbon](https://docs.zephyrproject.org/latest/boards/arm/96b_carbon/doc/index.html)
* [BBC micro:bit V2](https://docs.zephyrproject.org/latest/boards/arm/bbc_microbit_v2/doc/index.html)
* [ST Disco L475 IOT01](https://docs.zephyrproject.org/latest/boards/arm/disco_l475_iot1/doc/index.html)
* [NXP FRDM-K64F](https://docs.zephyrproject.org/latest/boards/arm/frdm_k64f/doc/index.html)
* [NXP FRDM-KW41Z](https://docs.zephyrproject.org/latest/boards/arm/frdm_kw41z/doc/index.html)
* [NXP MIMXRT1050-EVK](https://docs.zephyrproject.org/latest/boards/arm/mimxrt1050_evk/doc/index.html)
* [NXP MIMXRT685-EVK](https://docs.zephyrproject.org/latest/boards/arm/mimxrt685_evk/doc/index.html)
* [ST Nucleo H743ZI](https://docs.zephyrproject.org/latest/boards/arm/nucleo_h743zi/doc/index.html)
* [ST Nucleo WB55RG](https://docs.zephyrproject.org/latest/boards/arm/nucleo_wb55rg/doc/nucleo_wb55rg.html)
* [ARM Cortex-M3 Emulation (QEMU)](https://docs.zephyrproject.org/latest/boards/arm/qemu_cortex_m3/doc/index.html)
* [X86 Emulation (QEMU)](https://docs.zephyrproject.org/latest/boards/x86/qemu_x86/doc/index.html)
* [reel board](https://docs.zephyrproject.org/latest/boards/arm/reel_board/doc/index.html)
* [OpenISA VEGAboard](https://docs.zephyrproject.org/latest/boards/riscv/rv32m1_vega/doc/index.html)

この中で手持ちのものでは[BBC micro:bit V2](https://docs.zephyrproject.org/latest/boards/arm/bbc_microbit_v2/doc/index.html)があったので、これ用にビルドして試してみることにしました。

# ビルドを試す

MIcroPython のソースコードを GitHub からクローンします。

```bash
$ git clone https://github.com/micropython/micropython.git
```

準備で用意しておいた zephyrproject のディレクトリに移動します。

```bash
$ cd <zepherprojectのディレクトリ>
```

次を実行することでビルドが始まります。

```bash
$ west build -b bbc_microbit_v2 <micropythonソースコードのディレクトリ>/ports/zephyr
```

ビルドが完了したら、micro:bit V2 をボスとPCのUSBに接続して次を実行することで、MicroPython ファームウェアが micro:bit V2 に転送されます。

```bash
$ west flash
```

# 実行してハマったこと

mpremote コマンドで REPL に入ります。

```bash
$ mpremote
```

無事に REPL に入れました。

![スクリーンショット 2023-12-10 12.36.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106817/bb419f19-9db5-cf86-2fa5-f9b820f39416.png)

試しにLチカを試してみます。

Zephyr ポートの GPIO ピンの指定方法は特殊で、ポートとピン番号のペアで指定します。
この値がZephyrのドキュメントを調べてもよくわからなかったのですが、[これ](https://github.com/zephyrproject-rtos/zephyr/blob/main/boards/bbc/microbit_v2/bbc_microbit_v2.dts)の `edge_connector: connector` 定義から察するに次のように指定すればよさそうです。

* P0: ("GPIO_0", 2)
* P1: ("GPIO_0", 3)
* P2: ("GPIO_0", 4)

これに基づいて、P0 に繋いだ LED を点滅させるスクリプトを作成しました。

```python
from time import sleep_ms
from machine import Pin

LED = Pin(("GPIO_0", 2), Pin.OUT)
while True:
    LED.value(1)
    sleep_ms(500)
    LED.value(0)
    sleep_ms(500)
```

いざ、スクリプトを mpremote で書き込もうとすると OSError: 19 が発生します。REPLで挙動を調べてみると、どうやら、そもそも書き込み可能なファイルシステムが無いようです。

[ここ](https://micropython-docs-ja.readthedocs.io/ja/latest/zephyr/quickref.html#flash-area)の記載から察するに、自分でフラッシュ領域のファイルシステムを作らねばならないのかと想像しました。

ところが、FlashArea クラスが存在しない！ フラッシュ領域が使えるようなビルド設定になっていなかったようなのです。他のボードのビルド設定を参考にダメもとで、[bbc_microbit_v2.conf](https://github.com/micropython/micropython/blob/master/ports/zephyr/boards/bbc_microbit_v2.conf)に以下を追加しました。

```
# Flash drivers
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y
```

これで再ビルドしたところ FlashArea クラスが使えるようになりました。

以下を REPL 上で実行して、ファイルシステムを作成します。サイズは何が適切な値かわからなかったので、とりあえずドキュメントの例示のとおりにしています。

```python
import os
from zephyr import FlashArea

block_dev = FlashArea(FlashArea,STORAGE, 4096)
os.VfsLfs2.mkfs(block_dev)
os.mount(block_dev, '/flash')
```

ファイルシステムができたので、先ほどのLチカスクリプトを書き込んで実行してみました。やっと実行できました。

![IMG_7212.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106817/ff7d9cd1-c4d7-3377-478e-7ac2e0a8f4d4.jpeg)

# おわりに

ビルドまではすんなりいけたものの、Lチカまで想像以上に手がかかってしまいました。まあ、ボードが直接MicroPythonでサポートされているのであれば、わざわざ Zephyr ポートに手を出すこともないのですが、ドキュメント和訳できた記念にやってみました。