ESP IDF fixes (#927)

Various fixes and beautifications coordinated with @1c3t3a,
fixes 2 of the 3 all remaining issues from #892:
- enable to os_mmap executable memory
- fix os_malloc/os_realloc/os_free issues
- implement os_thread_get_stack_boundary
- add build scripts to include with esp-idf to use wamr as
  an ESP-IDF component
- update sample and document
This commit is contained in:
Stefan Wallentowitz
2022-01-05 05:50:17 +01:00
committed by GitHub
parent 2c3f284b85
commit 78414b627c
17 changed files with 345 additions and 196 deletions

View File

@ -0,0 +1,2 @@
sdkconfig
sdkconfig.old

View File

@ -1,77 +1,12 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# Copyright (C) 2019-21 Intel Corporation and others. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
# from ESP-IDF 4.0 examples/build_system/cmake/idf_as_lib
cmake_minimum_required(VERSION 3.5)
project(wamr_on_esp32c3)
enable_language(ASM)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif ()
set (COMPONENTS ${IDF_TARGET} main freertos esptool_py wamr)
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{WAMR_PATH}/build-scripts/esp-idf")
if("${IDF_TARGET}" STREQUAL "")
message(FATAL_ERROR "You need to set IDF_TARGET to your target string")
endif()
# Include for ESP-IDF build system functions
include($ENV{IDF_PATH}/tools/cmake/idf.cmake)
# Create idf::esp32c3 and idf::freertos static libraries
idf_build_process(${IDF_TARGET}
# try and trim the build; additional components
# will be included as needed based on dependency tree
#
# although esptool_py does not generate static library,
# processing the component is needed for flashing related
# targets and file generation
COMPONENTS ${IDF_TARGET} freertos esptool_py
SDKCONFIG ${CMAKE_BINARY_DIR}/sdkconfig
BUILD_DIR ${CMAKE_BINARY_DIR})
# Set WAMR's build options
if("${IDF_TARGET}" STREQUAL "esp32c3")
set(WAMR_BUILD_TARGET "RISCV32")
else()
set(WAMR_BUILD_TARGET "XTENSA")
add_compile_options(-DWAMR_BUILD_TARGET_XTENSA=1)
endif()
set(WAMR_BUILD_PLATFORM "esp-idf")
if (NOT DEFINED WAMR_BUILD_INTERP)
set (WAMR_BUILD_INTERP 0)
endif ()
if (NOT DEFINED WAMR_BUILD_FAST_INTERP)
set (WAMR_BUILD_FAST_INTERP 0)
endif ()
if (NOT DEFINED WAMR_BUILD_AOT)
set (WAMR_BUILD_AOT 1)
endif ()
if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN)
set (WAMR_BUILD_LIBC_BUILTIN 1)
endif ()
if (NOT DEFINED WAMR_BUILD_APP_FRAMEWORK)
set (WAMR_BUILD_APP_FRAMEWORK 0)
endif ()
# Set the compile time variable so that the right binary is selected
add_compile_options(-DWAMR_BUILD_INTERP=${WAMR_BUILD_INTERP})
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
include(${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
# define WAMR as library and provide it the esp-idf srcs
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
target_link_libraries(vmlib PUBLIC idf::pthread idf::${IDF_TARGET} idf::freertos)
# Define the final executable
set(elf_file ${CMAKE_PROJECT_NAME}.elf)
add_executable(${elf_file} main.c test_wasm.h)
target_link_libraries(${elf_file} idf::${IDF_TARGET} idf::freertos idf::spi_flash vmlib)
idf_build_executable(${elf_file})
project(wamr-simple)

View File

@ -1,4 +0,0 @@
rm -rf build && mkdir build && cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=$IDF_PATH/tools/cmake/toolchain-esp32c3.cmake -DIDF_TARGET=esp32c3 -DCMAKE_BUILD_TYPE=Release -GNinja
cmake --build .
ninja flash

View File

@ -0,0 +1,33 @@
#!/bin/bash -e
# Copyright (C) 2019-21 Intel Corporation and others. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
ESP32_TARGET="esp32"
ESP32C3_TARGET="esp32c3"
usage ()
{
echo "USAGE:"
echo "$0 $ESP32_TARGET|$ESP32C3_TARGET"
echo "Example:"
echo " $0 $ESP32_TARGET"
echo " $0 $ESP32C3_TARGET"
exit 1
}
if [ $# != 1 ] ; then
usage
fi
TARGET=$1
if [[ -z "${WAMR_PATH}" ]]; then
export WAMR_PATH=$PWD/../../..
fi
rm -rf build
idf.py set-target $TARGET
idf.py build
idf.py flash

View File

@ -1,105 +0,0 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "wasm_export.h"
#include "bh_platform.h"
#include "test_wasm.h"
static void *
app_instance_main(wasm_module_inst_t module_inst)
{
const char *exception;
wasm_application_execute_main(module_inst, 0, NULL);
if ((exception = wasm_runtime_get_exception(module_inst)))
printf("%s\n", exception);
return NULL;
}
void *
iwasm_main(void *arg)
{
(void)arg; /* unused */
/* setup variables for instantiating and running the wasm module */
uint8_t *wasm_file_buf = NULL;
unsigned wasm_file_buf_size = 0;
wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL;
char error_buf[128];
void *ret;
RuntimeInitArgs init_args;
/* configure memory allocation */
memset(&init_args, 0, sizeof(RuntimeInitArgs));
init_args.mem_alloc_type = Alloc_With_Allocator;
init_args.mem_alloc_option.allocator.malloc_func = (void *)os_malloc;
init_args.mem_alloc_option.allocator.realloc_func = (void *)os_realloc;
init_args.mem_alloc_option.allocator.free_func = (void *)os_free;
printf("wasm_runtime_full_init\n");
/* initialize runtime environment */
if (!wasm_runtime_full_init(&init_args)) {
printf("Init runtime failed.\n");
return NULL;
}
/* load WASM byte buffer from byte buffer of include file */
printf("use an internal test file, that's going to output Hello World\n");
wasm_file_buf = (uint8_t *)wasm_test_file;
wasm_file_buf_size = sizeof(wasm_test_file);
/* load WASM module */
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_buf_size,
error_buf, sizeof(error_buf)))) {
printf("Error in wasm_runtime_load: %s\n", error_buf);
goto fail1;
}
printf("about to call wasm_runtime_instantiate\n");
if (!(wasm_module_inst =
wasm_runtime_instantiate(wasm_module, 32 * 1024, // stack size
32 * 1024, // heap size
error_buf, sizeof(error_buf)))) {
printf("Error while instantiating: %s\n", error_buf);
goto fail2;
}
printf("run main() of the application\n");
ret = app_instance_main(wasm_module_inst);
assert(!ret);
/* destroy the module instance */
printf("wasm_runtime_deinstantiate\n");
wasm_runtime_deinstantiate(wasm_module_inst);
fail2:
/* unload the module */
printf("wasm_runtime_unload\n");
wasm_runtime_unload(wasm_module);
fail1:
/* destroy runtime environment */
printf("wasm_runtime_destroy\n");
wasm_runtime_destroy();
return NULL;
}
void
app_main(void)
{
pthread_t t;
int res;
res = pthread_create(&t, NULL, iwasm_main, (void *)NULL);
assert(res == 0);
res = pthread_join(t, NULL);
assert(res == 0);
printf("Exiting... \n");
}

View File

@ -0,0 +1,6 @@
# Copyright (C) 2021 Intel Corporation and others. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
idf_component_register(SRCS "main.c"
INCLUDE_DIRS "."
REQUIRES wamr)

View File

@ -0,0 +1,154 @@
/*
* Copyright (C) 2019-21 Intel Corporation and others. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "wasm_export.h"
#include "bh_platform.h"
#include "test_wasm.h"
#include "esp_log.h"
#define LOG_TAG "wamr"
static void *
app_instance_main(wasm_module_inst_t module_inst)
{
const char *exception;
wasm_application_execute_main(module_inst, 0, NULL);
if ((exception = wasm_runtime_get_exception(module_inst)))
printf("%s\n", exception);
return NULL;
}
void *
iwasm_main(void *arg)
{
(void)arg; /* unused */
/* setup variables for instantiating and running the wasm module */
uint8_t *wasm_file_buf = NULL;
unsigned wasm_file_buf_size = 0;
wasm_module_t wasm_module = NULL;
wasm_module_inst_t wasm_module_inst = NULL;
char error_buf[128];
void *ret;
RuntimeInitArgs init_args;
/* configure memory allocation */
memset(&init_args, 0, sizeof(RuntimeInitArgs));
init_args.mem_alloc_type = Alloc_With_Allocator;
init_args.mem_alloc_option.allocator.malloc_func = (void *)os_malloc;
init_args.mem_alloc_option.allocator.realloc_func = (void *)os_realloc;
init_args.mem_alloc_option.allocator.free_func = (void *)os_free;
ESP_LOGI(LOG_TAG, "Initialize WASM runtime");
/* initialize runtime environment */
if (!wasm_runtime_full_init(&init_args)) {
ESP_LOGE(LOG_TAG, "Init runtime failed.");
return NULL;
}
#if WASM_ENABLE_INTERP != 0
ESP_LOGI(LOG_TAG, "Run wamr with interpreter");
wasm_file_buf = (uint8_t *)wasm_test_file_interp;
wasm_file_buf_size = sizeof(wasm_test_file_interp);
/* load WASM module */
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_buf_size,
error_buf, sizeof(error_buf)))) {
ESP_LOGE(LOG_TAG, "Error in wasm_runtime_load: %s", error_buf);
goto fail1interp;
}
ESP_LOGI(LOG_TAG, "Instantiate WASM runtime");
if (!(wasm_module_inst =
wasm_runtime_instantiate(wasm_module, 32 * 1024, // stack size
32 * 1024, // heap size
error_buf, sizeof(error_buf)))) {
ESP_LOGE(LOG_TAG, "Error while instantiating: %s", error_buf);
goto fail2interp;
}
ESP_LOGI(LOG_TAG, "run main() of the application");
ret = app_instance_main(wasm_module_inst);
assert(!ret);
/* destroy the module instance */
ESP_LOGI(LOG_TAG, "Deinstantiate WASM runtime");
wasm_runtime_deinstantiate(wasm_module_inst);
fail2interp:
/* unload the module */
ESP_LOGI(LOG_TAG, "Unload WASM module");
wasm_runtime_unload(wasm_module);
fail1interp:
#endif
#if WASM_ENABLE_AOT != 0
ESP_LOGI(LOG_TAG, "Run wamr with AoT");
wasm_file_buf = (uint8_t *)wasm_test_file_aot;
wasm_file_buf_size = sizeof(wasm_test_file_aot);
/* load WASM module */
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_buf_size,
error_buf, sizeof(error_buf)))) {
ESP_LOGE(LOG_TAG, "Error in wasm_runtime_load: %s", error_buf);
goto fail1aot;
}
ESP_LOGI(LOG_TAG, "Instantiate WASM runtime");
if (!(wasm_module_inst =
wasm_runtime_instantiate(wasm_module, 32 * 1024, // stack size
32 * 1024, // heap size
error_buf, sizeof(error_buf)))) {
ESP_LOGE(LOG_TAG, "Error while instantiating: %s", error_buf);
goto fail2aot;
}
ESP_LOGI(LOG_TAG, "run main() of the application");
ret = app_instance_main(wasm_module_inst);
assert(!ret);
/* destroy the module instance */
ESP_LOGI(LOG_TAG, "Deinstantiate WASM runtime");
wasm_runtime_deinstantiate(wasm_module_inst);
fail2aot:
/* unload the module */
ESP_LOGI(LOG_TAG, "Unload WASM module");
wasm_runtime_unload(wasm_module);
fail1aot:
#endif
/* destroy runtime environment */
ESP_LOGI(LOG_TAG, "Destroy WASM runtime");
wasm_runtime_destroy();
return NULL;
}
void
app_main(void)
{
pthread_t t;
int res;
pthread_attr_t tattr;
pthread_attr_init(&tattr);
pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
pthread_attr_setstacksize(&tattr, 4096);
res = pthread_create(&t, &tattr, iwasm_main, (void *)NULL);
assert(res == 0);
res = pthread_join(t, NULL);
assert(res == 0);
ESP_LOGI(LOG_TAG, "Exiting...");
}

View File

@ -1,16 +1,10 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* Copyright (C) 2019-21 Intel Corporation and others. 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[] = {
// binary for the interpreter
#if WAMR_BUILD_INTERP != 0
#if WASM_ENABLE_INTERP != 0
unsigned char __aligned(4) wasm_test_file_interp[] = {
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,
@ -45,8 +39,13 @@ unsigned char __aligned(4) wasm_test_file[] = {
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
// binary for the xtensa aot compiler
#elif WAMR_BUILD_TARGET_XTENSA != 0
};
#endif
#if WASM_ENABLE_AOT != 0
#if BUILD_TARGET_XTENSA != 0
// XTENSA
unsigned char __aligned(4) wasm_test_file_aot[] = {
0x00, 0x61, 0x6F, 0x74, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x5E, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -156,8 +155,10 @@ unsigned char __aligned(4) wasm_test_file[] = {
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00
// binary for the riscv aot compiler
};
#else
// RISC-V
unsigned char __aligned(4) wasm_test_file_aot[] = {
0x00, 0x61, 0x6F, 0x74, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xF3, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -282,5 +283,6 @@ unsigned char __aligned(4) wasm_test_file[] = {
0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0xE8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00
#endif
};
#endif
#endif

View File

@ -0,0 +1,2 @@
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
# CONFIG_ESP_SYSTEM_MEMPROT_FEATURE is not set

View File

@ -0,0 +1 @@
# CONFIG_ESP32_MEMPROT_FEATURE is not set

View File

@ -0,0 +1 @@
# CONFIG_ESP32C3_MEMPROT_FEATURE is not set