ESP32 blink example

extensions
Volodymyr Shymanskyy 5 years ago
parent d26aa6183d
commit b97ef7794e

@ -0,0 +1,19 @@
## Arduino blink example
This example was tested with ESP32.
ESP8266 is almost working (just needs a workaround for 64KiB wasm pages).
`./wasm` directory contains an example Arduino app (sketch) that is compiled to WebAssembly.
Compilation is performed using `wasicc` here, but `clang --target=wasm32` can be used as well.
The resulting `wasm` binary is then converted to a C header using `xxd`.
See `build.sh` for details.
`PlatformIO` is used to build the host interpreter.
You can change the LED pin number in `platformio.ini` with `-DLED_BUILTIN` option.
To run the example on ESP32:
```sh
pio run -e esp32 -t upload && pio device monitor
```

@ -0,0 +1,38 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32]
platform = espressif32
board = esp32dev
framework = arduino
board_build.f_cpu = 240000000L
monitor_speed = 115200
src_build_flags =
-DLED_BUILTIN=19
-DESP32 -Dd_m3LogOutput=false
-O3 -flto
-Wno-unused-function -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers
[env:esp8266]
platform = espressif8266
board = nodemcuv2
framework = arduino
board_build.f_cpu = 160000000L
monitor_speed = 115200
upload_speed = 460800
src_build_flags =
-DLED_BUILTIN=13
-DESP8266 -Dd_m3FixedHeap=0x6000 -Dd_m3LinearMemLimit=2048 -Dd_m3LogOutput=false
-O3 -flto
-Wno-unused-function -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers

@ -0,0 +1,86 @@
#include "m3/m3_api_defs.h"
#include "m3/m3_env.h"
#include <Arduino.h>
/*
* Note: each RawFunction should complete with one of these calls:
* m3ApiReturn(val) - Returns a value
* m3ApiSuccess() - Returns void (and no traps)
* m3ApiTrap(trap) - Returns a trap
*/
m3ApiRawFunction(m3_arduino_millis)
{
m3ApiReturnType (uint32_t)
m3ApiReturn(millis());
}
m3ApiRawFunction(m3_arduino_delay)
{
m3ApiGetArg (uint32_t, ms)
//printf("api: delay %d\n", ms); // you can also trace API calls
delay(ms);
m3ApiSuccess();
}
// This maps pin modes from arduino_wasm_api.h
// to actual platform-specific values
uint8_t mapPinMode(uint8_t mode)
{
switch(mode) {
case (0): return INPUT;
case (1): return OUTPUT;
case (2): return INPUT_PULLUP;
}
return INPUT;
}
m3ApiRawFunction(m3_arduino_pinMode)
{
m3ApiGetArg (uint32_t, pin)
m3ApiGetArg (uint32_t, mode)
pinMode(pin, mapPinMode(mode));
m3ApiSuccess();
}
m3ApiRawFunction(m3_arduino_digitalWrite)
{
m3ApiGetArg (uint32_t, pin)
m3ApiGetArg (uint32_t, value)
digitalWrite(pin, value);
m3ApiSuccess();
}
// This is a convenience function
m3ApiRawFunction(m3_arduino_getPinLED)
{
m3ApiReturnType (uint32_t)
m3ApiReturn(LED_BUILTIN);
}
M3Result m3_LinkArduino (IM3Runtime runtime)
{
IM3Module module = runtime->modules;
const char* arduino = "arduino";
m3_LinkRawFunction (module, arduino, "millis", "i()", &m3_arduino_millis);
m3_LinkRawFunction (module, arduino, "delay", "v(i)", &m3_arduino_delay);
m3_LinkRawFunction (module, arduino, "pinMode", "v(ii)", &m3_arduino_pinMode);
m3_LinkRawFunction (module, arduino, "digitalWrite", "v(ii)", &m3_arduino_digitalWrite);
m3_LinkRawFunction (module, arduino, "getPinLED", "i()", &m3_arduino_getPinLED);
return m3Err_none;
}

@ -0,0 +1,70 @@
//
// Wasm3 - high performance WebAssembly interpreter written in C.
//
// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy.
// All rights reserved.
//
#include "Arduino.h"
#include "m3/m3.h"
#include "../wasm/arduino_app.wasm.h"
M3Result m3_LinkArduino (IM3Runtime runtime);
#define FATAL(msg, ...) { printf("Fatal: " msg "\n", ##__VA_ARGS__); return; }
void wasm_task(void*)
{
M3Result result = m3Err_none;
IM3Environment env = m3_NewEnvironment ();
if (!env) FATAL("m3_NewEnvironment failed");
IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL);
if (!runtime) FATAL("m3_NewRuntime failed");
IM3Module module;
result = m3_ParseModule (env, &module, arduino_app_wasm, arduino_app_wasm_len-1);
if (result) FATAL("m3_ParseModule: %s", result);
result = m3_LoadModule (runtime, module);
if (result) FATAL("m3_LoadModule: %s", result);
result = m3_LinkArduino (runtime);
if (result) FATAL("m3_LinkArduino: %s", result);
IM3Function f;
result = m3_FindFunction (&f, runtime, "_start");
if (result) FATAL("m3_FindFunction: %s", result);
printf("Running WebAssembly...\n");
const char* i_argv[1] = { NULL };
result = m3_CallWithArgs (f, 0, i_argv);
if (result) FATAL("m3_CallWithArgs: %s", result);
// Should not arrive here
}
void setup()
{
Serial.begin(115200);
delay(100);
Serial.print("\nWasm3 v" M3_VERSION ", build " __DATE__ " " __TIME__ "\n");
#ifdef ESP32
// On ESP32, we can launch in a separate thread
xTaskCreate(&wasm_task, "wasm3", 32768, NULL, 5, NULL);
#else
wasm_task(NULL);
#endif
}
void loop()
{
delay(100);
}

@ -0,0 +1,29 @@
#include "arduino_wasm_api.h"
int LED_BUILTIN;
void setup() {
LED_BUILTIN = getPinLED();
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(100); // wait 100ms
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(900); // wait 900ms
}
/*
* Entry point
*/
WASM_EXPORT
void _start() {
setup();
while (1) { loop(); }
}

@ -0,0 +1,20 @@
unsigned char arduino_app_wasm[] = {
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x11, 0x04, 0x60,
0x02, 0x7f, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60,
0x00, 0x01, 0x7f, 0x02, 0x4e, 0x04, 0x07, 0x61, 0x72, 0x64, 0x75, 0x69,
0x6e, 0x6f, 0x09, 0x67, 0x65, 0x74, 0x50, 0x69, 0x6e, 0x4c, 0x45, 0x44,
0x00, 0x03, 0x07, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x07, 0x70,
0x69, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x00, 0x00, 0x07, 0x61, 0x72, 0x64,
0x75, 0x69, 0x6e, 0x6f, 0x0c, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c,
0x57, 0x72, 0x69, 0x74, 0x65, 0x00, 0x00, 0x07, 0x61, 0x72, 0x64, 0x75,
0x69, 0x6e, 0x6f, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x02, 0x03,
0x02, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x01, 0x07, 0x13, 0x02, 0x06,
0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x5f, 0x73, 0x74,
0x61, 0x72, 0x74, 0x00, 0x04, 0x0a, 0x3a, 0x01, 0x38, 0x01, 0x01, 0x7f,
0x41, 0x80, 0x08, 0x10, 0x00, 0x22, 0x00, 0x36, 0x02, 0x00, 0x20, 0x00,
0x41, 0x01, 0x10, 0x01, 0x03, 0x40, 0x41, 0x80, 0x08, 0x28, 0x02, 0x00,
0x41, 0x01, 0x10, 0x02, 0x41, 0xe4, 0x00, 0x10, 0x03, 0x41, 0x80, 0x08,
0x28, 0x02, 0x00, 0x41, 0x00, 0x10, 0x02, 0x41, 0x84, 0x07, 0x10, 0x03,
0x0c, 0x00, 0x0b, 0x00, 0x0b
};
unsigned int arduino_app_wasm_len = 197;

@ -0,0 +1,30 @@
#ifndef arduino_wasm_api_h
#define arduino_wasm_api_h
#include <stdint.h>
#define WASM_EXPORT extern "C" __attribute__((used)) __attribute__((visibility ("default")))
#define WASM_EXPORT_AS(NAME) WASM_EXPORT __attribute__((export_name(NAME)))
#define WASM_IMPORT(MODULE,NAME) __attribute__((import_module(MODULE))) __attribute__((import_name(NAME)))
#define WASM_CONSTRUCTOR __attribute__((constructor))
#define LOW 0x0
#define HIGH 0x1
#define INPUT 0x0
#define OUTPUT 0x1
#define INPUT_PULLUP 0x2
extern "C" {
WASM_IMPORT("arduino", "millis") uint32_t millis (void);
WASM_IMPORT("arduino", "delay") void delay (uint32_t ms);
WASM_IMPORT("arduino", "pinMode") void pinMode (uint32_t pin, uint32_t mode);
WASM_IMPORT("arduino", "digitalWrite") void digitalWrite (uint32_t pin, uint32_t value);
// This is a convenience function
WASM_IMPORT("arduino", "getPinLED") uint32_t getPinLED (void);
}
#endif // arduino_wasm_api_h

@ -0,0 +1,5 @@
millis
delay
pinMode
digitalWrite
getPinLED

@ -0,0 +1,12 @@
# Compile
wasicc -Os \
-z stack-size=4096 -Wl,--initial-memory=65536 \
-Wl,--allow-undefined-file=arduino_wasm_api.syms \
-Wl,--strip-all -nostdlib \
-o arduino_app.wasm arduino_app.cpp
# Optimize (optional)
#wasm-opt -O3 arduino_app.wasm -o arduino_app.wasm
# Convert to header
xxd -i arduino_app.wasm > arduino_app.wasm.h
Loading…
Cancel
Save