M5StickVでマルチブートする

# はじめに

[Maixduinoでマルチブートする①](https://qiita.com/fukuebiz/items/f5ee98dbd1ab5055a50b)、[Maixduinoでマルチブートする②](https://qiita.com/fukuebiz/items/e1170a8e798c20ac1feb)のM5StickV版になります。詳細は上記の記事をご覧ください。

M5StickVのフラッシュメモリは16Mバイトあって通常は使わない領域がたくさんあります。loborisさんが作成したブートローダー[Kboot](https://github.com/loboris/Kboot)を使用していくつかのアプリを入れて切り替えて使おうというお話です。でも、MaixPyではなく、Arduino、Kendryte Standard SDK開発環境でのアプリケーション向けです。

# 準備

### Ktool

フラッシュの書き込みに[Ktool](https://github.com/loboris/ktool)を使用します。ktool.pyをダウンロードしてください。

### ブートセレクター（Bootselector）

ソースは[こちら](https://github.com/fukuen/m5stickv-bootselector)


### Kbootの調整

Kbootは起動時にブート構成（インデックス）を読み込み、最初のアクティブなアプリを読み込んで起動します。デフォルトでは、起動時にK210のIO18(18pin)をGNDにするとアプリの一覧を表示して、シリアル接続のコンソールからアプリを選択することができます。

M5StackVはIO18が端子に出ていないので、代わりにボタンBのIO37を使います。その場合、bootloader_hiのソース50行目の値を修正してリコンパイルします。

また、シリアルコンソールから操作するのではなく、ボタンBを選択した場合にデフォルトアプリ（Bootselector）を起動するようにします。

```c++:main.c
// Constants
/*
 * Pin used to enter interactive mode and request the user
 * to select which application to load
 * Any valid and not used K210 gpio can be used except gpio#16 (0 ~ 15 & 17 ~ 47)
 */
#define BOOT_PIN            18 <-- ここを37に修正する
#define GPIO_KEY            2

...中略...

    else if (boot_pin == 0) {
        // === Interractive mode ===
        // Check boot pin again
        boot_pin = gpiohs_get_pin(GPIO_KEY);
        if (boot_pin == 0) {
/* ここからコメントアウト
            // ** request user to select the application to run
            LOG("\nSelect the application number to load [");
            for (i = 0; i < BOOT_CONFIG_ITEMS; i++) {
                if (available_apps[i]) {
                    LOG(" %u,", i);
                }
            }
            LOG(" d=default ] ? ");
            while (1) {
                char_in = rom_getchar();
                if ((char_in == 'd') || (char_in == 'D')) {
                    // use default application
                    app_flash_start = DEFAULT_APP_ADDR;
                    break;
                }
                else {
                    char_in -= 0x30;
                    if ((char_in >= 0) && (char_in < BOOT_CONFIG_ITEMS)) {
                        if (available_apps[char_in]) {
                            get_params(char_in);
                            // get application's size and address in Flash
                            app_size = flash2uint32(cfg_address+1);
                            app_flash_start = cfg_address;
                            char_in += 0x30;
                            break;
                        }
                    }
                    char_in += 0x30;
                    LOG("%c? ", char_in);
                }
            }
            LOG("%c\n\n", (char)char_in);
*/
        // ボタンBを選択した場合にデフォルトアプリを起動する
        LOG("\nRunning default application\n");
        // use default application
        app_flash_start = DEFAULT_APP_ADDR;
        }
    }

```

### MicroPython

MaixPy、LoborisのMicroPythonなどをダウンロードしてください。

### フラッシュの書き込み

Kbootとbootselectorのコンパイル済のパッケージを [こちら](https://github.com/fukuen/m5stickv-bootselector/releases/download/v0.1/m5stickv.kfpkg) からダウンロードしてください。上記のbootloaderとkbootについてはスキップできます。

```bash:
# まずはこれ（bootloader_lo.bin bootloader_hi.bin, config.bin, default.bin）
./ktool.py -B goE m5stickv.kfpkg

# MicroPython
./ktool.py -B goE -a 524288 MicroPython.bin

# dvp_ov (サンプルアプリ)
./ktool.py -B goE -a 2621440 dvp_ov.bin

```



# 使い方

M5StackVをそのまま起動/リセットすると最初のアクティブなアプリケーションが起動します。
ボタンBを押したままM5StickVを起動/リセットすると次のような画面を表示してアプリケーションのアクティブ/非アクティブを選択できます。ボタンBでメニューの選択、ボタンAでアクティブ/非アクティブを選択します。*印がアクティブで、複数アクティブにした場合は、先頭のアクティブなアプリが起動します。１つもアクティブなアプリがない場合もこのメニューが表示されます。

![bootselector.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555397/a74c4dff-61e6-fc39-149f-832af910a552.png)

# 最後に

やっつけで作ってからほとんど手を入れておらず、SDカードからインポートなど機能追加もしたいと思いつつ、実現できていません。。。