WebAssembly Micro Runtimeお試し②

はじめに

少し前に、組込みで使えるWebAssembly Micro Runtimeが公開されました。 また、いつの間にかSTMでのデモアプリが公開されています。

github.com

リファレンスが普段触っているZephyrなので、少し動かしてみます。

前回のおさらい

試しに、qemu_cortex_m3をターゲットにビルドすると、RAM不足でビルドが失敗していました。

$ cmake -GNinja -DBOARD=qemu_cortex_m3 ..
$ ninja run
Memory region         Used Size  Region Size  %age Used
           FLASH:       69112 B       256 KB     26.36%
            SRAM:      535984 B        64 KB    817.85%
        IDT_LIST:         120 B         2 KB      5.86/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/8.3.0/../../../../arm-zephyr-eabi/bin/ld: zephyr/zephyr_prebuilt.elf section `bss' will not fit in region `SRAM'
/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/8.3.0/../../../../arm-zephyr-eabi/bin/ld: section .intList VMA [0000000020010000,0000000020010077] overlaps section bss VMA [0000000020000000,0000000020080354]
/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/8.3.0/../../../../arm-zephyr-eabi/bin/ld: region `SRAM' overflowed by 470448 bytes
collect2: error: ld returned 1 exit status
%
ninja: build stopped: subcommand failed.

64KBくらいRAMがあれば動いて欲しいところなので、なんとか動かせないか試してみます。

利用RAMサイズを減らす

twitterで@nodamushiさんがヒントをくれました。

|> core/iwasm/runtime/vmcore-wasm/wasm.h

#define MaxMemoryPages 65536
#define MaxTableElems UINT32_MAX
#define NumBytesPerPage 65536
#define NumBytesPerPageLog2 16
#define MaxReturnValues 16

wasmに詳しくないので、ページの概念が何を表現しているのかわかりませんが、とりあえず1ページ4KBくらいでよくない?ということで、定義を修正します。

#define NumBytesPerPage 4096
#define NumBytesPerPageLog2 12

main.cで確保されるヒープサイズを32KBにします。

|> core/iwasm/products/zephyr/simple/src/main.c

static char global_heap_buf[32 * 1024] = { 0 };
$ ninja run
[9/14] Linking C executable zephyr/zephyr_prebuilt.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       69112 B       256 KB     26.36%
            SRAM:       44464 B        64 KB     67.85%
        IDT_LIST:         120 B         2 KB      5.86%
[13/14] To exit from QEMU enter: 'CTRL+a, x'[QEMU] CPU: cortex-m3
qemu-system-arm: warning: nic stellaris_enet.0 has no peer
***** Booting Zephyr OS zephyr-v1.14.0 *****
Hello world!
buf ptr: 0x40000178
buf: 1234

お、動きますね! OS、アプリケーションとラインタイム合わせて、RAMの使用量は44KBくらいです。

ちなみに、global_heap_bufは26KBまで小さくしても動作します。 25KBからはRuntimeのインスタンス化に失敗します。 Runtimeに最低でも26KB程度は必要、ということでしょう。

memory_usage.txtに、RAM利用量について、次の記述がありました。

Current memory usage, take samples/littlevgl in Zephyr for example:
(1) WASM app binary:                        142K for littlevgl ui_app.wasm
(2) WASM app memory space:                  64K for littlevgl ui_app.wasm
(3) WASM app heap space:                    8K by default
(4) WASM app thread native stack:           4K by default
(5) WASM interpreter stack:                 8K by default
(6) WASM block address hash cache:          3K
(7) timer thread stack:                     4K
(8) sensor thread stack:                    4K
(9) touch screen thread stack:              4K
(10) others: vm, app mgr, queue, native lib: ~22K

Total memory usage: ~263K

(10) others: vm, app mgr, queue, native lib: ~22Kとなっているので、プラスαで何かがあって、26KBが最低ライン、というのは有り得そうです。 次回以降で、もう少し詳しく内部を見ていきましょう。