mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #15329 from kfessel/p-add-wamr
pkg/wamr: add WAMR to provide WASM support in RIOT
This commit is contained in:
commit
a5b91362cb
36
examples/wasm/Makefile
Normal file
36
examples/wasm/Makefile
Normal file
@ -0,0 +1,36 @@
|
||||
APPLICATION = wasm-example
|
||||
# If no BOARD is defined in the environment, use this default:
|
||||
BOARD ?= native
|
||||
|
||||
# This has to be the absolute path to the RIOT base directory:
|
||||
RIOTBASE ?= $(CURDIR)/../..
|
||||
|
||||
USEPKG += wamr
|
||||
|
||||
ifneq ($(BOARD),native)
|
||||
CFLAGS += -DTHREAD_STACKSIZE_MAIN='(6 * 1024)'
|
||||
endif
|
||||
|
||||
export WAMR_CONFIG := $(abspath config.cmake)
|
||||
|
||||
BLOBS += test.wasm hello.wasm
|
||||
|
||||
# Comment this out to disable code in RIOT that does safety checking
|
||||
# which is not needed in a production environment but helps in the
|
||||
# development process:
|
||||
DEVELHELP ?= 1
|
||||
|
||||
# Change this to 0 show compiler invocation lines by default:
|
||||
QUIET ?= 1
|
||||
|
||||
all: hello.wasm
|
||||
|
||||
hello.wasm: wasm_sample/hello.c wasm_sample/Makefile
|
||||
make -C wasm_sample hello.wasm
|
||||
mv wasm_sample/hello.wasm .
|
||||
|
||||
#######################################################
|
||||
# Load the rest of the usual RIOT make infrastructure #
|
||||
#######################################################
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
37
examples/wasm/Makefile.ci
Normal file
37
examples/wasm/Makefile.ci
Normal file
@ -0,0 +1,37 @@
|
||||
BOARD_INSUFFICIENT_MEMORY64K :=\
|
||||
blackpill \
|
||||
bluepill \
|
||||
bluepill-stm32f030c8 \
|
||||
i-nucleo-lrwan1 \
|
||||
nucleo-f030r8 \
|
||||
nucleo-f302r8 \
|
||||
nucleo-f303k8 \
|
||||
nucleo-f334r8 \
|
||||
nucleo-l053r8 \
|
||||
stm32f0discovery \
|
||||
stm32l0538-disco\
|
||||
stm32mp157c-dk2 \
|
||||
#
|
||||
|
||||
BOARD_INSUFFICIENT_MEMORY32K :=\
|
||||
nucleo-f031k6 \
|
||||
nucleo-f042k6 \
|
||||
nucleo-l031k6 \
|
||||
stm32g0316-disco \
|
||||
#
|
||||
|
||||
BOARD_INSUFFICIENT_MEMORY16K :=\
|
||||
nucleo-l011k4 \
|
||||
stm32f030f4-demo \
|
||||
#
|
||||
|
||||
BOARD_INSUFFICIENT_MEMORY := \
|
||||
slstk3400a \
|
||||
stk3200 \
|
||||
samd10-xmini \
|
||||
saml10-xpro \
|
||||
saml11-xpro \
|
||||
$(BOARD_INSUFFICIENT_MEMORY64K) \
|
||||
$(BOARD_INSUFFICIENT_MEMORY32K) \
|
||||
$(BOARD_INSUFFICIENT_MEMORY16K) \
|
||||
#
|
6
examples/wasm/README.md
Normal file
6
examples/wasm/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
# building WASM
|
||||
|
||||
The source for test.wasm can be found in
|
||||
<RIOT>/build/pkg/wamr/product-mini/app-samples/hello-world/
|
||||
|
||||
https://github.com/bytecodealliance/wasm-micro-runtime/tree/main/product-mini/app-samples/hello-world
|
24
examples/wasm/config.cmake
Normal file
24
examples/wasm/config.cmake
Normal file
@ -0,0 +1,24 @@
|
||||
# following line a hints for build options mostly untested
|
||||
# some are not matching RIOTs application targets
|
||||
# they default to off
|
||||
|
||||
# set (WAMR_BUILD_LIBC_WASI 1) #enable libc wasi support
|
||||
# set (WAMR_BUILD_THREAD_MGR 1) #enable thread manager support
|
||||
# set (WAMR_BUILD_APP_FRAMEWORK 1) #enable WAMR app framework support
|
||||
# set (WAMR_BUILD_LIB_PTHREAD 1) #enable pthread support
|
||||
|
||||
# set (WAMR_BUILD_JIT 1) #enable WAMR JIT
|
||||
# set (WAMR_BUILD_FAST_INTERP 1) #enable Fast interpreter
|
||||
# set (WAMR_BUILD_MULTI_MODULE 1) #enable Multiple modules
|
||||
# set (WAMR_BUILD_SPEC_TEST 1) #enable spec test compatible mode is on
|
||||
# set (WAMR_BUILD_BULK_MEMORY 1) #enable Bulk memory feature
|
||||
# set (WAMR_BUILD_SHARED_MEMORY 1) #enable Shared memory
|
||||
# set (WAMR_BUILD_MINI_LOADER 1) #enable WASM mini loader
|
||||
# set (WAMR_DISABLE_HW_BOUND_CHECK 1) #enable Hardware boundary check disabled
|
||||
# set (WAMR_BUILD_MEMORY_PROFILING 1) #enable Memory profiling
|
||||
# set (WAMR_APP_THREAD_STACK_SIZE_MAX ${WAMR_APP_THREAD_STACK_SIZE_MAX}) #set maximum thread stack size
|
||||
# set (WAMR_BUILD_CUSTOM_NAME_SECTION 1) #enable Custom name section
|
||||
# set (WAMR_BUILD_TAIL_CALL 1) #enable Tail call
|
||||
|
||||
# the builtin wamr libc is enabled by default
|
||||
# set (WAMR_BUILD_LIBC_BUILTIN 0) #disable builtin libc
|
142
examples/wasm/iwasmt.c
Normal file
142
examples/wasm/iwasmt.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2020 TU Bergakademie Freiberg Karl Fessel
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wasm_export.h"
|
||||
|
||||
/* execs the main function in an instantiated module */
|
||||
static int iwasm_instance_exec_main(wasm_module_inst_t module_inst, int argc, char **argv)
|
||||
{
|
||||
/* exception memory is part of instance -> no buffer need */
|
||||
const char *exception = 0;
|
||||
int ret = 0;
|
||||
wasm_application_execute_main(module_inst, argc, argv);
|
||||
if ((exception = wasm_runtime_get_exception(module_inst))) {
|
||||
puts(exception);
|
||||
return -1;
|
||||
}
|
||||
if (argc > 0) {
|
||||
ret = *((int*)argv);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* execs the main function of a loaded module */
|
||||
int iwasm_module_exec_main(wasm_module_t wasm_module, int argc, char **argv)
|
||||
{
|
||||
wasm_module_inst_t wasm_module_inst = NULL;
|
||||
int ret = 0;
|
||||
|
||||
{ /* instantiate the module */
|
||||
char error_buf[128];
|
||||
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, 8 * 1024,
|
||||
8 * 1024, error_buf, sizeof(error_buf)))) {
|
||||
puts(error_buf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ret = iwasm_instance_exec_main(wasm_module_inst, argc, argv);
|
||||
/* destroy the module instance */
|
||||
wasm_runtime_deinstantiate(wasm_module_inst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* bytecode needs to be writeable*/
|
||||
int iwasm_bytecode_exec_main(uint8_t *bytecode, size_t bytecode_len, int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
wasm_module_t wasm_module = NULL;
|
||||
|
||||
{ /* load WASM module */
|
||||
char error_buf[128];
|
||||
if (!(wasm_module = wasm_runtime_load(bytecode, bytecode_len,
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
puts(error_buf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ret = iwasm_module_exec_main(wasm_module, argc, argv);
|
||||
/* unload WASM module */
|
||||
wasm_runtime_unload(wasm_module);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* running this initialises the wamr runtime*/
|
||||
bool iwasm_runtime_init(void)
|
||||
{
|
||||
RuntimeInitArgs init_args;
|
||||
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||
/* using default system allocator, pool allocator and
|
||||
* and allocator function hooks are available
|
||||
* see <wamr>/core/iwasm/include/wasm_export.h l99..*/
|
||||
init_args.mem_alloc_type = Alloc_With_System_Allocator;
|
||||
|
||||
/* initialize runtime environment */
|
||||
if (!wasm_runtime_full_init(&init_args)) {
|
||||
puts("Init runtime environment failed.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void iwasm_runtime_destroy(void)
|
||||
{
|
||||
wasm_runtime_destroy();
|
||||
}
|
||||
|
||||
/* this seems to be a very direct interpretation of "i like to have a wamr_run" */
|
||||
int wamr_run(void *bytecode, size_t bytecode_len, int argc, char **argv)
|
||||
{
|
||||
return iwasm_bytecode_exec_main((uint8_t *)bytecode, bytecode_len, argc, argv);
|
||||
}
|
||||
|
||||
/* this creates a copy of bytecode and argv
|
||||
* if argc is 0 it is set to 1 and argv[0] is set to ""
|
||||
* to create some space for a return value */
|
||||
int wamr_run_cp(const void *bytecode, size_t bytecode_len, int argc, char *argv[])
|
||||
{
|
||||
/* we need the bytecode to be writable while loading
|
||||
* loading adds size information to stack POPs */
|
||||
uint8_t * wasm_buf = malloc(bytecode_len);
|
||||
if (!wasm_buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(wasm_buf, bytecode, bytecode_len);
|
||||
/* no copy need if architecture has const in writable mem */
|
||||
/* wasm_buf = (uint8_t *) main_wasm; */
|
||||
|
||||
unsigned wasm_buf_size = bytecode_len;
|
||||
|
||||
/* iwasm uses argv[0] cast to an int to store mains return value */
|
||||
static char * empty = "";
|
||||
char ** parv;
|
||||
if (argc > 0) {
|
||||
parv = malloc(sizeof(argv[0]) * argc);
|
||||
if (!parv){
|
||||
return -1;
|
||||
}
|
||||
memcpy(parv, argv, sizeof(argv[0]) * argc);
|
||||
}
|
||||
else {
|
||||
argc = 1;
|
||||
parv = malloc(sizeof(argv[0]) * argc);
|
||||
if (!parv) {
|
||||
return -1;
|
||||
}
|
||||
parv[0] = empty;
|
||||
}
|
||||
int ret = wamr_run(wasm_buf, wasm_buf_size, argc, parv);
|
||||
free(parv);
|
||||
free(wasm_buf);
|
||||
|
||||
return ret;
|
||||
}
|
BIN
examples/wasm/test.wasm
Executable file
BIN
examples/wasm/test.wasm
Executable file
Binary file not shown.
44
examples/wasm/wasm-main.c
Normal file
44
examples/wasm/wasm-main.c
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2020 TU Bergakademie Freiberg Karl Fessel
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*provide some test program*/
|
||||
#include "blob/test.wasm.h"
|
||||
#include "blob/hello.wasm.h"
|
||||
|
||||
bool iwasm_runtime_init(void);
|
||||
void iwasm_runtime_destroy(void);
|
||||
|
||||
/* wamr_run is a very direct interpretation of "i like to have a wamr_run" */
|
||||
int wamr_run(void *bytecode, size_t bytecode_len, int argc, char **argv);
|
||||
|
||||
/* wamr_run_cp creates a copy bytecode and argv
|
||||
* if argc is 0 it is set to 1 and argv[0] is set to ""
|
||||
* to create some space for a return value */
|
||||
int wamr_run_cp(const void *bytecode, size_t bytecode_len, int argc, const char **argv);
|
||||
|
||||
#define telltruth(X) ((X) ? "true" : "false")
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("iwasm_initilised: %s\n", telltruth(iwasm_runtime_init()));
|
||||
|
||||
int app_argc = 2;
|
||||
const char *app_argv[] = {"test", "bob"};
|
||||
int ret = wamr_run_cp(test_wasm, test_wasm_len, app_argc, app_argv);
|
||||
printf("ret = %d\n", ret);
|
||||
ret = wamr_run_cp(hello_wasm, hello_wasm_len, app_argc, app_argv);
|
||||
printf("ret = %d\n", ret);
|
||||
|
||||
iwasm_runtime_destroy();
|
||||
|
||||
}
|
117
examples/wasm/wasm_sample/Makefile
Normal file
117
examples/wasm/wasm_sample/Makefile
Normal file
@ -0,0 +1,117 @@
|
||||
#sometimes there might not be a wasm-ld (Ubuntu:focal)
|
||||
#lets check if we can find a specific version
|
||||
|
||||
#this is a kind of crazy which from
|
||||
#https://www.gnu.org/software/make/manual/html_node/Call-Function.html#Call-Function
|
||||
#see https://github.com/RIOT-OS/RIOT/pull/16806 and /16807 and /16776 for why
|
||||
search_fn = $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)))))
|
||||
|
||||
ifneq ($(call search_fn,wasm-ld),)
|
||||
WASM-LD ?= wasm-ld
|
||||
else
|
||||
ifneq ($(call search_fn,wasm-ld-11),)
|
||||
LLVM_VERSION := 11
|
||||
else
|
||||
ifneq ($(call search_fn,wasm-ld-10),)
|
||||
LLVM_VERSION := 10
|
||||
else
|
||||
ifneq ($(call search_fn,wasm-ld-9),)
|
||||
LLVM_VERSION := 9
|
||||
else
|
||||
ifneq ($(call search_fn,wasm-ld-8),)
|
||||
LLVM_VERSION := 8
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(LLVM_VERSION),)
|
||||
CLANG ?= clang-$(LLVM_VERSION)
|
||||
CLANGPP ?= clang++-$(LLVM_VERSION)
|
||||
WASM-LD ?= wasm-ld-$(LLVM_VERSION)
|
||||
else
|
||||
CLANG ?= clang
|
||||
CLANGPP ?= clang++
|
||||
endif
|
||||
|
||||
ifeq ($(WASM-LD),)
|
||||
WASM-LD ?= echo "!! NO wasm-ld(-VERSION) found !!"; false
|
||||
COPY_HELLO := YES
|
||||
endif
|
||||
|
||||
LINK_FLAGS := -z stack-size=4096 \
|
||||
--export main \
|
||||
--export=__heap_base \
|
||||
--export=__data_end \
|
||||
--allow-undefined \
|
||||
--no-entry \
|
||||
--strip-all \
|
||||
--export-dynamic \
|
||||
-error-limit=0 \
|
||||
--lto-O3 \
|
||||
-O3 \
|
||||
--gc-sections\
|
||||
--initial-memory=65536 \
|
||||
|
||||
# --initial-memory may only be set in 64kB steps (pagesize of WASM)
|
||||
# even though this one page is 64kB
|
||||
# - data starts at 0, (1024 is chosen by lld)
|
||||
# - stack starts at 4kB growing down
|
||||
# - heap at 4kB growing up (see stack-size option)
|
||||
# -> memory can be smaller than first page
|
||||
# without stack-size option stack will start at 64kB
|
||||
# -> heap needs a second page
|
||||
# wasm-ld 8 and 11 do not need --initial-memory=64kB
|
||||
|
||||
COMPILE_FLAGS := -Wall \
|
||||
--target=wasm32-unknown-unknown-wasm \
|
||||
-emit-llvm \
|
||||
-Os \
|
||||
-flto \
|
||||
-fvisibility=hidden \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
|
||||
#one might consider adding these
|
||||
# -nostartfiles \
|
||||
# --nostdlib \
|
||||
# --nostdinc \
|
||||
# -std=c++14 \
|
||||
|
||||
%.show: %.wasm
|
||||
wasm2wat $<
|
||||
|
||||
%.wasm: %.o Makefile
|
||||
$(WASM-LD) -o $@ $(LINK_FLAGS) $<
|
||||
|
||||
|
||||
%.o: %.cpp Makefile FORCE
|
||||
$(CLANGPP) \
|
||||
-c \
|
||||
$(COMPILE_FLAGS) \
|
||||
-o $@ \
|
||||
$<
|
||||
|
||||
%.o: %.c Makefile FORCE
|
||||
$(CLANG)\
|
||||
-c \
|
||||
$(COMPILE_FLAGS) \
|
||||
-o $@ \
|
||||
$<
|
||||
|
||||
%.wat: %.wasm Makefile
|
||||
wasm2wat -o $@ $<
|
||||
|
||||
ifeq ($(COPY_HELLO),YES)
|
||||
hello.wasm: hello_prebuild.wasm
|
||||
@echo "!! NO wasm-ld(-VERSION) found !!"
|
||||
@echo "!! copying hello_prebuild.wasm !! "
|
||||
cp hello_prebuild.wasm hello.wasm
|
||||
else
|
||||
hello_prebuild.wasm: hello.wasm
|
||||
cp hello.wasm hello_prebuild.wasm
|
||||
endif
|
||||
|
||||
|
||||
.PHONY: FORCE
|
21
examples/wasm/wasm_sample/hello.c
Normal file
21
examples/wasm/wasm_sample/hello.c
Normal file
@ -0,0 +1,21 @@
|
||||
/* Copyright (C) World
|
||||
* a native printf is provided by the builtin libc of wamr */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" int printf( const char *, ...);
|
||||
#define WASM_EXPORT __attribute__((visibility("default"))) extern "C"
|
||||
#else
|
||||
extern int printf( const char *, ...);
|
||||
#define WASM_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
WASM_EXPORT int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1) {
|
||||
printf("Hello %s %i\n", argv[1], 2001);
|
||||
}
|
||||
else {
|
||||
printf("Hello %s %i\n", "RIOT", 2001);
|
||||
}
|
||||
return 2468;
|
||||
}
|
BIN
examples/wasm/wasm_sample/hello_prebuild.wasm
Executable file
BIN
examples/wasm/wasm_sample/hello_prebuild.wasm
Executable file
Binary file not shown.
60
pkg/wamr/CMakeLists.txt
Normal file
60
pkg/wamr/CMakeLists.txt
Normal file
@ -0,0 +1,60 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 3.8.2)
|
||||
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
|
||||
|
||||
project(NONE)
|
||||
|
||||
enable_language (ASM)
|
||||
|
||||
set (WAMR_BUILD_PLATFORM "riot")
|
||||
|
||||
if (DEFINED WAMR_CONFIG)
|
||||
include (${WAMR_CONFIG})
|
||||
endif ()
|
||||
|
||||
# Build as X86_32 by default, change to "AARCH64[sub]", "ARM[sub]", "THUMB[sub]", "MIPS" or "XTENSA"
|
||||
# if we want to support arm, thumb, mips or xtensa
|
||||
if (NOT DEFINED WAMR_BUILD_TARGET)
|
||||
set (WAMR_BUILD_TARGET "X86_32")
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_INTERP)
|
||||
# Enable Interpreter by default
|
||||
set (WAMR_BUILD_INTERP 1)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_AOT)
|
||||
# Disable AOT by default.
|
||||
set (WAMR_BUILD_AOT 0)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN)
|
||||
# Enable libc builtin support by default
|
||||
set (WAMR_BUILD_LIBC_BUILTIN 1)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_LIBC_WASI)
|
||||
# Disable libc wasi support by default
|
||||
set (WAMR_BUILD_LIBC_WASI 0)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_ROOT_DIR)
|
||||
# this assumption is true if this file is copied to WAMR_ROOT
|
||||
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif ()
|
||||
|
||||
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||
|
||||
# need includes from RIOT
|
||||
string(REGEX MATCHALL "([^\ ]+\ |[^\ ]+$)" RIOT_INCLUDES_LIST "${RIOT_INCLUDES}")
|
||||
|
||||
include_directories(SYSTEM ${RIOT_INCLUDES_LIST})
|
||||
|
||||
|
||||
# target_sources( ${WAMR_RUNTIME_LIB_SOURCE} )
|
||||
# executable linking is done by RIOT build system this just builds libwamr.a
|
||||
|
||||
add_library( wamr ${WAMR_RUNTIME_LIB_SOURCE})
|
95
pkg/wamr/Makefile
Normal file
95
pkg/wamr/Makefile
Normal file
@ -0,0 +1,95 @@
|
||||
PKG_NAME=wamr
|
||||
PKG_URL=https://github.com/bytecodealliance/wasm-micro-runtime.git
|
||||
ifeq ($(PKG_BLEADING),1)
|
||||
PKG_VERSION=main
|
||||
else
|
||||
PKG_VERSION=a22a5da40d7c81ebf3ebb26b457439712f5dde56
|
||||
#main 2022-02-09
|
||||
endif
|
||||
PKG_LICENSE=Apache-2.0
|
||||
|
||||
PKG_CUSTOM_PREPARED = CHECK_VERSION
|
||||
|
||||
include $(RIOTBASE)/pkg/pkg.mk
|
||||
|
||||
#less Wall TODO: get things fixed upstream
|
||||
CFLAGS := $(filter-out -Wcast-align, $(CFLAGS))
|
||||
CFLAGS := $(filter-out -Werror, $(CFLAGS))
|
||||
CFLAGS += -Wno-format
|
||||
CFLAGS += -Wno-strict-prototypes
|
||||
CFLAGS += -Wno-old-style-definition
|
||||
CFLAGS += -Wno-cast-function-type
|
||||
|
||||
#Prepapre includes for cmake
|
||||
RIOT_INCLUDES = $(filter-out -%,$(subst -I,,$(INCLUDES)))
|
||||
|
||||
#translate (CPU_ARCH) to Build Target
|
||||
#WAMR_BUILD_TARGET is "X86_32" "AARCH64[sub]", "ARM[sub]",
|
||||
# "THUMB[sub]", "MIPS" or "XTENSA"
|
||||
#no msp430, no AVR support for now
|
||||
|
||||
ifeq ($(CPU),native)
|
||||
ifeq ($(findstring x86,$(OS_ARCH)),x86)
|
||||
WAMR_BUILD_TARGET = X86_32
|
||||
endif
|
||||
ifeq ($(findstring arm,$(OS_ARCH)),arm)
|
||||
WAMR_BUILD_TARGET = ARM
|
||||
endif
|
||||
ifeq ($(findstring aarch,$(OS_ARCH)),aarch)
|
||||
#using 32Bit arm on native aarch
|
||||
WAMR_BUILD_TARGET = ARM
|
||||
endif
|
||||
else ifeq ($(findstring arm,$(CPU_ARCH)),arm)
|
||||
WAMR_BUILD_TARGET = THUMB
|
||||
else ifeq ($(CPU_ARCH),mips32r2)
|
||||
WAMR_BUILD_TARGET = MIPS
|
||||
else ifeq ($(CPU_ARCH),xtensa)
|
||||
WAMR_BUILD_TARGET = XTENSA
|
||||
else ifeq ($(CPU_ARCH),rv32)
|
||||
WAMR_BUILD_TARGET = RISCV32
|
||||
else
|
||||
$(error "WASM is not supported for architecture $(CPU_ARCH)")
|
||||
endif
|
||||
|
||||
ifeq ($(QUIET),0)
|
||||
CMAKEMAKEFLAGS += VERBOSE=1
|
||||
endif
|
||||
|
||||
#WAMR_CONFIG will be included into the cmake
|
||||
ifneq ($(WAMR_CONFIG),)
|
||||
WAMR_CMAKE_FLAGS += "-DWAMR_CONFIG=$(WAMR_CONFIG)"
|
||||
endif
|
||||
|
||||
WAMR_CMAKE_FLAGS += "-DRIOT_INCLUDES=$(RIOT_INCLUDES)"\
|
||||
-DWAMR_BUILD_TARGET=$(WAMR_BUILD_TARGET)\
|
||||
-DWAMR_ROOT_DIR=$(PKG_SOURCE_DIR)/ \
|
||||
-DCMAKE_SYSTEM_NAME=Generic \
|
||||
-DCMAKE_SYSTEM_PROCESSOR="$(MCPU)" \
|
||||
-DCMAKE_C_COMPILER=$(CC) \
|
||||
-DCMAKE_C_COMPILER_WORKS=TRUE \
|
||||
#
|
||||
|
||||
all: $(BINDIR)/libwamr.a
|
||||
|
||||
$(BINDIR)/libwamr.a: $(PKG_BUILD_DIR)/libwamr.a
|
||||
cp $< $@
|
||||
|
||||
$(PKG_BUILD_DIR)/libwamr.a: $(PKG_BUILD_DIR)/Makefile
|
||||
+$(MAKE) -C $(PKG_BUILD_DIR) $(CMAKEMAKEFLAGS)
|
||||
|
||||
$(PKG_BUILD_DIR)/Makefile: $(PKG_PREPARED) print_build_target
|
||||
ASMFLAGS="${CFLAGS}" cmake -B$(PKG_BUILD_DIR) $(WAMR_CMAKE_FLAGS)
|
||||
|
||||
print_build_target:
|
||||
@echo PKG_VERSION: $(PKG_VERSION)
|
||||
@echo native OS_ARCH: $(OS_ARCH)
|
||||
@echo CPU_ARCH: $(CPU_ARCH)
|
||||
@echo CPU: $(CPU)
|
||||
@echo CFLAGS: $(CFLAGS)
|
||||
@echo WAMR_BUILD_TARGET: $(WAMR_BUILD_TARGET)
|
||||
@echo WAMR_CONFIG: $(WAMR_CONFIG)
|
||||
@echo RIOT_INCLUDES: $(RIOT_INCLUDES)
|
||||
|
||||
|
||||
CHECK_VERSION:
|
||||
test -f $(PKG_DOWNLOADED) && (test `cat $(PKG_DOWNLOADED)` = $(PKG_VERSION) || rm $(PKG_DOWNLOADED));true
|
9
pkg/wamr/Makefile.dep
Normal file
9
pkg/wamr/Makefile.dep
Normal file
@ -0,0 +1,9 @@
|
||||
USEMODULE += sema
|
||||
USEMODULE += ztimer64_msec
|
||||
USEMODULE += ztimer_usec
|
||||
|
||||
|
||||
#WAMR supports "X86_32/64", "AARCH64", "ARM", "THUMB", "MIPS", "XTENSA" and RISCV
|
||||
FEATURES_REQUIRED_ANY += arch_native|arch_esp32|arch_riscv|cortexm_svc
|
||||
#arch_arm|arch_mips32r2|arch_esp need modified
|
||||
# build/pkg/wamr/core/iwasm/common/arch/invokeNative_<arch>.s
|
12
pkg/wamr/Makefile.include
Normal file
12
pkg/wamr/Makefile.include
Normal file
@ -0,0 +1,12 @@
|
||||
IWASM_CORE := $(PKGDIRBASE)/wamr/core
|
||||
IWASM_ROOT := $(IWASM_CORE)/iwasm
|
||||
SHARED_LIB_ROOT := $(IWASM_CORE)/shared
|
||||
|
||||
IWASM_INCLUDES += ${IWASM_ROOT}/include \
|
||||
${SHARED_LIB_ROOT}/platform/include \
|
||||
${SHARED_LIB_ROOT}/platform/riot \
|
||||
#
|
||||
|
||||
INCLUDES += $(addprefix -I,${IWASM_INCLUDES})
|
||||
|
||||
ARCHIVES += $(BINDIR)/libwamr.a
|
24
pkg/wamr/config.cmake
Normal file
24
pkg/wamr/config.cmake
Normal file
@ -0,0 +1,24 @@
|
||||
# following lines are hints for build options (mostly untested)
|
||||
# some are not matching RIOTs application targets
|
||||
# they default to off
|
||||
|
||||
# set (WAMR_BUILD_LIBC_WASI 1) #enable libc wasi support
|
||||
# set (WAMR_BUILD_THREAD_MGR 1) #enable thread manager support
|
||||
# set (WAMR_BUILD_APP_FRAMEWORK 1) #enable WAMR app framework support
|
||||
# set (WAMR_BUILD_LIB_PTHREAD 1) #enable pthread support
|
||||
|
||||
# set (WAMR_BUILD_JIT 1) #enable WAMR JIT
|
||||
# set (WAMR_BUILD_FAST_INTERP 1) #enable Fast interpreter
|
||||
# set (WAMR_BUILD_MULTI_MODULE 1) #enable Multiple modules
|
||||
# set (WAMR_BUILD_SPEC_TEST 1) #enable spec test compatible mode is on
|
||||
# set (WAMR_BUILD_BULK_MEMORY 1) #enable Bulk memory feature
|
||||
# set (WAMR_BUILD_SHARED_MEMORY 1) #enable Shared memory
|
||||
# set (WAMR_BUILD_MINI_LOADER 1) #enable WASM mini loader
|
||||
# set (WAMR_DISABLE_HW_BOUND_CHECK 1) #enable Hardware boundary check disabled
|
||||
# set (WAMR_BUILD_MEMORY_PROFILING 1) #enable Memory profiling
|
||||
# set (WAMR_APP_THREAD_STACK_SIZE_MAX ${WAMR_APP_THREAD_STACK_SIZE_MAX}) #set maximum thread stack size
|
||||
# set (WAMR_BUILD_CUSTOM_NAME_SECTION 1) #enable Custom name section
|
||||
# set (WAMR_BUILD_TAIL_CALL 1) #enable Tail call
|
||||
|
||||
# the builtin wamr libc is enabled by default
|
||||
# set (WAMR_BUILD_LIBC_BUILTIN 0) #disable builtin libc
|
86
pkg/wamr/doc.txt
Normal file
86
pkg/wamr/doc.txt
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* @defgroup pkg_wamr WebAssembly Micro Runtime
|
||||
* @ingroup pkg
|
||||
* @brief Provides WebAssembly support for RIOT
|
||||
* @see https://github.com/bytecodealliance/wasm-micro-runtime
|
||||
*
|
||||
* # WebAssembly Micro Runtime Riot Package
|
||||
*
|
||||
* "WebAssembly Micro Runtime (WAMR) is a standalone WebAssembly (WASM)
|
||||
* runtime with a small footprint."
|
||||
*
|
||||
* @see https://github.com/bytecodealliance/wasm-micro-runtime
|
||||
*
|
||||
* ## Status
|
||||
*
|
||||
* WAMR integration into RIOT should be considered experimental.
|
||||
* Changes that had to be done in WAMR are send to and integrated into upstream.
|
||||
* WAMR provides support for numerous architectures:
|
||||
* "X86_32/64", "AARCH64", "ARM", "THUMB", "MIPS", "XTENSA" and "RISCV"
|
||||
* this Package will build for native (x86,arm, aarch(using arm)), cortex-m, esp32 and riscv
|
||||
*
|
||||
* support for other architectures might provideable using the generic
|
||||
* `core/iwasm/common/arch/invokeNative_general.c` this is not tested
|
||||
*
|
||||
* tested : Cortex-M - "THUMB", native - "X86_32"
|
||||
*
|
||||
* ## Memory usage
|
||||
*
|
||||
* WebAssembly defines its pages to be 64kB -> WAMR needs a good amount of RAM to run.
|
||||
*
|
||||
* WASM files can be linked to use just a part of the first page.
|
||||
* In this case the VM can be run with less ram.
|
||||
* (see `wasm_sample/Makefile` in `examples/wasm` for linker options to help with this)
|
||||
* While running the example configured with 8KiB Heap and 8KiB Stack,
|
||||
* ~24KiB of System Heap are used.
|
||||
* The thread, the WAMR interpreter (iwasm) is executed in,
|
||||
* should be configured to have more than 3KiB of Stack,
|
||||
* this also depend on the architecture and the native functions that are called.
|
||||
*
|
||||
* ## building wasm-bytecode
|
||||
*
|
||||
* `clang` and `wasm-ld` of the *same version* must be used
|
||||
* The Makefile in `examples/wasm/wasm_sample/Makefile` will try to guess
|
||||
* a matching clang, wasm-ld pair, if they do not match linking will fail.
|
||||
*
|
||||
* ## Configuration
|
||||
*
|
||||
* WAMR compilation is configured using a CMAKE config file (see `pkg/wamr/config.cmake`)
|
||||
* Add `export WAMR_CONFIG := $(abspath config.cmake)` to Makefile to apply a specific config.
|
||||
* Most options (e.g. WASI) are not supported in RIOT since they have OS requirements,
|
||||
* that are no yet fulfilled.
|
||||
*
|
||||
* ## Usage Details
|
||||
*
|
||||
* WAMR should be used using the functions provided by the WAMR project their API-headers
|
||||
* they can be found in `<RIOT>/build/pkg/wamr/core/iwasm/include/`.
|
||||
* pkg/wamr adds no RIOT specific API to that.
|
||||
* For simple usages like in the example `iwasm.c` in `examples/wasm` might be useful and
|
||||
* if used should be copied and adapt to the application need.
|
||||
*
|
||||
* While WebAssembly does not define a set native functions. WAMR provides its own builtin-libc.
|
||||
* Other native functions may be provided by registering native_api to WAMR.
|
||||
* @see https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/export_native_api.md
|
||||
*
|
||||
* ### Why is there no RIOT specific API?
|
||||
*
|
||||
* many use cases more complex than: take that Bytecode and run its main would require
|
||||
* a application specific usage pattern of the WAMR-API
|
||||
* (memory setup, function search, parameter, module-loading/unloading)
|
||||
* the WAMR-API does this well and they provide a second wasm-c-api compatible API.
|
||||
*
|
||||
* `iwasm.c` might therefore be a good starting point (copy) but it is no good
|
||||
* generic interface to WAMR. Making it good and generic would lead to the API
|
||||
* provided by WAMR.
|
||||
*
|
||||
* ## Upstream Documentation
|
||||
*
|
||||
* @see https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/README.md
|
||||
* @see https://github.com/bytecodealliance/wasm-micro-runtime/tree/main/doc
|
||||
* @see https://github.com/bytecodealliance/wasm-micro-runtime/wiki
|
||||
*
|
||||
* @see https://github.com/WebAssembly/wasm-c-api
|
||||
* Include Headers:
|
||||
* @see https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/core/iwasm/include/
|
||||
*
|
||||
*/
|
Loading…
Reference in New Issue
Block a user