wasm3: NodeMCU examples throw errors

About two weeks ago, we were able to run several WebAssembly modules on NodeMCU ESP microcontrollers following the esp32-pio and esp8266 platform examples.

In the meanwhile, work on wasm3 has clearly continued - we are particularly happy with the WASI support!

I am, however, now unable to run our WASM modules using the latest code base. For instance, on adapting the esp8266 example as follows:

#include <stdio.h>

#include "Arduino.h"

#define FATAL(msg, ...) { printf("Fatal: " msg "\n", ##__VA_ARGS__); return; }

#include "m3/m3.h" 
#include "m3/m3_env.h"

#include "m3/extra/fib32.wasm.h"

void run_wasm()
{
    M3Result result = c_m3Err_none;

    uint8_t* wasm = (uint8_t*)fib32_wasm;
    size_t fsize = fib32_wasm_len-1;

    IM3Environment env = m3_NewEnvironment ();
    if (!env) FATAL("m3_NewEnvironment failed");

    IM3Runtime runtime = m3_NewRuntime (env, 64*1024, NULL);
    if (!runtime) FATAL("m3_NewRuntime failed");

    IM3Module module;
    result = m3_ParseModule (env, &module, wasm, fsize);
    if (result) FATAL("m3_ParseModule: %s", result);

    result = m3_LoadModule (runtime, module);
    if (result) FATAL("m3_LoadModule: %s", result);
    
    /*result = m3_LinkWASI (runtime->modules);
    if (result) FATAL("m3_LinkWASI: %s", result); 
    
    result = m3_LinkLibC (runtime->modules);
    if (result) FATAL("m3_LinkLibC: %s", result);*/
    
    IM3Function f;
    result = m3_FindFunction (&f, runtime, "fib");
    if (result) FATAL("m3_FindFunction: %s", result);

    const char* i_argv[2] = { "3", NULL };
    result = m3_CallWithArgs (f, 1, i_argv);

    if (result) FATAL("Call: %s", result);

    long value = *(long*)(runtime->stack);

    Serial.println(value);

}

void setup()
{
  Serial.begin(115200);
  delay(10);

  Serial.print("\nwasm3 on ESP8266, build " __DATE__ " " __TIME__ "\n");

  u32 start = millis();
  run_wasm();
  u32 end = millis();

  Serial.print(String("Elapsed: ") +  (end - start) + " ms\n");
}

void loop()
{
  delay(100);
}

… one of our ESP8266’s throws the following error:

wasm3 on ESP8266, build Dec 27 2019 18:59:05
Fatal: m3_NewRuntime failed
Elapsed: 6 ms

Also, updating the code of the esp32-pio example along the same lines throws a Guru Meditation error, followed by a boot loop.

Might it be possible to provide a minimal working example that runs, for instance, fib32_wasm on ESP8266 and ESP32 using the latest version of wasm3?

(Separately, linking WASI gives rise to the following error on the ESP8266: /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/time/clock.c:62: undefined reference to _times_r … but that is of course a different issue)

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 24 (22 by maintainers)

Most upvoted comments

Far from ideal, but I have a prototype of ESP32 running or simple WASI test: image

Thanks for the info! I will try to get esp* working again asap.

I doubt it WASI can be reasonably supported on MCUs (and if this is needed at all). We’ll see.

On Sat, 28 Dec 2019, 14:26 Robin van Emden, notifications@github.com wrote:

Super that you’ll be able to get around to fixing/updating the MCU examples - being able to run WASM on MCU’s is a great prospect! Enabling d_m3AllocateLinearMemory by itself does not seem enough to make things work yet, probably there is something I am still missing.

I don’t know if it is of any use, but the latest esp-pio based wasm3 example we ran was based on commit 4c01ba4, about 17 days ago. We just removed the unfinished WASI files from the m3 directory and included m3/m3_core.h:

// ESP-PIO Fibonacci test, Wasm3, no-WASI, 4c01ba4, Dec 12th

#include <stdio.h> #include <time.h>

#include “freertos/FreeRTOS.h” #include “freertos/task.h” #include “driver/gpio.h” #include “sdkconfig.h” #include “esp_system.h” #include “esp_spi_flash.h”

#define FATAL(msg, …) { printf("Fatal: " msg “\n”, ##VA_ARGS); return; }

#include “m3/m3.h” #include “m3/m3_core.h”

#include “m3/extra/fib32.wasm.h” void run_wasm() { M3Result result = c_m3Err_none;

u8* wasm = (u8*)fib32_wasm;
u32 fsize = fib32_wasm_len-1;

printf("Loading WebAssembly...\n");

IM3Module module;
result = m3_ParseModule (& module, wasm, fsize);
if (result) FATAL("m3_ParseModule: %s", result);

IM3Runtime env = m3_NewRuntime (1024);
if (!env) FATAL("m3_NewRuntime");

result = m3_LoadModule (env, module);
if (result) FATAL("m3_LoadModule: %s", result);

IM3Function f;
result = m3_FindFunction (&f, env, "fib");
if (result) FATAL("m3_FindFunction: %s", result);

printf("Running...\n");

const char* i_argv[2] = { "24", NULL };
result = m3_CallWithArgs (f, 1, i_argv);

if (result) FATAL("m3_CallWithArgs: %s", result);

} void wasm_task(void*) { printf("\nwasm3 on ESP32, build " DATE " " TIME “\n”);

clock_t start = clock();
run_wasm();
clock_t end = clock();

printf("Elapsed: %d ms\n", (end - start)*1000 / CLOCKS_PER_SEC);

for(;;) {
    vTaskDelay(0xFFFF);
}

} extern "C"void app_main() { /* Print chip information */ esp_chip_info_t chip_info; esp_chip_info(&chip_info); printf("This is ESP32 chip with %d CPU cores, WiFi%s%s, ", chip_info.cores, (chip_info.features & CHIP_FEATURE_BT) ? “/BT” : “”, (chip_info.features & CHIP_FEATURE_BLE) ? “/BLE” : “”);

printf("silicon revision %d, ", chip_info.revision);

printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
        (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");

xTaskCreate(&wasm_task, "wasm_m3", 32768, NULL, 5, NULL);

for(;;) {
    vTaskDelay(0xFFFF);
}

}

Which, when run on an ESP32-WROOM-32, indeed correctly calculates the 24th term of the Fibonacci sequence:

This is ESP32 chip with 2 CPU cores, WiFi/BT/BLE, silicon revision 1, 4MB external flash

wasm3 on ESP32, build Dec 28 2019 12:53:11 Loading WebAssembly… Running… Result: 46368 Elapsed: 410 ms

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/wasm3/wasm3/issues/26?email_source=notifications&email_token=AALP3FEODT4UDO54EAL4XBTQ25AXVA5CNFSM4KAA2XF2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHYIZDY#issuecomment-569412751, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALP3FFKVYEXR25CJMPC4YDQ25AXVANCNFSM4KAA2XFQ .

@igrr @robinvanemden @hberntsen A basic ESP32-WASI example has landed here: https://github.com/wasm3/wasm3/tree/master/platforms/esp32-idf-wasi Please consider contributing your improvements. Thanks!

@vshymanskyy Would you be interested in a PR to add CI tests for the ESP32 platform (in QEMU)?

@robinvanemden @hberntsen should work now with esp8266, esp32-pio examples

I just spent some time debugging this. It looks like d_m3AllocateLinearMemory needs to be defined (tested on an ESP32 (with idf) and Linux) in order not to crash.

A Git bisect pointed me to 73c990a38b525135e1303b63dd4ec1ef8701fc16 where the Entry op reads from _mem, which is NULL when d_m3AllocateLinearMemory = 0

@robinvanemden For WASI on the ESP32 you need to integrate with the FreeRTOS/ESP32 API. I am doing some experiments with Rust -> Webassembly -> wasm3 on ESP32. I already got a simple thread::sleep working by implementing a small piece of WASI. I’ve been trying to include Rust’s standard library but even for a simple println! I run out of memory. (On x86 I already need to allocate a heap > 200K, my new ESP32 with PSRAM is being shipped from China now)

Very interested as well! Can help with cleanup for this new example.