macOSでZephyrのmicro:bitデモを動かす

この文章は、[ZephyrRTOS Advent Calendar 2024](https://qiita.com/advent-calendar/2024/zephyr) [^1]の21日目のエントリとして書かれました。

[^1]: https://qiita.com/advent-calendar/2024/zephyr

# はじめに
今回の同人誌では、[Zephyr RTOS 〜 Lチカのその先へ 〜"](https://qiita.com/Corgeek/items/ca4c515ccf556551562f)[^2]などでWindowsやUbuntuでの開発環境の構築に関して、詳しく説明されています。
ここでは、macOSとmicro:bitで試してみたので、報告してみたいと思います。

環境構築に関しては、公式ドキュメントの紹介だけですが、micro:bitでデモを動かす部分を参考にして下さい。

[^2]: https://qiita.com/Corgeek/items/ca4c515ccf556551562f

# Zephyr開発環境の準備
Zephyr公式サイトの[Getting Started Guide](https://docs.zephyrproject.org/latest/develop/getting_started/index.html)[^3]で、macOSタブを選択して表示される手順で問題なく開発環境が構築できます。
というわけで、ここでは詳細は説明しません。

[^3]: https://docs.zephyrproject.org/latest/develop/getting_started/index.html

## micro:bitをJ-Link用にする
SDKでは、J-Linkを経由した書き込みが必要です。
このため、J-Link用のデバイス([J-Link Edu](https://embeddedcomputing.weebly.com/segger-j-link-edu-programmer-debugger.html) [^4]など)が必要になるのですが、micro:bitには以下のようなJ-Link化するファームウエアが用意されています。

- [BBC micro:bit J-Link Upgrade Upgrading the BBC micro:bit DAPLink to J-Link](https://www.segger.com/products/debug-probes/j-link/models/other-j-links/bbc-microbit-j-link-upgrade/) [^5]

導入は、このページの説明の通りに行えば大丈夫です。

::: note warn
**ただし、ここで提供されているファームウエアはv.2.2では使えないようです。v.1.5かv.2.0を用意してください。**
:::

概略は以下の通りです。

- micro:bitをメンテナンスモードで起動します。
  -	リセットボタンを押しながら、電源を投入します。
- ファームウエアのHexファイルの`JLink_OB_BBC_microbit_22-11-16.hex`(v.1.5用)、または、 `JLink_OB_BBC_microbitV2_22-11-15.hex`(**v.2.0用**)を現れたMAINTANANCEフォルダーにコピーします。

[^4]: https://embeddedcomputing.weebly.com/segger-j-link-edu-programmer-debugger.html
[^5]: https://www.segger.com/products/debug-probes/j-link/models/other-j-links/bbc-microbit-j-link-upgrade/

# micro:bit用デモのBuildと実行
micro:bit専用のデモがZephyr SDKの中に3つ含まれています。

- display:	5x5 LED画面に数字、文字、パターンなどを表示します。
- sound:	音を出し、その周波数をボタンで変更します。
- pong:	pongゲームで、マルチプレーヤーにも対応しています。

ボードの定義を確認するには、以下のように`west boards`コマンドを使います。
micro:bitに関しては、`bbc_microbit`(v.1.5)と`bbc_microbit_v2`(v.2系)が利用可能です。

```shell
$ west boards|grep -i micro
micromod
sparkfun_pro_micro_rp2040
bbc_microbit
bbc_microbit_v2
```

## デモのbuild
以下のコマンドでは、micro:bit v.1.5系のコマンドラインで説明しますが、v.2系の場合は`-b`オプションの`bbc_microbit`を`bbc_microbit_v2`に読み替えて下さい。

以下のコマンドで、micro:bitの5x5 LEDに数字や文字、パターンを表示するデモがbuildできます。

```shell
$ west build -p always -b bbc_microbit samples/boards/bbc/microbit/display
```

また、以下のコマンドで、音を出すデモが構築できます。こちらのデモは、スピーカーのないv.1.5では意味がありません。

```shell
$ west build -p always -b bbc_microbit samples/boards/bbc/microbit/sound
```

pongゲームは以下のコマンドで構築できます。
一人用とBluetoothで接続するマルチプレーヤー用を選択して遊べます。

```shell
$ west build -p always -b bbc_microbit samples/boards/bbc/microbit/pong
```

## デモをボードに書き込む
buildが終わった後、ボードに書き込むには、以下のコマンドを実行します。

```shell
$ west flash
```

# blinkyデモを動かす
micro:bit専用のデモは、何も変更しなくても問題なく動作します。

一番基本のBlinkyデモは、`led0`に関する定義などがないため、そのままでは動作しません。
そこで、動作するように変更してみました。
このプログラムでは、micro:bit 5x5 LEDの一左上隅のLEDがblinkするようになっています。
`pixel.row[0] = BIT(0);`部分を書き換えることで、好きな場所のLEDを光らせたり消したりすることが可能です。

以下の二つのファイル(`main.c`と`prj.conf`)を更新することで、buildと実行ができるようになります。

本体のソース`main.c`の変更後のソースは、以下の通りです。

```c:samples/basic/blinky/src/main.c                                          
/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/device.h>

#include <zephyr/display/mb_display.h>

/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   1000

/* Blink for microbit */
void blink(bool led_state){
        struct mb_display *disp = mb_display_get();
        struct mb_image pixel = {};

        if(led_state) {
                pixel.row[0] = BIT(0);
        }
        mb_display_image(disp, MB_DISPLAY_MODE_SINGLE, 250,&pixel, 1);
}

int main(void)
{
        bool led_state = true;

        while (1) {
                blink(led_state);

                led_state = !led_state;
                printf("LED state: %s\n", led_state ? "ON" : "OFF");
                k_msleep(SLEEP_TIME_MS);
        }
        return 0;
}
```

build用の設定ファイル`prj.conf`の変更点は以下の通りです。

```text:samples/basic/blinky/prj.conf
CONFIG_GPIO=y
CONFIG_DISPLAY=y
CONFIG_MICROBIT_DISPLAY=y
```

::: note info
今回は、簡単のために、アプリケーション側で直接micro:bitのMatrix LEDを操作する形で対応しましたが、本来はmicro:bitのDTSファイルにled0などの定義を行う方が汎用的で望ましい対応方法だと思います。
:::

# おわりに
macOSで、Zephyr SDKを使ってmicro:bitでデモを動作させてみました。

VSCodeを使った解説の記事[nRF Connect SDK FundamentalsでZephyrを試してみる: micro:bit編](https://qiita.com/610t/items/c6cc9cc32ed16f709f13) [^6] (本誌に収録)と合わせて読んでいただけると幸いです。

[^6]: https://qiita.com/610t/items/c6cc9cc32ed16f709f13

# 参考資料:Zephyr Blogのmicro:bit関連記事
micro:bitでの開発のよりすすんだトピックスに関しては、以下のZephyr Blogの記事が参考になると思います。
- [Zephyr and the BBC Microbit V2 Tutorial Part 1 : GPIO](https://zephyrproject.org/zephyr-and-the-bbc-microbit-v2-tutorial-part-1-gpio/)[^7]
- [Zephyr and the BBC Microbit V2 Tutorial Part 2: Analogue input and output](https://zephyrproject.org/zephyr-and-the-bbc-microbit-part-2/) [^8]
- [Zephyr and the BBC Microbit V2 Tutorial Part 3: I2C](https://zephyrproject.org/zephyr-and-the-bbc-microbit-v2-tutorial-part-3-i2c/) [^9]
- [Zephyr and the BBC Microbit V2 Tutorial Part 4: BLE](https://zephyrproject.org/zephyr-and-the-bbc-microbit-v2-tutorial-part-4-ble/) [^10]

[^7]: https://zephyrproject.org/zephyr-and-the-bbc-microbit-v2-tutorial-part-1-gpio/
[^8]: https://zephyrproject.org/zephyr-and-the-bbc-microbit-part-2/
[^9]: https://zephyrproject.org/zephyr-and-the-bbc-microbit-v2-tutorial-part-3-i2c/
[^10]: https://zephyrproject.org/zephyr-and-the-bbc-microbit-v2-tutorial-part-4-ble/