mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 15:05:19 +00:00
Add an example of how to embed WAMR in Zephyr user mode (#3998)
This commit is contained in:
parent
1958808a24
commit
1807eec9d2
|
@ -32,7 +32,8 @@ if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (NOT DEFINED WAMR_BUILD_LIBC_WASI)
|
if (NOT DEFINED WAMR_BUILD_LIBC_WASI)
|
||||||
# Disable libc wasi support by default
|
# Disable libc wasi support by default, in the future,
|
||||||
|
# it can be enabled if libc wasi file/socket/lock support is ready on Zephyr platform
|
||||||
set (WAMR_BUILD_LIBC_WASI 0)
|
set (WAMR_BUILD_LIBC_WASI 0)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
15
product-mini/platforms/zephyr/user-mode/CMakeLists.txt
Normal file
15
product-mini/platforms/zephyr/user-mode/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.13.1)
|
||||||
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
|
||||||
|
project(wamr_user_mode LANGUAGES C)
|
||||||
|
|
||||||
|
# Add the wamr-lib directory
|
||||||
|
add_subdirectory(lib-wamr-zephyr)
|
||||||
|
|
||||||
|
# Link the wamr library to the app target
|
||||||
|
target_link_libraries(app PRIVATE wamr_lib)
|
||||||
|
|
||||||
|
target_sources(app PRIVATE src/main.c)
|
60
product-mini/platforms/zephyr/user-mode/README.md
Normal file
60
product-mini/platforms/zephyr/user-mode/README.md
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
# How to use WAMR with Zephyr in user mode
|
||||||
|
|
||||||
|
This example demonstrates how to build and run a WebAssembly application in user mode on Zephyr.
|
||||||
|
|
||||||
|
> Note: The user mode is not supported on all Zephyr boards. Please refer to the Zephyr documentation for more information.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
Please refer to the [previous WAMR Zephyr README.md](../simple/README.md) for general Zephyr setup instructions.
|
||||||
|
|
||||||
|
And refer to [official documentation of Zephyr user mode](https://docs.zephyrproject.org/latest/kernel/usermode/index.html) for more information about Zephyr user mode.
|
||||||
|
|
||||||
|
### Enable user mode
|
||||||
|
|
||||||
|
To enable Zephyr user mode, set the `CONFIG_USERSPACE` option to yes in the Zephyr configuration.
|
||||||
|
|
||||||
|
```conf
|
||||||
|
CONFIG_USERSPACE=y
|
||||||
|
```
|
||||||
|
|
||||||
|
And link the WAMR runtime as a separate library in CMakelists.txt.
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
...WAMR CMake set up...
|
||||||
|
|
||||||
|
zephyr_library_named (wamr_lib)
|
||||||
|
|
||||||
|
zephyr_library_sources (
|
||||||
|
${WAMR_RUNTIME_LIB_SOURCE}
|
||||||
|
wamr_lib.c
|
||||||
|
)
|
||||||
|
|
||||||
|
zephyr_library_app_memory (wamr_partition)
|
||||||
|
```
|
||||||
|
|
||||||
|
The `wamr_partition` is a memory partition that will be granted to the WAMR runtime. It is defined in the Zephyr application code.
|
||||||
|
|
||||||
|
```C
|
||||||
|
K_APPMEM_PARTITION_DEFINE(wamr_partition);
|
||||||
|
```
|
||||||
|
|
||||||
|
When creating a Zephyr thread, set the thread option to `K_USER` and the timeout to `K_FOREVER`. This can ensure that the `wamr_partition` is granted access to the thread before starting it with `k_thread_start`.
|
||||||
|
|
||||||
|
### Advantage of using WAMR runtime in Zephyr user mode thread
|
||||||
|
|
||||||
|
In a user-mode Zephyr thread, the application can only access a restricted partition of memory it granted to. It creates a sandbox for the WAMR runtime to run in, and the WAMR runtime can only access that memory space, meaning that all global variables in the WAMR runtime and both runtime and wasm app heap memory will be allocated from it. In this way, an extra layer of security is added to the wasm application on top of the wasm sandbox provided by WAMR.
|
||||||
|
|
||||||
|
### Example Targets
|
||||||
|
|
||||||
|
x86_64 QEMU (x86_64) is a 64-bit x86 target for emulating the x86_64 platform.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
west build -b qemu_x86_tiny . -p always -- -DWAMR_BUILD_TARGET=X86_32
|
||||||
|
```
|
||||||
|
|
||||||
|
Use qemu to run the image.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
qemu-system-i386 -m 32 -cpu qemu32,+nx,+pae -machine pc -device isa-debug-exit,iobase=0xf4,iosize=0x04 -no-reboot -nographic -net none -pidfile qemu.pid -chardev stdio,id=con,mux=on -serial chardev:con -mon chardev=con,mode=readline -icount shift=5,align=off,sleep=off -rtc clock=vm -kernel ./build/zephyr/zephyr.elf
|
||||||
|
```
|
|
@ -0,0 +1,63 @@
|
||||||
|
# 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 (WAMR_BUILD_PLATFORM "zephyr")
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
# Enable AOT by default.
|
||||||
|
set (WAMR_BUILD_AOT 1)
|
||||||
|
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, in the future,
|
||||||
|
# it can be enabled if libc wasi file/socket/lock support is ready on Zephyr platform
|
||||||
|
set (WAMR_BUILD_LIBC_WASI 0)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (WAMR_BUILD_TARGET STREQUAL "RISCV64_LP64" OR WAMR_BUILD_TARGET STREQUAL "RISCV32_ILP32")
|
||||||
|
set (WAMR_BUILD_FAST_INTERP 1)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Limited to global heap usage in Zephyr user mode
|
||||||
|
set (WAMR_BUILD_GLOBAL_HEAP_POOL 1)
|
||||||
|
|
||||||
|
# Override the global heap size for small devices
|
||||||
|
if (NOT DEFINED WAMR_BUILD_GLOBAL_HEAP_SIZE)
|
||||||
|
set (WAMR_BUILD_GLOBAL_HEAP_SIZE 40960) # 40 KB
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../..)
|
||||||
|
|
||||||
|
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||||
|
|
||||||
|
# Embed WAMR as a Zephyr library
|
||||||
|
zephyr_library_named (wamr_lib)
|
||||||
|
|
||||||
|
# Add source files to the library
|
||||||
|
zephyr_library_sources (
|
||||||
|
${WAMR_RUNTIME_LIB_SOURCE}
|
||||||
|
wamr_lib.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Specify the memory partition where all globals(including the WAMR global heap buffer)
|
||||||
|
# in the library should be placed. This partition will be defined in the app source code
|
||||||
|
# and added to the use-mode thread that uses the WAMR library.
|
||||||
|
zephyr_library_app_memory (wamr_partition)
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The byte array buffer is the file content of a test wasm binary file,
|
||||||
|
* which is compiled by wasi-sdk toolchain from C source file of:
|
||||||
|
* product-mini/app-samples/hello-world/main.c.
|
||||||
|
*/
|
||||||
|
unsigned char __aligned(4) wasm_test_file[] = {
|
||||||
|
0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x03, 0x60,
|
||||||
|
0x01, 0x7F, 0x01, 0x7F, 0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F, 0x60, 0x01,
|
||||||
|
0x7F, 0x00, 0x02, 0x31, 0x04, 0x03, 0x65, 0x6E, 0x76, 0x04, 0x70, 0x75,
|
||||||
|
0x74, 0x73, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x6D, 0x61, 0x6C,
|
||||||
|
0x6C, 0x6F, 0x63, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x70, 0x72,
|
||||||
|
0x69, 0x6E, 0x74, 0x66, 0x00, 0x01, 0x03, 0x65, 0x6E, 0x76, 0x04, 0x66,
|
||||||
|
0x72, 0x65, 0x65, 0x00, 0x02, 0x03, 0x02, 0x01, 0x01, 0x04, 0x05, 0x01,
|
||||||
|
0x70, 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x01, 0x06, 0x13, 0x03,
|
||||||
|
0x7F, 0x01, 0x41, 0xC0, 0x28, 0x0B, 0x7F, 0x00, 0x41, 0xBA, 0x08, 0x0B,
|
||||||
|
0x7F, 0x00, 0x41, 0xC0, 0x28, 0x0B, 0x07, 0x2C, 0x04, 0x06, 0x6D, 0x65,
|
||||||
|
0x6D, 0x6F, 0x72, 0x79, 0x02, 0x00, 0x0A, 0x5F, 0x5F, 0x64, 0x61, 0x74,
|
||||||
|
0x61, 0x5F, 0x65, 0x6E, 0x64, 0x03, 0x01, 0x0B, 0x5F, 0x5F, 0x68, 0x65,
|
||||||
|
0x61, 0x70, 0x5F, 0x62, 0x61, 0x73, 0x65, 0x03, 0x02, 0x04, 0x6D, 0x61,
|
||||||
|
0x69, 0x6E, 0x00, 0x04, 0x0A, 0xB2, 0x01, 0x01, 0xAF, 0x01, 0x01, 0x03,
|
||||||
|
0x7F, 0x23, 0x80, 0x80, 0x80, 0x80, 0x00, 0x41, 0x20, 0x6B, 0x22, 0x02,
|
||||||
|
0x24, 0x80, 0x80, 0x80, 0x80, 0x00, 0x41, 0x9B, 0x88, 0x80, 0x80, 0x00,
|
||||||
|
0x10, 0x80, 0x80, 0x80, 0x80, 0x00, 0x1A, 0x02, 0x40, 0x02, 0x40, 0x41,
|
||||||
|
0x80, 0x08, 0x10, 0x81, 0x80, 0x80, 0x80, 0x00, 0x22, 0x03, 0x0D, 0x00,
|
||||||
|
0x41, 0xA8, 0x88, 0x80, 0x80, 0x00, 0x10, 0x80, 0x80, 0x80, 0x80, 0x00,
|
||||||
|
0x1A, 0x41, 0x7F, 0x21, 0x04, 0x0C, 0x01, 0x0B, 0x20, 0x02, 0x20, 0x03,
|
||||||
|
0x36, 0x02, 0x10, 0x41, 0x80, 0x88, 0x80, 0x80, 0x00, 0x20, 0x02, 0x41,
|
||||||
|
0x10, 0x6A, 0x10, 0x82, 0x80, 0x80, 0x80, 0x00, 0x1A, 0x41, 0x00, 0x21,
|
||||||
|
0x04, 0x20, 0x03, 0x41, 0x04, 0x6A, 0x41, 0x00, 0x2F, 0x00, 0x91, 0x88,
|
||||||
|
0x80, 0x80, 0x00, 0x3B, 0x00, 0x00, 0x20, 0x03, 0x41, 0x00, 0x28, 0x00,
|
||||||
|
0x8D, 0x88, 0x80, 0x80, 0x00, 0x36, 0x00, 0x00, 0x20, 0x02, 0x20, 0x03,
|
||||||
|
0x36, 0x02, 0x00, 0x41, 0x93, 0x88, 0x80, 0x80, 0x00, 0x20, 0x02, 0x10,
|
||||||
|
0x82, 0x80, 0x80, 0x80, 0x00, 0x1A, 0x20, 0x03, 0x10, 0x83, 0x80, 0x80,
|
||||||
|
0x80, 0x00, 0x0B, 0x20, 0x02, 0x41, 0x20, 0x6A, 0x24, 0x80, 0x80, 0x80,
|
||||||
|
0x80, 0x00, 0x20, 0x04, 0x0B, 0x0B, 0x41, 0x01, 0x00, 0x41, 0x80, 0x08,
|
||||||
|
0x0B, 0x3A, 0x62, 0x75, 0x66, 0x20, 0x70, 0x74, 0x72, 0x3A, 0x20, 0x25,
|
||||||
|
0x70, 0x0A, 0x00, 0x31, 0x32, 0x33, 0x34, 0x0A, 0x00, 0x62, 0x75, 0x66,
|
||||||
|
0x3A, 0x20, 0x25, 0x73, 0x00, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77,
|
||||||
|
0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00, 0x6D, 0x61, 0x6C, 0x6C, 0x6F, 0x63,
|
||||||
|
0x20, 0x62, 0x75, 0x66, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x00
|
||||||
|
};
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned char __aligned(4) wasm_test_file[] = {
|
||||||
|
0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x03, 0x60,
|
||||||
|
0x01, 0x7F, 0x01, 0x7F, 0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F, 0x60, 0x01,
|
||||||
|
0x7F, 0x00, 0x02, 0x31, 0x04, 0x03, 0x65, 0x6E, 0x76, 0x04, 0x70, 0x75,
|
||||||
|
0x74, 0x73, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x6D, 0x61, 0x6C,
|
||||||
|
0x6C, 0x6F, 0x63, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x70, 0x72,
|
||||||
|
0x69, 0x6E, 0x74, 0x66, 0x00, 0x01, 0x03, 0x65, 0x6E, 0x76, 0x04, 0x66,
|
||||||
|
0x72, 0x65, 0x65, 0x00, 0x02, 0x03, 0x02, 0x01, 0x01, 0x04, 0x05, 0x01,
|
||||||
|
0x70, 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x01, 0x06, 0x12, 0x03,
|
||||||
|
0x7F, 0x01, 0x41, 0xC0, 0x01, 0x0B, 0x7F, 0x00, 0x41, 0x3A, 0x0B, 0x7F,
|
||||||
|
0x00, 0x41, 0xC0, 0x01, 0x0B, 0x07, 0x2C, 0x04, 0x06, 0x6D, 0x65, 0x6D,
|
||||||
|
0x6F, 0x72, 0x79, 0x02, 0x00, 0x04, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x04,
|
||||||
|
0x0A, 0x5F, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x65, 0x6E, 0x64, 0x03,
|
||||||
|
0x01, 0x0B, 0x5F, 0x5F, 0x68, 0x65, 0x61, 0x70, 0x5F, 0x62, 0x61, 0x73,
|
||||||
|
0x65, 0x03, 0x02, 0x0A, 0xB1, 0x01, 0x01, 0xAE, 0x01, 0x01, 0x03, 0x7F,
|
||||||
|
0x23, 0x80, 0x80, 0x80, 0x80, 0x00, 0x41, 0x20, 0x6B, 0x22, 0x02, 0x24,
|
||||||
|
0x80, 0x80, 0x80, 0x80, 0x00, 0x41, 0x9B, 0x80, 0x80, 0x80, 0x00, 0x10,
|
||||||
|
0x80, 0x80, 0x80, 0x80, 0x00, 0x1A, 0x02, 0x40, 0x02, 0x40, 0x41, 0x10,
|
||||||
|
0x10, 0x81, 0x80, 0x80, 0x80, 0x00, 0x22, 0x03, 0x0D, 0x00, 0x41, 0xA8,
|
||||||
|
0x80, 0x80, 0x80, 0x00, 0x10, 0x80, 0x80, 0x80, 0x80, 0x00, 0x1A, 0x41,
|
||||||
|
0x7F, 0x21, 0x04, 0x0C, 0x01, 0x0B, 0x20, 0x02, 0x20, 0x03, 0x36, 0x02,
|
||||||
|
0x10, 0x41, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x02, 0x41, 0x10, 0x6A,
|
||||||
|
0x10, 0x82, 0x80, 0x80, 0x80, 0x00, 0x1A, 0x41, 0x00, 0x21, 0x04, 0x20,
|
||||||
|
0x03, 0x41, 0x04, 0x6A, 0x41, 0x00, 0x2F, 0x00, 0x91, 0x80, 0x80, 0x80,
|
||||||
|
0x00, 0x3B, 0x00, 0x00, 0x20, 0x03, 0x41, 0x00, 0x28, 0x00, 0x8D, 0x80,
|
||||||
|
0x80, 0x80, 0x00, 0x36, 0x00, 0x00, 0x20, 0x02, 0x20, 0x03, 0x36, 0x02,
|
||||||
|
0x00, 0x41, 0x93, 0x80, 0x80, 0x80, 0x00, 0x20, 0x02, 0x10, 0x82, 0x80,
|
||||||
|
0x80, 0x80, 0x00, 0x1A, 0x20, 0x03, 0x10, 0x83, 0x80, 0x80, 0x80, 0x00,
|
||||||
|
0x0B, 0x20, 0x02, 0x41, 0x20, 0x6A, 0x24, 0x80, 0x80, 0x80, 0x80, 0x00,
|
||||||
|
0x20, 0x04, 0x0B, 0x0B, 0x40, 0x01, 0x00, 0x41, 0x00, 0x0B, 0x3A, 0x62,
|
||||||
|
0x75, 0x66, 0x20, 0x70, 0x74, 0x72, 0x3A, 0x20, 0x25, 0x70, 0x0A, 0x00,
|
||||||
|
0x31, 0x32, 0x33, 0x34, 0x0A, 0x00, 0x62, 0x75, 0x66, 0x3A, 0x20, 0x25,
|
||||||
|
0x73, 0x00, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C,
|
||||||
|
0x64, 0x21, 0x00, 0x6D, 0x61, 0x6C, 0x6C, 0x6F, 0x63, 0x20, 0x62, 0x75,
|
||||||
|
0x66, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x00
|
||||||
|
};
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "bh_platform.h"
|
||||||
|
#include "bh_assert.h"
|
||||||
|
#include "bh_log.h"
|
||||||
|
#include "bh_queue.h"
|
||||||
|
#include "wasm_export.h"
|
||||||
|
#if defined(BUILD_TARGET_RISCV64_LP64) || defined(BUILD_TARGET_RISCV32_ILP32)
|
||||||
|
#include "test_wasm_riscv64.h"
|
||||||
|
#else
|
||||||
|
#include "test_wasm.h"
|
||||||
|
#endif /* end of BUILD_TARGET_RISCV64_LP64 || BUILD_TARGET_RISCV32_ILP32 */
|
||||||
|
|
||||||
|
#if defined(BUILD_TARGET_RISCV64_LP64) || defined(BUILD_TARGET_RISCV32_ILP32)
|
||||||
|
#define CONFIG_GLOBAL_HEAP_BUF_SIZE 5120
|
||||||
|
#define CONFIG_APP_STACK_SIZE 512
|
||||||
|
#define CONFIG_APP_HEAP_SIZE 512
|
||||||
|
#else /* else of BUILD_TARGET_RISCV64_LP64 || BUILD_TARGET_RISCV32_ILP32 */
|
||||||
|
#define CONFIG_GLOBAL_HEAP_BUF_SIZE WASM_GLOBAL_HEAP_SIZE
|
||||||
|
#define CONFIG_APP_STACK_SIZE 8192
|
||||||
|
#define CONFIG_APP_HEAP_SIZE 8192
|
||||||
|
#endif /* end of BUILD_TARGET_RISCV64_LP64 || BUILD_TARGET_RISCV32_ILP32 */
|
||||||
|
|
||||||
|
static int app_argc;
|
||||||
|
static char **app_argv;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the unique main function from a WASM module instance
|
||||||
|
* and execute that function.
|
||||||
|
*
|
||||||
|
* @param module_inst the WASM module instance
|
||||||
|
* @param argc the number of arguments
|
||||||
|
* @param argv the arguments array
|
||||||
|
*
|
||||||
|
* @return true if the main function is called, false otherwise.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
wasm_application_execute_main(wasm_module_inst_t module_inst, int argc,
|
||||||
|
char *argv[]);
|
||||||
|
|
||||||
|
static void *
|
||||||
|
app_instance_main(wasm_module_inst_t module_inst)
|
||||||
|
{
|
||||||
|
const char *exception;
|
||||||
|
wasm_function_inst_t func;
|
||||||
|
wasm_exec_env_t exec_env;
|
||||||
|
unsigned argv[2] = { 0 };
|
||||||
|
|
||||||
|
if (wasm_runtime_lookup_function(module_inst, "main")
|
||||||
|
|| wasm_runtime_lookup_function(module_inst, "__main_argc_argv")) {
|
||||||
|
LOG_VERBOSE("Calling main function\n");
|
||||||
|
wasm_application_execute_main(module_inst, app_argc, app_argv);
|
||||||
|
}
|
||||||
|
else if ((func = wasm_runtime_lookup_function(module_inst, "app_main"))) {
|
||||||
|
exec_env =
|
||||||
|
wasm_runtime_create_exec_env(module_inst, CONFIG_APP_HEAP_SIZE);
|
||||||
|
if (!exec_env) {
|
||||||
|
os_printf("Create exec env failed\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_VERBOSE("Calling app_main function\n");
|
||||||
|
wasm_runtime_call_wasm(exec_env, func, 0, argv);
|
||||||
|
|
||||||
|
if (!wasm_runtime_get_exception(module_inst)) {
|
||||||
|
os_printf("result: 0x%x\n", argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_runtime_destroy_exec_env(exec_env);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
os_printf("Failed to lookup function main or app_main to call\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((exception = wasm_runtime_get_exception(module_inst)))
|
||||||
|
os_printf("%s\n", exception);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
|
||||||
|
static char global_heap_buf[CONFIG_GLOBAL_HEAP_BUF_SIZE] = { 0 };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
iwasm_main(void *arg1, void *arg2, void *arg3)
|
||||||
|
{
|
||||||
|
int start, end;
|
||||||
|
start = k_uptime_get_32();
|
||||||
|
uint8 *wasm_file_buf = NULL;
|
||||||
|
uint32 wasm_file_size;
|
||||||
|
wasm_module_t wasm_module = NULL;
|
||||||
|
wasm_module_inst_t wasm_module_inst = NULL;
|
||||||
|
RuntimeInitArgs init_args;
|
||||||
|
char error_buf[128];
|
||||||
|
#if WASM_ENABLE_LOG != 0
|
||||||
|
int log_verbose_level = 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
(void)arg1;
|
||||||
|
(void)arg2;
|
||||||
|
(void)arg3;
|
||||||
|
|
||||||
|
os_printf("User mode thread: start\n");
|
||||||
|
|
||||||
|
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||||
|
|
||||||
|
#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
|
||||||
|
init_args.mem_alloc_type = Alloc_With_Pool;
|
||||||
|
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
|
||||||
|
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
|
||||||
|
#elif (defined(CONFIG_COMMON_LIBC_MALLOC) \
|
||||||
|
&& CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE != 0) \
|
||||||
|
|| defined(CONFIG_NEWLIB_LIBC)
|
||||||
|
init_args.mem_alloc_type = Alloc_With_System_Allocator;
|
||||||
|
#else
|
||||||
|
#error "memory allocation scheme is not defined."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* initialize runtime environment */
|
||||||
|
if (!wasm_runtime_full_init(&init_args)) {
|
||||||
|
printf("Init runtime environment failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_LOG != 0
|
||||||
|
bh_log_set_verbose_level(log_verbose_level);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* load WASM byte buffer from byte buffer of include file */
|
||||||
|
wasm_file_buf = (uint8 *)wasm_test_file;
|
||||||
|
wasm_file_size = sizeof(wasm_test_file);
|
||||||
|
|
||||||
|
/* load WASM module */
|
||||||
|
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
|
||||||
|
error_buf, sizeof(error_buf)))) {
|
||||||
|
printf("%s\n", error_buf);
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* instantiate the module */
|
||||||
|
if (!(wasm_module_inst = wasm_runtime_instantiate(
|
||||||
|
wasm_module, CONFIG_APP_STACK_SIZE, CONFIG_APP_HEAP_SIZE,
|
||||||
|
error_buf, sizeof(error_buf)))) {
|
||||||
|
printf("%s\n", error_buf);
|
||||||
|
goto fail2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* invoke the main function */
|
||||||
|
app_instance_main(wasm_module_inst);
|
||||||
|
|
||||||
|
/* destroy the module instance */
|
||||||
|
wasm_runtime_deinstantiate(wasm_module_inst);
|
||||||
|
|
||||||
|
fail2:
|
||||||
|
/* unload the module */
|
||||||
|
wasm_runtime_unload(wasm_module);
|
||||||
|
|
||||||
|
fail1:
|
||||||
|
/* destroy runtime environment */
|
||||||
|
wasm_runtime_destroy();
|
||||||
|
|
||||||
|
end = k_uptime_get_32();
|
||||||
|
|
||||||
|
os_printf("User mode thread: elapsed %d\n", (end - start));
|
||||||
|
}
|
9
product-mini/platforms/zephyr/user-mode/prj.conf
Normal file
9
product-mini/platforms/zephyr/user-mode/prj.conf
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
CONFIG_USERSPACE=y
|
||||||
|
CONFIG_STACK_SENTINEL=y
|
||||||
|
CONFIG_PRINTK=y
|
||||||
|
CONFIG_LOG=y
|
||||||
|
CONFIG_LOG_BUFFER_SIZE=8096
|
||||||
|
CONFIG_THREAD_RUNTIME_STATS=y
|
78
product-mini/platforms/zephyr/user-mode/src/main.c
Normal file
78
product-mini/platforms/zephyr/user-mode/src/main.c
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <zephyr/version.h>
|
||||||
|
#include <zephyr/app_memory/app_memdomain.h>
|
||||||
|
|
||||||
|
#define MAIN_THREAD_STACK_SIZE 2048
|
||||||
|
#define MAIN_THREAD_PRIORITY 5
|
||||||
|
|
||||||
|
static struct k_thread iwasm_user_mode_thread;
|
||||||
|
K_THREAD_STACK_DEFINE(iwasm_user_mode_thread_stack, MAIN_THREAD_STACK_SIZE);
|
||||||
|
|
||||||
|
extern struct k_mem_partition z_libc_partition;
|
||||||
|
K_APPMEM_PARTITION_DEFINE(wamr_partition);
|
||||||
|
|
||||||
|
/* WAMR memory domain */
|
||||||
|
struct k_mem_domain wamr_domain;
|
||||||
|
|
||||||
|
extern void
|
||||||
|
iwasm_main(void *arg1, void *arg2, void *arg3);
|
||||||
|
|
||||||
|
bool
|
||||||
|
iwasm_user_mode(void)
|
||||||
|
{
|
||||||
|
struct k_mem_partition *wamr_domain_parts[] = { &wamr_partition,
|
||||||
|
&z_libc_partition };
|
||||||
|
|
||||||
|
printk("wamr_partition start addr: %ld, size: %zu\n", wamr_partition.start,
|
||||||
|
wamr_partition.size);
|
||||||
|
|
||||||
|
/* Initialize the memory domain with single WAMR partition */
|
||||||
|
if (k_mem_domain_init(&wamr_domain, 2, wamr_domain_parts) != 0) {
|
||||||
|
printk("Failed to initialize memory domain.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
k_tid_t tid =
|
||||||
|
k_thread_create(&iwasm_user_mode_thread, iwasm_user_mode_thread_stack,
|
||||||
|
MAIN_THREAD_STACK_SIZE, iwasm_main, NULL, NULL, NULL,
|
||||||
|
MAIN_THREAD_PRIORITY, K_USER, K_FOREVER);
|
||||||
|
|
||||||
|
/* Grant WAMR memory domain access to user mode thread */
|
||||||
|
if (k_mem_domain_add_thread(&wamr_domain, tid) != 0) {
|
||||||
|
printk("Failed to add memory domain to thread.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if KERNEL_VERSION_NUMBER < 0x040000 /* version 4.0.0 */
|
||||||
|
/* k_thread_start is a legacy API for compatibility. Modern Zephyr threads
|
||||||
|
* are initialized in the "sleeping" state and do not need special handling
|
||||||
|
* for "start".*/
|
||||||
|
k_thread_start(tid);
|
||||||
|
#else
|
||||||
|
/* wakes up thread from sleeping */
|
||||||
|
k_wakeup(tid);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return tid ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if KERNEL_VERSION_NUMBER < 0x030400 /* version 3.4.0 */
|
||||||
|
void
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
iwasm_user_mode();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
iwasm_user_mode();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user