diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..0e82e0b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.vscode +**/*build/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..565b740e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +# Currently supports clang-8 compiler +# Using the "test.c" app from the README.md: +# clang-8 --target=wasm32 -O3 -Wl,--initial-memory=131072,--allow-undefined,--export=main,--no-threads,--strip-all,--no-entry -nostdlib -o test.wasm test.c +# Pay attention to spacing above! ^ +# iwasm test.wasm + +FROM ubuntu:latest + +RUN apt-get update && \ + apt-get -y upgrade && \ + apt-get install -y build-essential clang-8 cmake g++-multilib git lib32gcc-5-dev llvm-8 lld-8 nano + +WORKDIR /root + +RUN git clone https://github.com/intel/wasm-micro-runtime + +RUN cd wasm-micro-runtime/core/iwasm/products/linux/ && mkdir build && \ + cd build && cmake .. && make + +RUN cd /usr/bin && ln -s wasm-ld-8 wasm-ld +RUN cd /usr/bin && ln -s ~/wasm-micro-runtime/core/iwasm/products/linux/build/iwasm iwasm diff --git a/README.md b/README.md index fed5aa90..f7c9bbdb 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,52 @@ cd build cmake .. make ``` + +Mac +------------------------- +Make sure to install Xcode from App Store firstly, and install cmake. + +If you use Homebrew, install cmake from the command line: +``` Bash +brew install cmake +``` + +Then build the source codes: +``` +cd core/iwasm/products/darwin/ +mkdir build +cd build +cmake .. +make +``` + +VxWorks +------------------------- +VxWorks 7 SR0620 release is validated. + +First you need to build a VSB. Make sure *UTILS_UNIX* layer is added in the VSB. +After the VSB is built, export the VxWorks toolchain path by: +``` +export /host/vx-compiler/bin:$PATH +``` +Now switch to iwasm source tree to build the source code: +``` +cd core/iwasm/products/vxworks/ +mkdir build +cd build +cmake .. +make +``` +Create a VIP based on the VSB. Make sure the following components are added: +* INCLUDE_POSIX_PTHREADS +* INCLUDE_POSIX_PTHREAD_SCHEDULER +* INCLUDE_SHARED_DATA +* INCLUDE_SHL + +Copy the generated iwasm executable, the test WASM binary as well as the needed +shared libraries (libc.so.1, libllvm.so.1 or libgnu.so.1 depending on the VSB, +libunix.so.1) to a supported file system (eg: romfs). + Zephyr ------------------------- You need to download the Zephyr source code first and embed WAMR into it. @@ -124,6 +170,23 @@ AliOS-Things ``` 9. download the binary to developerkit board, check the output from serial port +Docker +------------------------- +[Docker](https://www.docker.com/) will download all the dependencies and build WAMR Core on your behalf. + +Make sure you have Docker installed on your machine: [macOS](https://docs.docker.com/docker-for-mac/install/), [Windows](https://docs.docker.com/docker-for-windows/install/) or [Linux](https://docs.docker.com/install/linux/docker-ce/ubuntu/). + +Build the Docker image: + +``` Bash +docker build --rm -f "Dockerfile" -t wamr:latest . +``` +Run the image in interactive mode: +``` Bash +docker run --rm -it wamr:latest +``` +You'll now enter the container at `/root`. + Build WASM app ========================= You can write a simple ```test.c``` as the first sample. @@ -154,7 +217,7 @@ int main(int argc, char **argv) } ``` -There are two methods to build a WASM binary. One is using Emscripten tool, another is using clang compiler. +There are three methods to build a WASM binary. They are Emscripten, the clang compiler and Docker. ## Use Emscripten tool @@ -215,12 +278,25 @@ clang-8 --target=wasm32 -O3 -Wl,--initial-memory=131072,--allow-undefined,--expo You will get ```test.wasm``` which is the WASM app binary. +## Using Docker + +The last method availble is using [Docker](https://www.docker.com/). We assume you've already configured Docker (see Platform section above) and have a running interactive shell. Currently the Dockerfile only supports compiling apps with clang, with Emscripten planned for the future. + +Use the clang-8 command below to build the WASM C source code into the WASM binary. + +```Bash +clang-8 --target=wasm32 -O3 -Wl,--initial-memory=131072,--allow-undefined,--export=main, +--no-threads,--strip-all,--no-entry -nostdlib -o test.wasm test.c +``` + +You will get ```test.wasm``` which is the WASM app binary. + Run WASM app ======================== Assume you are using Linux, the command to run the test.wasm is: ``` Bash -cd iwasm/products/linux/bin +cd iwasm/products/linux/build ./iwasm test.wasm ``` You will get the following output: @@ -336,15 +412,42 @@ void api_timer_restart(user_timer_t timer, int interval); ``` **Library extension reference**
-Currently we provide the sensor API's as one library extension sample. In the header file ```lib/app-libs/extension/sensor/sensor.h```, the API set is defined as below: +Currently we provide several kinds of extension library for reference including sensor, connection and GUI. + +Sensor API: In the header file ```lib/app-libs/extension/sensor/sensor.h```, the API set is defined as below: ``` C sensor_t sensor_open(const char* name, int index, - void(*on_sensor_event)(sensor_t, attr_container_t *, void *), - void *user_data); + void(*on_sensor_event)(sensor_t, attr_container_t *, void *), + void *user_data); bool sensor_config(sensor_t sensor, int interval, int bit_cfg, int delay); bool sensor_config_with_attr_container(sensor_t sensor, attr_container_t *cfg); bool sensor_close(sensor_t sensor); ``` +Connection API: In the header file `lib/app-libs/extension/connection/connection.h.`, the API set is defined as below: +``` C +/* Connection event type */ +typedef enum { + /* Data is received */ + CONN_EVENT_TYPE_DATA = 1, + /* Connection is disconnected */ + CONN_EVENT_TYPE_DISCONNECT +} conn_event_type_t; + +typedef void (*on_connection_event_f)(connection_t *conn, + conn_event_type_t type, + const char *data, + uint32 len, + void *user_data); +connection_t *api_open_connection(const char *name, + attr_container_t *args, + on_connection_event_f on_event, + void *user_data); +void api_close_connection(connection_t *conn); +int api_send_on_connection(connection_t *conn, const char *data, uint32 len); +bool api_config_connection(connection_t *conn, attr_container_t *cfg); +``` +GUI API: The API's is list in header file ```lib/app-libs/extension/gui/wgl.h``` which is implemented based open soure 2D graphic library [LittlevGL](https://docs.littlevgl.com/en/html/index.html). Currently supported widgets include button, label, list and check box and more wigdet would be provided in future. + The mechanism of exporting native API to WASM application ======================================================= @@ -572,7 +675,9 @@ Please refer to the ```samples/simple``` folder for samples of WASM application 2D graphic user interface with LittlevGL ------------------------------------------------ -This sample demonstrates that a graphic user interface application in WebAssembly integrates the LittlevGL, an open-source embedded 2d graphic library. The sample source code is under ```samples/littlevgl``` +We have 2 samples for 2D graphic user interface. + +One of them demonstrates that a graphic user interface application in WebAssembly integrates the LittlevGL, an open-source embedded 2d graphic library. The sample source code is under ```samples/littlevgl``` In this sample, the LittlevGL source code is built into the WebAssembly code with the user application source files. The platform interfaces defined by LittlevGL is implemented in the runtime and exported to the application through the declarations from source "ext_lib_export.c" as below: @@ -595,6 +700,10 @@ Below pictures show the WASM application is running on an STM board with an LCD The sample also provides the native Linux version of application without the runtime under folder "vgl-native-ui-app". It can help to check differences between the implementations in native and WebAssembly. +The other sample demonstrates that a graphic user interface application in WebAssembly programming with WAMR graphic library(WGL), which is implemented based on LittlevGL, an open-source embedded 2d graphic library. The sample source code is under ```samples/gui``` + +Unlike `sample/littlevgl/val-wasm-runtime`, in this sample, the LittlevGL source code is built into the WAMR runtime and exported to Webassembly applicaton but not directly built into Webassembly application. And WGL provides a group of WebAssembly wrapper API's for user to write graphic application. These API's are listed in: `/core/iwasm/lib/app-libs/extension/gui/wgl.h`. Currently only a few API's are provided and there will be more. + Submit issues and contact the maintainers ========================================= diff --git a/core/app-mgr/app-manager/module_wasm_app.h b/core/app-mgr/app-manager/module_wasm_app.h index dbdf8052..077af05e 100644 --- a/core/app-mgr/app-manager/module_wasm_app.h +++ b/core/app-mgr/app-manager/module_wasm_app.h @@ -39,8 +39,11 @@ extern "C" { #define SECTION_TYPE_DATA 11 enum { - WASM_Msg_Start = BASE_EVENT_MAX, TIMER_EVENT_WASM, SENSOR_EVENT_WASM, - + WASM_Msg_Start = BASE_EVENT_MAX, + TIMER_EVENT_WASM, + SENSOR_EVENT_WASM, + CONNECTION_EVENT_WASM, + WIDGET_EVENT_WASM, WASM_Msg_End = WASM_Msg_Start + 100 }; diff --git a/core/iwasm/lib/3rdparty/LICENCE.txt b/core/iwasm/lib/3rdparty/LICENCE.txt new file mode 100644 index 00000000..beaef1d2 --- /dev/null +++ b/core/iwasm/lib/3rdparty/LICENCE.txt @@ -0,0 +1,8 @@ +MIT licence +Copyright (c) 2016 Gábor Kiss-Vámosi + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/core/iwasm/lib/3rdparty/lv_conf.h b/core/iwasm/lib/3rdparty/lv_conf.h new file mode 100755 index 00000000..acfca41f --- /dev/null +++ b/core/iwasm/lib/3rdparty/lv_conf.h @@ -0,0 +1,495 @@ +/** + * @file lv_conf.h + * + */ + +/* + * COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER + */ + +#if 1 /*Set it to "1" to enable content*/ + +#ifndef LV_CONF_H +#define LV_CONF_H +/* clang-format off */ + +#include + +/*==================== + Graphical settings + *====================*/ + +/* Maximal horizontal and vertical resolution to support by the library.*/ +#define LV_HOR_RES_MAX (320) +#define LV_VER_RES_MAX (240) + +/* Color depth: + * - 1: 1 byte per pixel + * - 8: RGB233 + * - 16: RGB565 + * - 32: ARGB8888 + */ +#define LV_COLOR_DEPTH 32 + +/* Swap the 2 bytes of RGB565 color. + * Useful if the display has a 8 bit interface (e.g. SPI)*/ +#define LV_COLOR_16_SWAP 0 + +/* 1: Enable screen transparency. + * Useful for OSD or other overlapping GUIs. + * Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/ +#define LV_COLOR_SCREEN_TRANSP 0 + +/*Images pixels with this color will not be drawn (with chroma keying)*/ +#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/ + +/* Enable anti-aliasing (lines, and radiuses will be smoothed) */ +#define LV_ANTIALIAS 1 + +/* Default display refresh period. + * Can be changed in the display driver (`lv_disp_drv_t`).*/ +#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/ + +/* Dot Per Inch: used to initialize default sizes. + * E.g. a button with width = LV_DPI / 2 -> half inch wide + * (Not so important, you can adjust it to modify default sizes and spaces)*/ +#define LV_DPI 100 /*[px]*/ + +/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */ +typedef int16_t lv_coord_t; + +/*========================= + Memory manager settings + *=========================*/ + +/* LittelvGL's internal memory manager's settings. + * The graphical objects and other related data are stored here. */ + +/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */ +#define LV_MEM_CUSTOM 1 +#if LV_MEM_CUSTOM == 0 +/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ +# define LV_MEM_SIZE (128U * 1024U) + +/* Complier prefix for a big array declaration */ +# define LV_MEM_ATTR + +/* Set an address for the memory pool instead of allocating it as an array. + * Can be in external SRAM too. */ +# define LV_MEM_ADR 0 + +/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */ +# define LV_MEM_AUTO_DEFRAG 1 +#else /*LV_MEM_CUSTOM*/ +# define LV_MEM_CUSTOM_INCLUDE "bh_memory.h" /*Header for the dynamic memory function*/ +# define LV_MEM_CUSTOM_ALLOC bh_malloc /*Wrapper to malloc*/ +# define LV_MEM_CUSTOM_FREE bh_free /*Wrapper to free*/ +#endif /*LV_MEM_CUSTOM*/ + +/* Garbage Collector settings + * Used if lvgl is binded to higher level language and the memory is managed by that language */ +#define LV_ENABLE_GC 0 +#if LV_ENABLE_GC != 0 +# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/ +# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/ +# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/ +#endif /* LV_ENABLE_GC */ + +/*======================= + Input device settings + *=======================*/ + +/* Input device default settings. + * Can be changed in the Input device driver (`lv_indev_drv_t`)*/ + +/* Input device read period in milliseconds */ +#define LV_INDEV_DEF_READ_PERIOD 30 + +/* Drag threshold in pixels */ +#define LV_INDEV_DEF_DRAG_LIMIT 10 + +/* Drag throw slow-down in [%]. Greater value -> faster slow-down */ +#define LV_INDEV_DEF_DRAG_THROW 20 + +/* Long press time in milliseconds. + * Time to send `LV_EVENT_LONG_PRESSSED`) */ +#define LV_INDEV_DEF_LONG_PRESS_TIME 400 + +/* Repeated trigger period in long press [ms] + * Time between `LV_EVENT_LONG_PRESSED_REPEAT */ +#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100 + +/*================== + * Feature usage + *==================*/ + +/*1: Enable the Animations */ +#define LV_USE_ANIMATION 1 +#if LV_USE_ANIMATION + +/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_anim_user_data_t; + +#endif + +/* 1: Enable shadow drawing*/ +#define LV_USE_SHADOW 1 + +/* 1: Enable object groups (for keyboard/encoder navigation) */ +#define LV_USE_GROUP 0 +#if LV_USE_GROUP +typedef void * lv_group_user_data_t; +#endif /*LV_USE_GROUP*/ + +/* 1: Enable GPU interface*/ +#define LV_USE_GPU 1 + +/* 1: Enable file system (might be required for images */ +#define LV_USE_FILESYSTEM 1 +#if LV_USE_FILESYSTEM +/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_fs_drv_user_data_t; +#endif + +/*1: Add a `user_data` to drivers and objects*/ +#define LV_USE_USER_DATA 0 + +/*======================== + * Image decoder and cache + *========================*/ + +/* 1: Enable indexed (palette) images */ +#define LV_IMG_CF_INDEXED 1 + +/* 1: Enable alpha indexed images */ +#define LV_IMG_CF_ALPHA 1 + +/* Default image cache size. Image caching keeps the images opened. + * If only the built-in image formats are used there is no real advantage of caching. + * (I.e. no new image decoder is added) + * With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images. + * However the opened images might consume additional RAM. + * LV_IMG_CACHE_DEF_SIZE must be >= 1 */ +#define LV_IMG_CACHE_DEF_SIZE 1 + +/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_img_decoder_user_data_t; + +/*===================== + * Compiler settings + *====================*/ +/* Define a custom attribute to `lv_tick_inc` function */ +#define LV_ATTRIBUTE_TICK_INC + +/* Define a custom attribute to `lv_task_handler` function */ +#define LV_ATTRIBUTE_TASK_HANDLER + +/* With size optimization (-Os) the compiler might not align data to + * 4 or 8 byte boundary. This alignment will be explicitly applied where needed. + * E.g. __attribute__((aligned(4))) */ +#define LV_ATTRIBUTE_MEM_ALIGN + +/* Attribute to mark large constant arrays for example + * font's bitmaps */ +#define LV_ATTRIBUTE_LARGE_CONST + +/*=================== + * HAL settings + *==================*/ + +/* 1: use a custom tick source. + * It removes the need to manually update the tick with `lv_tick_inc`) */ +#define LV_TICK_CUSTOM 1 +#if LV_TICK_CUSTOM == 1 +#define LV_TICK_CUSTOM_INCLUDE "bh_time.h" /*Header for the sys time function*/ +#define LV_TICK_CUSTOM_SYS_TIME_EXPR (_bh_time_get_boot_millisecond()) /*Expression evaluating to current systime in ms*/ +#endif /*LV_TICK_CUSTOM*/ + +typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/ +typedef void * lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/ + +/*================ + * Log settings + *===============*/ + +/*1: Enable the log module*/ +#define LV_USE_LOG 1 +#if LV_USE_LOG +/* How important log should be added: + * LV_LOG_LEVEL_TRACE A lot of logs to give detailed information + * LV_LOG_LEVEL_INFO Log important events + * LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem + * LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail + * LV_LOG_LEVEL_NONE Do not log anything + */ +# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN + +/* 1: Print the log with 'printf'; + * 0: user need to register a callback with `lv_log_register_print`*/ +# define LV_LOG_PRINTF 1 +#endif /*LV_USE_LOG*/ + +/*================ + * THEME USAGE + *================*/ +#define LV_THEME_LIVE_UPDATE 1 /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/ + +#define LV_USE_THEME_TEMPL 1 /*Just for test*/ +#define LV_USE_THEME_DEFAULT 1 /*Built mainly from the built-in styles. Consumes very few RAM*/ +#define LV_USE_THEME_ALIEN 1 /*Dark futuristic theme*/ +#define LV_USE_THEME_NIGHT 1 /*Dark elegant theme*/ +#define LV_USE_THEME_MONO 1 /*Mono color theme for monochrome displays*/ +#define LV_USE_THEME_MATERIAL 1 /*Flat theme with bold colors and light shadows*/ +#define LV_USE_THEME_ZEN 1 /*Peaceful, mainly light theme */ +#define LV_USE_THEME_NEMO 1 /*Water-like theme based on the movie "Finding Nemo"*/ + +/*================== + * FONT USAGE + *===================*/ + +/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel. + * The symbols are available via `LV_SYMBOL_...` defines + * More info about fonts: https://docs.littlevgl.com/#Fonts + * To create a new font go to: https://littlevgl.com/ttf-font-to-c-array + */ + +/* Robot fonts with bpp = 4 + * https://fonts.google.com/specimen/Roboto */ +#define LV_FONT_ROBOTO_12 1 +#define LV_FONT_ROBOTO_16 1 +#define LV_FONT_ROBOTO_22 1 +#define LV_FONT_ROBOTO_28 1 + +/*Pixel perfect monospace font + * http://pelulamu.net/unscii/ */ +#define LV_FONT_UNSCII_8 1 + +/* Optionally declare your custom fonts here. + * You can use these fonts as default font too + * and they will be available globally. E.g. + * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ + * LV_FONT_DECLARE(my_font_2) + */ +#define LV_FONT_CUSTOM_DECLARE + +/*Always set a default font from the built-in fonts*/ +#define LV_FONT_DEFAULT &lv_font_roboto_16 + +/* Enable it if you have fonts with a lot of characters. + * The limit depends on the font size, font face and bpp + * but with > 10,000 characters if you see issues probably you need to enable it.*/ +#define LV_FONT_FMT_TXT_LARGE 1 + +/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_font_user_data_t; + +/*================= + * Text settings + *=================*/ + +/* Select a character encoding for strings. + * Your IDE or editor should have the same character encoding + * - LV_TXT_ENC_UTF8 + * - LV_TXT_ENC_ASCII + * */ +#define LV_TXT_ENC LV_TXT_ENC_UTF8 + + /*Can break (wrap) texts on these chars*/ +#define LV_TXT_BREAK_CHARS " ,.;:-_" + +/*=================== + * LV_OBJ SETTINGS + *==================*/ + +/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_obj_user_data_t; + +/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/ +#define LV_USE_OBJ_REALIGN 1 + +/* Enable to make the object clickable on a larger area. + * LV_EXT_CLICK_AREA_OFF or 0: Disable this feature + * LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px) + * LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px) + */ +#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_FULL + +/*================== + * LV OBJ X USAGE + *================*/ +/* + * Documentation of the object types: https://docs.littlevgl.com/#Object-types + */ + +/*Arc (dependencies: -)*/ +#define LV_USE_ARC 1 + +/*Bar (dependencies: -)*/ +#define LV_USE_BAR 1 + +/*Button (dependencies: lv_cont*/ +#define LV_USE_BTN 1 +#if LV_USE_BTN != 0 +/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/ +# define LV_BTN_INK_EFFECT 1 +#endif + +/*Button matrix (dependencies: -)*/ +#define LV_USE_BTNM 1 + +/*Calendar (dependencies: -)*/ +#define LV_USE_CALENDAR 1 + +/*Canvas (dependencies: lv_img)*/ +#define LV_USE_CANVAS 1 + +/*Check box (dependencies: lv_btn, lv_label)*/ +#define LV_USE_CB 1 + +/*Chart (dependencies: -)*/ +#define LV_USE_CHART 1 +#if LV_USE_CHART +# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 20 +#endif + +/*Container (dependencies: -*/ +#define LV_USE_CONT 1 + +/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/ +#define LV_USE_DDLIST 1 +#if LV_USE_DDLIST != 0 +/*Open and close default animation time [ms] (0: no animation)*/ +# define LV_DDLIST_DEF_ANIM_TIME 200 +#endif + +/*Gauge (dependencies:lv_bar, lv_lmeter)*/ +#define LV_USE_GAUGE 1 + +/*Image (dependencies: lv_label*/ +#define LV_USE_IMG 1 + +/*Image Button (dependencies: lv_btn*/ +#define LV_USE_IMGBTN 1 +#if LV_USE_IMGBTN +/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/ +# define LV_IMGBTN_TILED 0 +#endif + +/*Keyboard (dependencies: lv_btnm)*/ +#define LV_USE_KB 1 + +/*Label (dependencies: -*/ +#define LV_USE_LABEL 1 +#if LV_USE_LABEL != 0 +/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/ +# define LV_LABEL_DEF_SCROLL_SPEED 25 + +/* Waiting period at beginning/end of animation cycle */ +# define LV_LABEL_WAIT_CHAR_COUNT 3 + +/*Enable selecting text of the label */ +# define LV_LABEL_TEXT_SEL 1 + +/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/ +# define LV_LABEL_LONG_TXT_HINT 0 +#endif + +/*LED (dependencies: -)*/ +#define LV_USE_LED 1 + +/*Line (dependencies: -*/ +#define LV_USE_LINE 1 + +/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/ +#define LV_USE_LIST 1 +#if LV_USE_LIST != 0 +/*Default animation time of focusing to a list element [ms] (0: no animation) */ +# define LV_LIST_DEF_ANIM_TIME 100 +#endif + +/*Line meter (dependencies: *;)*/ +#define LV_USE_LMETER 1 + +/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ +#define LV_USE_MBOX 1 + +/*Page (dependencies: lv_cont)*/ +#define LV_USE_PAGE 1 +#if LV_USE_PAGE != 0 +/*Focus default animation time [ms] (0: no animation)*/ +# define LV_PAGE_DEF_ANIM_TIME 400 +#endif + +/*Preload (dependencies: lv_arc, lv_anim)*/ +#define LV_USE_PRELOAD 1 +#if LV_USE_PRELOAD != 0 +# define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/ +# define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/ +# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC +#endif + +/*Roller (dependencies: lv_ddlist)*/ +#define LV_USE_ROLLER 1 +#if LV_USE_ROLLER != 0 +/*Focus animation time [ms] (0: no animation)*/ +# define LV_ROLLER_DEF_ANIM_TIME 200 + +/*Number of extra "pages" when the roller is infinite*/ +# define LV_ROLLER_INF_PAGES 7 +#endif + +/*Slider (dependencies: lv_bar)*/ +#define LV_USE_SLIDER 1 + +/*Spinbox (dependencies: lv_ta)*/ +#define LV_USE_SPINBOX 1 + +/*Switch (dependencies: lv_slider)*/ +#define LV_USE_SW 1 + +/*Text area (dependencies: lv_label, lv_page)*/ +#define LV_USE_TA 1 +#if LV_USE_TA != 0 +# define LV_TA_DEF_CURSOR_BLINK_TIME 400 /*ms*/ +# define LV_TA_DEF_PWD_SHOW_TIME 1500 /*ms*/ +#endif + +/*Table (dependencies: lv_label)*/ +#define LV_USE_TABLE 1 +#if LV_USE_TABLE +# define LV_TABLE_COL_MAX 12 +#endif + +/*Tab (dependencies: lv_page, lv_btnm)*/ +#define LV_USE_TABVIEW 1 +# if LV_USE_TABVIEW != 0 +/*Time of slide animation [ms] (0: no animation)*/ +# define LV_TABVIEW_DEF_ANIM_TIME 300 +#endif + +/*Tileview (dependencies: lv_page) */ +#define LV_USE_TILEVIEW 1 +#if LV_USE_TILEVIEW +/*Time of slide animation [ms] (0: no animation)*/ +# define LV_TILEVIEW_DEF_ANIM_TIME 300 +#endif + +/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ +#define LV_USE_WIN 1 + +/*================== + * Non-user section + *==================*/ + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/ +# define _CRT_SECURE_NO_WARNINGS +#endif + +/*--END OF LV_CONF_H--*/ + +/*Be sure every define has a default value*/ +#include "lvgl/src/lv_conf_checker.h" + +#endif /*LV_CONF_H*/ + +#endif /*End of "Content enable"*/ diff --git a/core/iwasm/lib/app-libs/base/wasm_app.h b/core/iwasm/lib/app-libs/base/wasm_app.h index 03c8460b..081b2bfe 100644 --- a/core/iwasm/lib/app-libs/base/wasm_app.h +++ b/core/iwasm/lib/app-libs/base/wasm_app.h @@ -37,7 +37,9 @@ #include "attr_container.h" #include "request.h" #include "sensor.h" +#include "connection.h" #include "timer_wasm_app.h" +#include "wgl.h" #ifdef __cplusplus extern "C" { diff --git a/core/iwasm/lib/app-libs/extension/connection/connection.c b/core/iwasm/lib/app-libs/extension/connection/connection.c new file mode 100644 index 00000000..1c7845d4 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/connection/connection.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "connection.h" +#include "native_interface.h" + +/* Raw connection structure */ +typedef struct _connection { + /* Next connection */ + struct _connection *next; + + /* Handle of the connection */ + uint32 handle; + + /* Callback function called when event on this connection occurs */ + on_connection_event_f on_event; + + /* User data */ + void *user_data; +} connection_t; + +/* Raw connections list */ +static connection_t *g_conns = NULL; + +connection_t *api_open_connection(const char *name, + attr_container_t *args, + on_connection_event_f on_event, + void *user_data) +{ + connection_t *conn; + char *args_buffer = (char *)args; + uint32 handle, args_len = attr_container_get_serialize_length(args); + + handle = wasm_open_connection((int32)name, (int32)args_buffer, args_len); + if (handle == -1) + return NULL; + + conn = (connection_t *)malloc(sizeof(*conn)); + if (conn == NULL) { + wasm_close_connection(handle); + return NULL; + } + + memset(conn, 0, sizeof(*conn)); + conn->handle = handle; + conn->on_event = on_event; + conn->user_data = user_data; + + if (g_conns != NULL) { + conn->next = g_conns; + g_conns = conn; + } else { + g_conns = conn; + } + + return conn; +} + +void api_close_connection(connection_t *c) +{ + connection_t *conn = g_conns, *prev = NULL; + + while (conn) { + if (conn == c) { + wasm_close_connection(c->handle); + if (prev != NULL) + prev->next = conn->next; + else + g_conns = conn->next; + free(conn); + return; + } else { + prev = conn; + conn = conn->next; + } + } +} + +int api_send_on_connection(connection_t *conn, const char *data, uint32 len) +{ + return wasm_send_on_connection(conn->handle, (int32)data, len); +} + +bool api_config_connection(connection_t *conn, attr_container_t *cfg) +{ + char *cfg_buffer = (char *)cfg; + uint32 cfg_len = attr_container_get_serialize_length(cfg); + + return wasm_config_connection(conn->handle, (int32)cfg_buffer, cfg_len); +} + +void on_connection_data(uint32 handle, char *buffer, uint32 len) +{ + connection_t *conn = g_conns; + + while (conn != NULL) { + if (conn->handle == handle) { + if (len == 0) { + conn->on_event(conn, + CONN_EVENT_TYPE_DISCONNECT, + NULL, + 0, + conn->user_data); + } else { + conn->on_event(conn, + CONN_EVENT_TYPE_DATA, + buffer, + len, + conn->user_data); + } + + return; + } + conn = conn->next; + } +} + diff --git a/core/iwasm/lib/app-libs/extension/connection/connection.h b/core/iwasm/lib/app-libs/extension/connection/connection.h new file mode 100644 index 00000000..d87352a2 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/connection/connection.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _CONNECTION_H_ +#define _CONNECTION_H_ + +#include "attr_container.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct _connection; +typedef struct _connection connection_t; + +/* Connection event type */ +typedef enum { + /* Data is received */ + CONN_EVENT_TYPE_DATA = 1, + /* Connection is disconnected */ + CONN_EVENT_TYPE_DISCONNECT +} conn_event_type_t; + +/* + * @typedef on_connection_event_f + * + * @param conn the connection that the event belongs to + * @param type event type + * @param data the data received for CONN_EVENT_TYPE_DATA event + * @param len length of the data in byte + * @param user_data user data + */ +typedef void (*on_connection_event_f)(connection_t *conn, + conn_event_type_t type, + const char *data, + uint32 len, + void *user_data); + +/* + ***************** + * Connection API's + ***************** + */ + +/* + * @brief Open a connection. + * + * @param name name of the connection, "TCP", "UDP" or "UART" + * @param args connection arguments, such as: ip:127.0.0.1, port:8888 + * @param on_event callback function called when event occurs + * @param user_data user data + * + * @return the connection or NULL means fail + */ +connection_t *api_open_connection(const char *name, + attr_container_t *args, + on_connection_event_f on_event, + void *user_data); + +/* + * @brief Close a connection. + * + * @param conn connection + */ +void api_close_connection(connection_t *conn); + +/* + * Send data to the connection in non-blocking manner which returns immediately + * + * @param conn the connection + * @param data data buffer to be sent + * @param len length of the data in byte + * + * @return actual length sent, or -1 if fail(maybe underlying buffer is full) + */ +int api_send_on_connection(connection_t *conn, const char *data, uint32 len); + +/* + * @brief Configure connection. + * + * @param conn the connection + * @param cfg configurations + * + * @return true if success, false otherwise + */ +bool api_config_connection(connection_t *conn, attr_container_t *cfg); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/iwasm/lib/app-libs/extension/gui/inc/LICENCE.txt b/core/iwasm/lib/app-libs/extension/gui/inc/LICENCE.txt new file mode 100644 index 00000000..beaef1d2 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/inc/LICENCE.txt @@ -0,0 +1,8 @@ +MIT licence +Copyright (c) 2016 Gábor Kiss-Vámosi + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/core/iwasm/lib/app-libs/extension/gui/inc/wgl_btn.h b/core/iwasm/lib/app-libs/extension/gui/inc/wgl_btn.h new file mode 100644 index 00000000..7cf8e9d6 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/inc/wgl_btn.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_BTN_H +#define WAMR_GRAPHIC_LIBRARY_BTN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** Possible states of a button. + * It can be used not only by buttons but other button-like objects too*/ +enum { + /**Released*/ + WGL_BTN_STATE_REL, + + /**Pressed*/ + WGL_BTN_STATE_PR, + + /**Toggled released*/ + WGL_BTN_STATE_TGL_REL, + + /**Toggled pressed*/ + WGL_BTN_STATE_TGL_PR, + + /**Inactive*/ + WGL_BTN_STATE_INA, + + /**Number of states*/ + _WGL_BTN_STATE_NUM, +}; +typedef uint8_t wgl_btn_state_t; + +/**Styles*/ +enum { + /** Release style */ + WGL_BTN_STYLE_REL, + + /**Pressed style*/ + WGL_BTN_STYLE_PR, + + /** Toggle released style*/ + WGL_BTN_STYLE_TGL_REL, + + /** Toggle pressed style */ + WGL_BTN_STYLE_TGL_PR, + + /** Inactive style*/ + WGL_BTN_STYLE_INA, +}; +typedef uint8_t wgl_btn_style_t; + + +/* Create a button */ +wgl_obj_t wgl_btn_create(wgl_obj_t par, wgl_obj_t copy); + +/*===================== + * Setter functions + *====================*/ + +/** + * Enable the toggled states. On release the button will change from/to toggled state. + * @param btn pointer to a button object + * @param tgl true: enable toggled states, false: disable + */ +void wgl_btn_set_toggle(wgl_obj_t btn, bool tgl); + +/** + * Set the state of the button + * @param btn pointer to a button object + * @param state the new state of the button (from wgl_btn_state_t enum) + */ +void wgl_btn_set_state(wgl_obj_t btn, wgl_btn_state_t state); + +/** + * Toggle the state of the button (ON->OFF, OFF->ON) + * @param btn pointer to a button object + */ +void wgl_btn_toggle(wgl_obj_t btn); + +/** + * Set time of the ink effect (draw a circle on click to animate in the new state) + * @param btn pointer to a button object + * @param time the time of the ink animation + */ +void wgl_btn_set_ink_in_time(wgl_obj_t btn, uint16_t time); + +/** + * Set the wait time before the ink disappears + * @param btn pointer to a button object + * @param time the time of the ink animation + */ +void wgl_btn_set_ink_wait_time(wgl_obj_t btn, uint16_t time); + +/** + * Set time of the ink out effect (animate to the released state) + * @param btn pointer to a button object + * @param time the time of the ink animation + */ +void wgl_btn_set_ink_out_time(wgl_obj_t btn, uint16_t time); + +/** + * Set a style of a button. + * @param btn pointer to button object + * @param type which style should be set + * @param style pointer to a style + * */ +//void wgl_btn_set_style(wgl_obj_t btn, wgl_btn_style_t type, const wgl_style_t * style); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the current state of the button + * @param btn pointer to a button object + * @return the state of the button (from wgl_btn_state_t enum) + */ +wgl_btn_state_t wgl_btn_get_state(wgl_obj_t btn); + +/** + * Get the toggle enable attribute of the button + * @param btn pointer to a button object + * @return true: toggle enabled, false: disabled + */ +bool wgl_btn_get_toggle(wgl_obj_t btn); + +/** + * Get time of the ink in effect (draw a circle on click to animate in the new state) + * @param btn pointer to a button object + * @return the time of the ink animation + */ +uint16_t wgl_btn_get_ink_in_time(wgl_obj_t btn); + +/** + * Get the wait time before the ink disappears + * @param btn pointer to a button object + * @return the time of the ink animation + */ +uint16_t wgl_btn_get_ink_wait_time(wgl_obj_t btn); + +/** + * Get time of the ink out effect (animate to the releases state) + * @param btn pointer to a button object + * @return the time of the ink animation + */ +uint16_t wgl_btn_get_ink_out_time(wgl_obj_t btn); + +/** + * Get style of a button. + * @param btn pointer to button object + * @param type which style should be get + * @return style pointer to the style + * */ +//const wgl_style_t * wgl_btn_get_style(const wgl_obj_t btn, wgl_btn_style_t type); +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_BTN_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/inc/wgl_cb.h b/core/iwasm/lib/app-libs/extension/gui/inc/wgl_cb.h new file mode 100644 index 00000000..40604f46 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/inc/wgl_cb.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_CB_H +#define WAMR_GRAPHIC_LIBRARY_CB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** Checkbox styles. */ +enum { + WGL_CB_STYLE_BG, /**< Style of object background. */ + WGL_CB_STYLE_BOX_REL, /**< Style of box (released). */ + WGL_CB_STYLE_BOX_PR, /**< Style of box (pressed). */ + WGL_CB_STYLE_BOX_TGL_REL, /**< Style of box (released but checked). */ + WGL_CB_STYLE_BOX_TGL_PR, /**< Style of box (pressed and checked). */ + WGL_CB_STYLE_BOX_INA, /**< Style of disabled box */ +}; +typedef uint8_t wgl_cb_style_t; + + +/** + * Create a check box objects + * @param par pointer to an object, it will be the parent of the new check box + * @param copy pointer to a check box object, if not NULL then the new object will be copied from it + * @return pointer to the created check box + */ +wgl_obj_t wgl_cb_create(wgl_obj_t par, const wgl_obj_t copy); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set the text of a check box. `txt` will be copied and may be deallocated + * after this function returns. + * @param cb pointer to a check box + * @param txt the text of the check box. NULL to refresh with the current text. + */ +void wgl_cb_set_text(wgl_obj_t cb, const char * txt); + +/** + * Set the text of a check box. `txt` must not be deallocated during the life + * of this checkbox. + * @param cb pointer to a check box + * @param txt the text of the check box. NULL to refresh with the current text. + */ +void wgl_cb_set_static_text(wgl_obj_t cb, const char * txt); + + +/*===================== + * Getter functions + *====================*/ + + +/** + * Get the length of the text of a check box + * @param label the check box object + * @return the length of the text of the check box + */ +unsigned int wgl_cb_get_text_length(wgl_obj_t cb); + +/** + * Get the text of a check box + * @param label the check box object + * @param buffer buffer to save the text + * @param buffer_len length of the buffer + * @return the text of the check box, note that the text will be truncated if buffer is not long enough + */ +char *wgl_cb_get_text(wgl_obj_t cb, char *buffer, int buffer_len); + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_CB_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/inc/wgl_label.h b/core/iwasm/lib/app-libs/extension/gui/inc/wgl_label.h new file mode 100644 index 00000000..7cb06550 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/inc/wgl_label.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_LABEL_H +#define WAMR_GRAPHIC_LIBRARY_LABEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** Long mode behaviors. Used in 'wgl_label_ext_t' */ +enum { + WGL_LABEL_LONG_EXPAND, /**< Expand the object size to the text size*/ + WGL_LABEL_LONG_BREAK, /**< Keep the object width, break the too long lines and expand the object + height*/ + WGL_LABEL_LONG_DOT, /**< Keep the size and write dots at the end if the text is too long*/ + WGL_LABEL_LONG_SROLL, /**< Keep the size and roll the text back and forth*/ + WGL_LABEL_LONG_SROLL_CIRC, /**< Keep the size and roll the text circularly*/ + WGL_LABEL_LONG_CROP, /**< Keep the size and crop the text out of it*/ +}; +typedef uint8_t wgl_label_long_mode_t; + +/** Label align policy*/ +enum { + WGL_LABEL_ALIGN_LEFT, /**< Align text to left */ + WGL_LABEL_ALIGN_CENTER, /**< Align text to center */ + WGL_LABEL_ALIGN_RIGHT, /**< Align text to right */ +}; +typedef uint8_t wgl_label_align_t; + +/** Label styles*/ +enum { + WGL_LABEL_STYLE_MAIN, +}; +typedef uint8_t wgl_label_style_t; + +/* Create a label */ +wgl_obj_t wgl_label_create(wgl_obj_t par, wgl_obj_t copy); + +/* Set text for the label */ +void wgl_label_set_text(wgl_obj_t label, const char * text); + +/** + * Get the length of the text of a label + * @param label the label object + * @return the length of the text of the label + */ +unsigned int wgl_label_get_text_length(wgl_obj_t label); + +/** + * Get the text of a label + * @param label the label object + * @param buffer buffer to save the text + * @param buffer_len length of the buffer + * @return the text of the label, note that the text will be truncated if buffer is not long enough + */ +char *wgl_label_get_text(wgl_obj_t label, char *buffer, int buffer_len); + + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_LABEL_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/inc/wgl_list.h b/core/iwasm/lib/app-libs/extension/gui/inc/wgl_list.h new file mode 100644 index 00000000..c2c454b2 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/inc/wgl_list.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_LIST_H +#define WAMR_GRAPHIC_LIBRARY_LIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** List styles. */ +enum { + WGL_LIST_STYLE_BG, /**< List background style */ + WGL_LIST_STYLE_SCRL, /**< List scrollable area style. */ + WGL_LIST_STYLE_SB, /**< List scrollbar style. */ + WGL_LIST_STYLE_EDGE_FLASH, /**< List edge flash style. */ + WGL_LIST_STYLE_BTN_REL, /**< Same meaning as the ordinary button styles. */ + WGL_LIST_STYLE_BTN_PR, + WGL_LIST_STYLE_BTN_TGL_REL, + WGL_LIST_STYLE_BTN_TGL_PR, + WGL_LIST_STYLE_BTN_INA, +}; +typedef uint8_t wgl_list_style_t; + + +/** + * Create a list objects + * @param par pointer to an object, it will be the parent of the new list + * @param copy pointer to a list object, if not NULL then the new object will be copied from it + * @return pointer to the created list + */ +wgl_obj_t wgl_list_create(wgl_obj_t par, wgl_obj_t copy); + + +/*====================== + * Add/remove functions + *=====================*/ + +/** + * Add a list element to the list + * @param list pointer to list object + * @param img_fn file name of an image before the text (NULL if unused) + * @param txt text of the list element (NULL if unused) + * @return pointer to the new list element which can be customized (a button) + */ +wgl_obj_t wgl_list_add_btn(wgl_obj_t list, const void * img_src, const char * txt); + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_LIST_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/inc/wgl_obj.h b/core/iwasm/lib/app-libs/extension/gui/inc/wgl_obj.h new file mode 100644 index 00000000..7bd8775f --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/inc/wgl_obj.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_OBJ_H +#define WAMR_GRAPHIC_LIBRARY_OBJ_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void * wgl_obj_t; + +enum { + WGL_EVENT_PRESSED, /**< The object has been pressed*/ + WGL_EVENT_PRESSING, /**< The object is being pressed (called continuously while pressing)*/ + WGL_EVENT_PRESS_LOST, /**< User is still pressing but slid cursor/finger off of the object */ + WGL_EVENT_SHORT_CLICKED, /**< User pressed object for a short period of time, then released it. Not called if dragged. */ + WGL_EVENT_LONG_PRESSED, /**< Object has been pressed for at least `WGL_INDEV_LONG_PRESS_TIME`. Not called if dragged.*/ + WGL_EVENT_LONG_PRESSED_REPEAT, /**< Called after `WGL_INDEV_LONG_PRESS_TIME` in every + `WGL_INDEV_LONG_PRESS_REP_TIME` ms. Not called if dragged.*/ + WGL_EVENT_CLICKED, /**< Called on release if not dragged (regardless to long press)*/ + WGL_EVENT_RELEASED, /**< Called in every cases when the object has been released*/ + WGL_EVENT_DRAG_BEGIN, + WGL_EVENT_DRAG_END, + WGL_EVENT_DRAG_THROW_BEGIN, + WGL_EVENT_KEY, + WGL_EVENT_FOCUSED, + WGL_EVENT_DEFOCUSED, + WGL_EVENT_VALUE_CHANGED, /**< The object's value has changed (i.e. slider moved) */ + WGL_EVENT_INSERT, + WGL_EVENT_REFRESH, + WGL_EVENT_APPLY, /**< "Ok", "Apply" or similar specific button has clicked*/ + WGL_EVENT_CANCEL, /**< "Close", "Cancel" or similar specific button has clicked*/ + WGL_EVENT_DELETE, /**< Object is being deleted */ +}; +typedef uint8_t wgl_event_t; /**< Type of event being sent to the object. */ + + +/** Object alignment. */ +enum { + WGL_ALIGN_CENTER = 0, + WGL_ALIGN_IN_TOP_LEFT, + WGL_ALIGN_IN_TOP_MID, + WGL_ALIGN_IN_TOP_RIGHT, + WGL_ALIGN_IN_BOTTOM_LEFT, + WGL_ALIGN_IN_BOTTOM_MID, + WGL_ALIGN_IN_BOTTOM_RIGHT, + WGL_ALIGN_IN_LEFT_MID, + WGL_ALIGN_IN_RIGHT_MID, + WGL_ALIGN_OUT_TOP_LEFT, + WGL_ALIGN_OUT_TOP_MID, + WGL_ALIGN_OUT_TOP_RIGHT, + WGL_ALIGN_OUT_BOTTOM_LEFT, + WGL_ALIGN_OUT_BOTTOM_MID, + WGL_ALIGN_OUT_BOTTOM_RIGHT, + WGL_ALIGN_OUT_LEFT_TOP, + WGL_ALIGN_OUT_LEFT_MID, + WGL_ALIGN_OUT_LEFT_BOTTOM, + WGL_ALIGN_OUT_RIGHT_TOP, + WGL_ALIGN_OUT_RIGHT_MID, + WGL_ALIGN_OUT_RIGHT_BOTTOM, +}; +typedef uint8_t wgl_align_t; + + +enum { + WGL_DRAG_DIR_HOR = 0x1, /**< Object can be dragged horizontally. */ + WGL_DRAG_DIR_VER = 0x2, /**< Object can be dragged vertically. */ + WGL_DRAG_DIR_ALL = 0x3, /**< Object can be dragged in all directions. */ +}; + +typedef uint8_t wgl_drag_dir_t; + +typedef void (*wgl_event_cb_t)(wgl_obj_t obj, wgl_event_t event); + +void wgl_obj_align(wgl_obj_t obj, wgl_obj_t base, wgl_align_t align, wgl_coord_t x_mod, wgl_coord_t y_mod); +void wgl_obj_set_event_cb(wgl_obj_t obj, wgl_event_cb_t event_cb); +wgl_res_t wgl_obj_del(wgl_obj_t obj); +void wgl_obj_del_async(wgl_obj_t obj); +void wgl_obj_clean(wgl_obj_t obj); + + + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_OBJ_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/inc/wgl_types.h b/core/iwasm/lib/app-libs/extension/gui/inc/wgl_types.h new file mode 100644 index 00000000..30b115fa --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/inc/wgl_types.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_TYPES_H +#define WAMR_GRAPHIC_LIBRARY_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * WGL error codes. + */ +enum { + WGL_RES_INV = 0, /*Typically indicates that the object is deleted (become invalid) in the action + function or an operation was failed*/ + WGL_RES_OK, /*The object is valid (no deleted) after the action*/ +}; +typedef uint8_t wgl_res_t; + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_TYPES_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/LICENCE.txt b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/LICENCE.txt new file mode 100644 index 00000000..beaef1d2 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/LICENCE.txt @@ -0,0 +1,8 @@ +MIT licence +Copyright (c) 2016 Gábor Kiss-Vámosi + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_btn.h b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_btn.h new file mode 100644 index 00000000..7aa2391f --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_btn.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_BTN_LVGL_COMPATIBLE_H +#define WAMR_GRAPHIC_LIBRARY_BTN_LVGL_COMPATIBLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../inc/wgl_btn.h" + +/** Possible states of a button. + * It can be used not only by buttons but other button-like objects too*/ +enum { + /**Released*/ + LV_BTN_STATE_REL, + + /**Pressed*/ + LV_BTN_STATE_PR, + + /**Toggled released*/ + LV_BTN_STATE_TGL_REL, + + /**Toggled pressed*/ + LV_BTN_STATE_TGL_PR, + + /**Inactive*/ + LV_BTN_STATE_INA, + + /**Number of states*/ + _LV_BTN_STATE_NUM, +}; +typedef wgl_btn_state_t lv_btn_state_t; + +/**Styles*/ +enum { + /** Release style */ + LV_BTN_STYLE_REL, + + /**Pressed style*/ + LV_BTN_STYLE_PR, + + /** Toggle released style*/ + LV_BTN_STYLE_TGL_REL, + + /** Toggle pressed style */ + LV_BTN_STYLE_TGL_PR, + + /** Inactive style*/ + LV_BTN_STYLE_INA, +}; +typedef wgl_btn_style_t lv_btn_style_t; + + +#define lv_btn_create wgl_btn_create +#define lv_btn_set_toggle wgl_btn_set_toggle +#define lv_btn_set_state wgl_btn_set_state +#define lv_btn_toggle wgl_btn_toggle +#define lv_btn_set_ink_in_time wgl_btn_set_ink_in_time +#define lv_btn_set_ink_wait_time wgl_btn_set_ink_wait_time +#define lv_btn_set_ink_out_time wgl_btn_set_ink_out_time +#define lv_btn_get_state wgl_btn_get_state +#define lv_btn_get_toggle wgl_btn_get_toggle +#define lv_btn_get_ink_in_time wgl_btn_get_ink_in_time +#define lv_btn_get_ink_wait_time wgl_btn_get_ink_wait_time +#define lv_btn_get_ink_out_time wgl_btn_get_ink_out_time + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_BTN_LVGL_COMPATIBLE_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_cb.h b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_cb.h new file mode 100644 index 00000000..04e5d85e --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_cb.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_CB_LVGL_COMPATIBLE_H +#define WAMR_GRAPHIC_LIBRARY_CB_LVGL_COMPATIBLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../inc/wgl_cb.h" + +/** Checkbox styles. */ +enum { + LV_CB_STYLE_BG, /**< Style of object background. */ + LV_CB_STYLE_BOX_REL, /**< Style of box (released). */ + LV_CB_STYLE_BOX_PR, /**< Style of box (pressed). */ + LV_CB_STYLE_BOX_TGL_REL, /**< Style of box (released but checked). */ + LV_CB_STYLE_BOX_TGL_PR, /**< Style of box (pressed and checked). */ + LV_CB_STYLE_BOX_INA, /**< Style of disabled box */ +}; +typedef wgl_cb_style_t lv_cb_style_t; + + +#define lv_cb_create wgl_cb_create +#define lv_cb_set_text wgl_cb_set_text +#define lv_cb_set_static_text wgl_cb_set_static_text +#define lv_cb_get_text(cb) wgl_cb_get_text(cb, g_widget_text, 100) + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_CB_LVGL_COMPATIBLE_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_label.h b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_label.h new file mode 100644 index 00000000..060e115f --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_label.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_LABEL_LVGL_COMPATIBLE_H +#define WAMR_GRAPHIC_LIBRARY_LABEL_LVGL_COMPATIBLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../inc/wgl_label.h" + +/** Long mode behaviors. Used in 'lv_label_ext_t' */ +enum { + LV_LABEL_LONG_EXPAND, /**< Expand the object size to the text size*/ + LV_LABEL_LONG_BREAK, /**< Keep the object width, break the too long lines and expand the object + height*/ + LV_LABEL_LONG_DOT, /**< Keep the size and write dots at the end if the text is too long*/ + LV_LABEL_LONG_SROLL, /**< Keep the size and roll the text back and forth*/ + LV_LABEL_LONG_SROLL_CIRC, /**< Keep the size and roll the text circularly*/ + LV_LABEL_LONG_CROP, /**< Keep the size and crop the text out of it*/ +}; +typedef wgl_label_long_mode_t lv_label_long_mode_t; + +/** Label align policy*/ +enum { + LV_LABEL_ALIGN_LEFT, /**< Align text to left */ + LV_LABEL_ALIGN_CENTER, /**< Align text to center */ + LV_LABEL_ALIGN_RIGHT, /**< Align text to right */ +}; +typedef wgl_label_align_t lv_label_align_t; + +/** Label styles*/ +enum { + LV_LABEL_STYLE_MAIN, +}; +typedef wgl_label_style_t lv_label_style_t; + + +#define lv_label_create wgl_label_create +#define lv_label_set_text wgl_label_set_text +#define lv_label_get_text(label) wgl_label_get_text(label, g_widget_text, 100) + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_LABEL_LVGL_COMPATIBLE_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_list.h b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_list.h new file mode 100644 index 00000000..5f3c4b61 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_list.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_LIST_LVGL_COMPATIBLE_H +#define WAMR_GRAPHIC_LIBRARY_LIST_LVGL_COMPATIBLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../inc/wgl_list.h" + +/** List styles. */ +enum { + LV_LIST_STYLE_BG, /**< List background style */ + LV_LIST_STYLE_SCRL, /**< List scrollable area style. */ + LV_LIST_STYLE_SB, /**< List scrollbar style. */ + LV_LIST_STYLE_EDGE_FLASH, /**< List edge flash style. */ + LV_LIST_STYLE_BTN_REL, /**< Same meaning as the ordinary button styles. */ + LV_LIST_STYLE_BTN_PR, + LV_LIST_STYLE_BTN_TGL_REL, + LV_LIST_STYLE_BTN_TGL_PR, + LV_LIST_STYLE_BTN_INA, +}; +typedef wgl_list_style_t lv_list_style_t; + + +#define lv_list_create wgl_list_create +#define lv_list_add_btn wgl_list_add_btn + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_LIST_LVGL_COMPATIBLE_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_obj.h b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_obj.h new file mode 100644 index 00000000..1ea3ab85 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_obj.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_OBJ_LVGL_COMPATIBLE_H +#define WAMR_GRAPHIC_LIBRARY_OBJ_LVGL_COMPATIBLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../inc/wgl_obj.h" + +typedef void lv_obj_t; + +enum { + LV_EVENT_PRESSED, + LV_EVENT_PRESSING, + LV_EVENT_PRESS_LOST, + LV_EVENT_SHORT_CLICKED, + LV_EVENT_LONG_PRESSED, + LV_EVENT_LONG_PRESSED_REPEAT, + LV_EVENT_CLICKED, + LV_EVENT_RELEASED, + LV_EVENT_DRAG_BEGIN, + LV_EVENT_DRAG_END, + LV_EVENT_DRAG_THROW_BEGIN, + LV_EVENT_KEY, + LV_EVENT_FOCUSED, + LV_EVENT_DEFOCUSED, + LV_EVENT_VALUE_CHANGED, + LV_EVENT_INSERT, + LV_EVENT_REFRESH, + LV_EVENT_APPLY, + LV_EVENT_CANCEL, + LV_EVENT_DELETE, +}; +typedef wgl_event_t lv_event_t; + + +/** Object alignment. */ +enum { + LV_ALIGN_CENTER, + LV_ALIGN_IN_TOP_LEFT, + LV_ALIGN_IN_TOP_MID, + LV_ALIGN_IN_TOP_RIGHT, + LV_ALIGN_IN_BOTTOM_LEFT, + LV_ALIGN_IN_BOTTOM_MID, + LV_ALIGN_IN_BOTTOM_RIGHT, + LV_ALIGN_IN_LEFT_MID, + LV_ALIGN_IN_RIGHT_MID, + LV_ALIGN_OUT_TOP_LEFT, + LV_ALIGN_OUT_TOP_MID, + LV_ALIGN_OUT_TOP_RIGHT, + LV_ALIGN_OUT_BOTTOM_LEFT, + LV_ALIGN_OUT_BOTTOM_MID, + LV_ALIGN_OUT_BOTTOM_RIGHT, + LV_ALIGN_OUT_LEFT_TOP, + LV_ALIGN_OUT_LEFT_MID, + LV_ALIGN_OUT_LEFT_BOTTOM, + LV_ALIGN_OUT_RIGHT_TOP, + LV_ALIGN_OUT_RIGHT_MID, + LV_ALIGN_OUT_RIGHT_BOTTOM, +}; +typedef wgl_align_t lv_align_t; + + +enum { + LV_DRAG_DIR_HOR, + LV_DRAG_DIR_VER, + LV_DRAG_DIR_ALL, +}; + +typedef wgl_drag_dir_t lv_drag_dir_t; + + +#define lv_obj_align wgl_obj_align +#define lv_obj_set_event_cb wgl_obj_set_event_cb +#define lv_obj_del wgl_obj_del +#define lv_obj_del_async wgl_obj_del_async +#define lv_obj_clean wgl_obj_clean + + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_OBJ_LVGL_COMPATIBLE_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_types.h b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_types.h new file mode 100644 index 00000000..36157d14 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/lvgl-compatible/lv_types.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_TYPES_LVGL_COMPATIBLE_H +#define WAMR_GRAPHIC_LIBRARY_TYPES_LVGL_COMPATIBLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../inc/wgl_types.h" + +/** + * error codes. + */ +enum { + LV_RES_INV, + LV_RES_OK, +}; +typedef wgl_res_t lv_res_t; + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_TYPES_LVGL_COMPATIBLE_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/lvgl.h b/core/iwasm/lib/app-libs/extension/gui/lvgl.h new file mode 100644 index 00000000..b8eb99ce --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/lvgl.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_LVGL_COMPATIBLE_H +#define WAMR_GRAPHIC_LIBRARY_LVGL_COMPATIBLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wgl_shared_utils.h" /* shared types between app and native */ +#include "lvgl-compatible/lv_types.h" +#include "lvgl-compatible/lv_obj.h" +#include "lvgl-compatible/lv_btn.h" +#include "lvgl-compatible/lv_cb.h" +#include "lvgl-compatible/lv_label.h" +#include "lvgl-compatible/lv_list.h" + + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_LVGL_COMPATIBLE_H */ diff --git a/core/iwasm/lib/app-libs/extension/gui/src/wgl_btn.c b/core/iwasm/lib/app-libs/extension/gui/src/wgl_btn.c new file mode 100644 index 00000000..5cf8c1c2 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/src/wgl_btn.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wgl.h" +#include "native_interface.h" + + +#define ARGC sizeof(argv)/sizeof(uint32) +#define CALL_BTN_NATIVE_FUNC(id) wasm_btn_native_call(id, (int32)argv, ARGC) + +wgl_obj_t wgl_btn_create(wgl_obj_t par, wgl_obj_t copy) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)par; + argv[1] = (uint32)copy; + CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_CREATE); + return (wgl_obj_t)argv[0]; +} + +void wgl_btn_set_toggle(wgl_obj_t btn, bool tgl) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)btn; + argv[1] = tgl; + CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_SET_TOGGLE); +} + +void wgl_btn_set_state(wgl_obj_t btn, wgl_btn_state_t state) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)btn; + argv[1] = state; + CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_SET_STATE); +} + +void wgl_btn_toggle(wgl_obj_t btn) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)btn; + CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_TOGGLE); +} + +void wgl_btn_set_ink_in_time(wgl_obj_t btn, uint16_t time) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)btn; + argv[1] = time; + CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_SET_INK_IN_TIME); +} + +void wgl_btn_set_ink_wait_time(wgl_obj_t btn, uint16_t time) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)btn; + argv[1] = time; + CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_SET_INK_WAIT_TIME); +} + +void wgl_btn_set_ink_out_time(wgl_obj_t btn, uint16_t time) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)btn; + argv[1] = time; + CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_SET_INK_OUT_TIME); +} + +//void wgl_btn_set_style(wgl_obj_t btn, wgl_btn_style_t type, const wgl_style_t * style) +//{ +// //TODO: pack style +// //wasm_btn_set_style(btn, type, style); +//} +// +wgl_btn_state_t wgl_btn_get_state(const wgl_obj_t btn) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)btn; + CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_GET_STATE); + return (wgl_btn_state_t)argv[0]; +} + +bool wgl_btn_get_toggle(const wgl_obj_t btn) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)btn; + CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_GET_TOGGLE); + return (bool)argv[0]; +} + +uint16_t wgl_btn_get_ink_in_time(const wgl_obj_t btn) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)btn; + CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_GET_INK_IN_TIME); + return (uint16_t)argv[0]; +} + +uint16_t wgl_btn_get_ink_wait_time(const wgl_obj_t btn) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)btn; + CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_GET_INK_WAIT_TIME); + return (uint16_t)argv[0]; +} + +uint16_t wgl_btn_get_ink_out_time(const wgl_obj_t btn) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)btn; + CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_GET_INK_OUT_TIME); + return (uint16_t)argv[0]; +} +// +//const wgl_style_t * wgl_btn_get_style(const wgl_obj_t btn, wgl_btn_style_t type) +//{ +// //TODO: pack style +// //wasm_btn_get_style(btn, type); +// return NULL; +//} diff --git a/core/iwasm/lib/app-libs/extension/gui/src/wgl_cb.c b/core/iwasm/lib/app-libs/extension/gui/src/wgl_cb.c new file mode 100644 index 00000000..df646fbc --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/src/wgl_cb.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wgl.h" +#include "native_interface.h" + +#include + +#define ARGC sizeof(argv)/sizeof(uint32) +#define CALL_CB_NATIVE_FUNC(id) wasm_cb_native_call(id, (uint32)argv, ARGC) + +wgl_obj_t wgl_cb_create(wgl_obj_t par, const wgl_obj_t copy) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)par; + argv[1] = (uint32)copy; + CALL_CB_NATIVE_FUNC(CB_FUNC_ID_CREATE); + return (wgl_obj_t)argv[0]; +} + +void wgl_cb_set_text(wgl_obj_t cb, const char * txt) +{ + uint32 argv[3] = {0}; + argv[0] = (uint32)cb; + argv[1] = (uint32)txt; + argv[2] = strlen(txt) + 1; + CALL_CB_NATIVE_FUNC(CB_FUNC_ID_SET_TEXT); +} + +void wgl_cb_set_static_text(wgl_obj_t cb, const char * txt) +{ + uint32 argv[3] = {0}; + argv[0] = (uint32)cb; + argv[1] = (uint32)txt; + argv[2] = strlen(txt) + 1; + CALL_CB_NATIVE_FUNC(CB_FUNC_ID_SET_STATIC_TEXT); +} + +//void wgl_cb_set_style(wgl_obj_t cb, wgl_cb_style_t type, const wgl_style_t * style) +//{ +// //TODO: +//} +// + +unsigned int wgl_cb_get_text_length(wgl_obj_t cb) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)cb; + CALL_CB_NATIVE_FUNC(CB_FUNC_ID_GET_TEXT_LENGTH); + return argv[0]; +} + +char *wgl_cb_get_text(wgl_obj_t cb, char *buffer, int buffer_len) +{ + uint32 argv[3] = {0}; + argv[0] = (uint32)cb; + argv[1] = (uint32)buffer; + argv[2] = buffer_len; + CALL_CB_NATIVE_FUNC(CB_FUNC_ID_GET_TEXT); + return (char *)argv[0]; +} + +//const wgl_style_t * wgl_cb_get_style(const wgl_obj_t cb, wgl_cb_style_t type) +//{ +// //TODO +// return NULL; +//} +// + + diff --git a/core/iwasm/lib/app-libs/extension/gui/src/wgl_label.c b/core/iwasm/lib/app-libs/extension/gui/src/wgl_label.c new file mode 100644 index 00000000..3a14cdb4 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/src/wgl_label.c @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "wgl.h" +#include "native_interface.h" +#include + + +#define ARGC sizeof(argv)/sizeof(uint32) +#define CALL_LABEL_NATIVE_FUNC(id) wasm_label_native_call(id, (uint32)argv, ARGC) + +wgl_obj_t wgl_label_create(wgl_obj_t par, wgl_obj_t copy) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)par; + argv[1] = (uint32)copy; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_CREATE); + return (wgl_obj_t)argv[0]; +} + +void wgl_label_set_text(wgl_obj_t label, const char * text) +{ + uint32 argv[3] = {0}; + argv[0] = (uint32)label; + argv[1] = (uint32)text; + argv[2] = strlen(text) + 1; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_TEXT); +} + + +void wgl_label_set_array_text(wgl_obj_t label, const char * array, uint16_t size) +{ + uint32 argv[3] = {0}; + argv[0] = (uint32)label; + argv[1] = (uint32)array; + argv[2] = size; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_ARRAY_TEXT); +} + + +void wgl_label_set_static_text(wgl_obj_t label, const char * text) +{ + uint32 argv[3] = {0}; + argv[0] = (uint32)label; + argv[1] = (uint32)text; + argv[2] = strlen(text) + 1; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_STATIC_TEXT); +} + + +void wgl_label_set_long_mode(wgl_obj_t label, wgl_label_long_mode_t long_mode) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)label; + argv[1] = long_mode; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_LONG_MODE); +} + + +void wgl_label_set_align(wgl_obj_t label, wgl_label_align_t align) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)label; + argv[1] = align; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_ALIGN); +} + + +void wgl_label_set_recolor(wgl_obj_t label, bool en) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)label; + argv[1] = en; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_RECOLOR); +} + + +void wgl_label_set_body_draw(wgl_obj_t label, bool en) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)label; + argv[1] = en; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_BODY_DRAW); +} + + +void wgl_label_set_anim_speed(wgl_obj_t label, uint16_t anim_speed) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)label; + argv[1] = anim_speed; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_ANIM_SPEED); +} + + +void wgl_label_set_text_sel_start(wgl_obj_t label, uint16_t index) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)label; + argv[1] = index; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_TEXT_SEL_START); +} + + +void wgl_label_set_text_sel_end(wgl_obj_t label, uint16_t index) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)label; + argv[1] = index; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_TEXT_SEL_END); +} + +unsigned int wgl_label_get_text_length(wgl_obj_t label) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)label; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_TEXT_LENGTH); + return argv[0]; +} + +char * wgl_label_get_text(wgl_obj_t label, char *buffer, int buffer_len) +{ + uint32 argv[3] = {0}; + argv[0] = (uint32)label; + argv[1] = (uint32)buffer; + argv[2] = buffer_len; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_TEXT); + return (char *)argv[0]; +} + + +wgl_label_long_mode_t wgl_label_get_long_mode(const wgl_obj_t label) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)label; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_LONG_MODE); + return (wgl_label_long_mode_t)argv[0]; +} + + +wgl_label_align_t wgl_label_get_align(const wgl_obj_t label) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)label; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_ALIGN); + return (wgl_label_align_t)argv[0]; +} + + +bool wgl_label_get_recolor(const wgl_obj_t label) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)label; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_RECOLOR); + return (bool)argv[0]; +} + + +bool wgl_label_get_body_draw(const wgl_obj_t label) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)label; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_BODY_DRAW); + return (bool)argv[0]; +} + + +uint16_t wgl_label_get_anim_speed(const wgl_obj_t label) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)label; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_ANIM_SPEED); + return (uint16_t)argv[0]; +} + + +void wgl_label_get_letter_pos(const wgl_obj_t label, uint16_t index, wgl_point_t * pos) +{ + uint32 argv[4] = {0}; + argv[0] = (uint32)label; + argv[1] = index; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_LETTER_POS); + pos->x = argv[2]; + pos->y = argv[3]; +} + + +uint16_t wgl_label_get_letter_on(const wgl_obj_t label, wgl_point_t * pos) +{ + uint32 argv[3] = {0}; + argv[0] = (uint32)label; + argv[1] = pos->x; + argv[2] = pos->y; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_LETTER_POS); + return (uint16_t)argv[0]; +} + + +bool wgl_label_is_char_under_pos(const wgl_obj_t label, wgl_point_t * pos) +{ + uint32 argv[3] = {0}; + argv[0] = (uint32)label; + argv[1] = pos->x; + argv[2] = pos->y; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_LETTER_POS); + return (bool)argv[0]; +} + + +uint16_t wgl_label_get_text_sel_start(const wgl_obj_t label) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)label; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_TEXT_SEL_START); + return (uint16_t)argv[0]; +} + + +uint16_t wgl_label_get_text_sel_end(const wgl_obj_t label) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)label; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_TEXT_SEL_END); + return (uint16_t)argv[0]; +} + + +void wgl_label_ins_text(wgl_obj_t label, uint32_t pos, const char * txt) +{ + uint32 argv[4] = {0}; + argv[0] = (uint32)label; + argv[1] = pos; + argv[2] = (uint32)txt; + argv[3] = strlen(txt) + 1; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_INS_TEXT); +} + + +void wgl_label_cut_text(wgl_obj_t label, uint32_t pos, uint32_t cnt) +{ + uint32 argv[3] = {0}; + argv[0] = (uint32)label; + argv[1] = pos; + argv[2] = cnt; + CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_CUT_TEXT); +} + + diff --git a/core/iwasm/lib/app-libs/extension/gui/src/wgl_list.c b/core/iwasm/lib/app-libs/extension/gui/src/wgl_list.c new file mode 100644 index 00000000..ad580b7f --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/src/wgl_list.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wgl.h" +#include "native_interface.h" + +#include + +#define ARGC sizeof(argv)/sizeof(uint32) +#define CALL_LIST_NATIVE_FUNC(id) wasm_list_native_call(id, (int32)argv, ARGC) + + +wgl_obj_t wgl_list_create(wgl_obj_t par, const wgl_obj_t copy) +{ + uint32 argv[2] = {0}; + argv[0] = (uint32)par; + argv[1] = (uint32)copy; + CALL_LIST_NATIVE_FUNC(LIST_FUNC_ID_CREATE); + return (wgl_obj_t)argv[0]; +} +// +// +//void wgl_list_clean(wgl_obj_t obj) +//{ +// wasm_list_clean(obj); +//} +// + +wgl_obj_t wgl_list_add_btn(wgl_obj_t list, const void * img_src, const char * txt) +{ + (void)img_src; /* doesn't support img src currently */ + + uint32 argv[3] = {0}; + argv[0] = (uint32)list; + argv[1] = (uint32)txt; + argv[2] = strlen(txt) + 1; + CALL_LIST_NATIVE_FUNC(LIST_FUNC_ID_ADD_BTN); + return (wgl_obj_t)argv[0]; +} +// +// +//bool wgl_list_remove(const wgl_obj_t list, uint16_t index) +//{ +// return wasm_list_remove(list, index); +//} +// +// +//void wgl_list_set_single_mode(wgl_obj_t list, bool mode) +//{ +// wasm_list_set_single_mode(list, mode); +//} +// +//#if LV_USE_GROUP +// +// +//void wgl_list_set_btn_selected(wgl_obj_t list, wgl_obj_t btn) +//{ +// wasm_list_set_btn_selected(list, btn); +//} +//#endif +// +// +//void wgl_list_set_style(wgl_obj_t list, wgl_list_style_t type, const wgl_style_t * style) +//{ +// //TODO +//} +// +// +//bool wgl_list_get_single_mode(wgl_obj_t list) +//{ +// return wasm_list_get_single_mode(list); +//} +// +// +//const char * wgl_list_get_btn_text(const wgl_obj_t btn) +//{ +// return wasm_list_get_btn_text(btn); +//} +// +//wgl_obj_t wgl_list_get_btn_label(const wgl_obj_t btn) +//{ +// return wasm_list_get_btn_label(btn); +//} +// +// +//wgl_obj_t wgl_list_get_btn_img(const wgl_obj_t btn) +//{ +// return wasm_list_get_btn_img(btn); +//} +// +// +//wgl_obj_t wgl_list_get_prev_btn(const wgl_obj_t list, wgl_obj_t prev_btn) +//{ +// return wasm_list_get_prev_btn(list, prev_btn); +//} +// +// +//wgl_obj_t wgl_list_get_next_btn(const wgl_obj_t list, wgl_obj_t prev_btn) +//{ +// return wasm_list_get_next_btn(list, prev_btn); +//} +// +// +//int32_t wgl_list_get_btn_index(const wgl_obj_t list, const wgl_obj_t btn) +//{ +// return wasm_list_get_btn_index(list, btn); +//} +// +// +//uint16_t wgl_list_get_size(const wgl_obj_t list) +//{ +// return wasm_list_get_size(list); +//} +// +//#if LV_USE_GROUP +// +//wgl_obj_t wgl_list_get_btn_selected(const wgl_obj_t list) +//{ +// return wasm_list_get_btn_selected(list); +//} +//#endif +// +// +// +//const wgl_style_t * wgl_list_get_style(const wgl_obj_t list, wgl_list_style_t type) +//{ +// //TODO +// return NULL; +//} +// +// +//void wgl_list_up(const wgl_obj_t list) +//{ +// wasm_list_up(list); +//} +// +//void wgl_list_down(const wgl_obj_t list) +//{ +// wasm_list_down(list); +//} +// +// +//void wgl_list_focus(const wgl_obj_t btn, wgl_anim_enable_t anim) +//{ +// wasm_list_focus(btn, anim); +//} +// + + diff --git a/core/iwasm/lib/app-libs/extension/gui/src/wgl_obj.c b/core/iwasm/lib/app-libs/extension/gui/src/wgl_obj.c new file mode 100644 index 00000000..d53f8b29 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/src/wgl_obj.c @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wgl.h" +#include "native_interface.h" +#include +#include + +#define ARGC sizeof(argv)/sizeof(uint32) +#define CALL_OBJ_NATIVE_FUNC(id) wasm_obj_native_call(id, (int32)argv, ARGC) + +typedef struct _obj_evt_cb { + struct _obj_evt_cb *next; + + wgl_obj_t obj; + + wgl_event_cb_t event_cb; +} obj_evt_cb_t; + +static obj_evt_cb_t *g_obj_evt_cb_list = NULL; + +/* For lvgl compatible */ +char g_widget_text[100]; + +wgl_res_t wgl_obj_del(wgl_obj_t obj) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)obj; + CALL_OBJ_NATIVE_FUNC(OBJ_FUNC_ID_DEL); + return (wgl_res_t)argv[0]; +} + +void wgl_obj_del_async(wgl_obj_t obj) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)obj; + CALL_OBJ_NATIVE_FUNC(OBJ_FUNC_ID_DEL_ASYNC); +} + +void wgl_obj_clean(wgl_obj_t obj) +{ + uint32 argv[1] = {0}; + argv[0] = (uint32)obj; + CALL_OBJ_NATIVE_FUNC(OBJ_FUNC_ID_CLEAN); +} + +void wgl_obj_align(wgl_obj_t obj, const wgl_obj_t base, wgl_align_t align, wgl_coord_t x_mod, wgl_coord_t y_mod) +{ + uint32 argv[5] = {0}; + argv[0] = (uint32)obj; + argv[1] = (uint32)base; + argv[2] = align; + argv[3] = x_mod; + argv[4] = y_mod; + CALL_OBJ_NATIVE_FUNC(OBJ_FUNC_ID_ALIGN); +} + +wgl_event_cb_t wgl_obj_get_event_cb(const wgl_obj_t obj) +{ + obj_evt_cb_t *obj_evt_cb = g_obj_evt_cb_list; + while (obj_evt_cb != NULL) { + if (obj_evt_cb->obj == obj) { + return obj_evt_cb->event_cb; + } + obj_evt_cb = obj_evt_cb->next; + } + + return NULL; +} + +void wgl_obj_set_event_cb(wgl_obj_t obj, wgl_event_cb_t event_cb) +{ + obj_evt_cb_t *obj_evt_cb; + uint32 argv[1] = {0}; + + obj_evt_cb = g_obj_evt_cb_list; + while (obj_evt_cb) { + if (obj_evt_cb->obj == obj) { + obj_evt_cb->event_cb = event_cb; + return; + } + } + + obj_evt_cb = (obj_evt_cb_t *)malloc(sizeof(*obj_evt_cb)); + if (obj_evt_cb == NULL) + return; + + memset(obj_evt_cb, 0, sizeof(*obj_evt_cb)); + obj_evt_cb->obj = obj; + obj_evt_cb->event_cb = event_cb; + + if (g_obj_evt_cb_list != NULL) { + obj_evt_cb->next = g_obj_evt_cb_list; + g_obj_evt_cb_list = obj_evt_cb; + } else { + g_obj_evt_cb_list = obj_evt_cb; + } + + argv[0] = (uint32)obj; + CALL_OBJ_NATIVE_FUNC(OBJ_FUNC_ID_SET_EVT_CB); +} + +void on_widget_event(wgl_obj_t obj, wgl_event_t event) +{ + obj_evt_cb_t *obj_evt_cb = g_obj_evt_cb_list; + + while (obj_evt_cb != NULL) { + if (obj_evt_cb->obj == obj) { + obj_evt_cb->event_cb(obj, event); + return; + } + obj_evt_cb = obj_evt_cb->next; + } +} diff --git a/core/iwasm/lib/app-libs/extension/gui/wgl.h b/core/iwasm/lib/app-libs/extension/gui/wgl.h new file mode 100644 index 00000000..2f1e7946 --- /dev/null +++ b/core/iwasm/lib/app-libs/extension/gui/wgl.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_H +#define WAMR_GRAPHIC_LIBRARY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wgl_shared_utils.h" /* shared types between app and native */ + +#include "inc/wgl_types.h" +#include "inc/wgl_obj.h" +#include "inc/wgl_btn.h" +#include "inc/wgl_cb.h" +#include "inc/wgl_label.h" +#include "inc/wgl_list.h" + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_H */ diff --git a/core/iwasm/runtime/platform/zephyr/wasm_platform.c b/core/iwasm/lib/native-interface/connection_api.h similarity index 54% rename from core/iwasm/runtime/platform/zephyr/wasm_platform.c rename to core/iwasm/lib/native-interface/connection_api.h index 08b1650e..f55583bd 100644 --- a/core/iwasm/runtime/platform/zephyr/wasm_platform.c +++ b/core/iwasm/lib/native-interface/connection_api.h @@ -14,43 +14,25 @@ * limitations under the License. */ -#include "wasm_platform.h" +#ifndef CONNECTION_API_H_ +#define CONNECTION_API_H_ +#include "bh_platform.h" -#ifndef CONFIG_AEE_ENABLE -static int -_stdout_hook_iwasm(int c) -{ - printk("%c", (char)c); - return 1; -} - -extern void __stdout_hook_install(int (*hook)(int)); +#ifdef __cplusplus +extern "C" { #endif -bool is_little_endian = false; +uint32 wasm_open_connection(int32 name_offset, int32 args_offset, uint32 len); -bool __is_little_endian() -{ - union w - { - int a; - char b; - }c; +void wasm_close_connection(uint32 handle); - c.a = 1; - return (c.b == 1); +int wasm_send_on_connection(uint32 handle, int32 data_offset, uint32 len); + +bool wasm_config_connection(uint32 handle, int32 cfg_offset, uint32 len); + +#ifdef __cplusplus } - -int wasm_platform_init() -{ - if (__is_little_endian()) - is_little_endian = true; - -#ifndef CONFIG_AEE_ENABLE - /* Enable printf() in Zephyr */ - __stdout_hook_install(_stdout_hook_iwasm); #endif - return 0; -} +#endif /* CONNECTION_API_H_ */ diff --git a/core/iwasm/lib/native-interface/gui_api.h b/core/iwasm/lib/native-interface/gui_api.h new file mode 100644 index 00000000..0b1dbb00 --- /dev/null +++ b/core/iwasm/lib/native-interface/gui_api.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GUI_API_H_ +#define GUI_API_H_ +#include "bh_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void wasm_obj_native_call(int32 func_id, uint32 argv_offset, uint32 argc); +void wasm_btn_native_call(int32 func_id, uint32 argv_offset, uint32 argc); +void wasm_label_native_call(int32 func_id, uint32 argv_offset, uint32 argc); +void wasm_cb_native_call(int32 func_id, uint32 argv_offset, uint32 argc); +void wasm_list_native_call(int32 func_id, uint32 argv_offset, uint32 argc); + + +#ifdef __cplusplus +} +#endif + + +#endif /* GUI_API_H_ */ diff --git a/core/iwasm/lib/native-interface/native_interface.h b/core/iwasm/lib/native-interface/native_interface.h index a538330b..0312b1f6 100644 --- a/core/iwasm/lib/native-interface/native_interface.h +++ b/core/iwasm/lib/native-interface/native_interface.h @@ -75,4 +75,16 @@ void wasm_timer_destory(timer_id_t timer_id); void wasm_timer_cancel(timer_id_t timer_id); void wasm_timer_restart(timer_id_t timer_id, int interval); uint32 wasm_get_sys_tick_ms(void); -#endif /* DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_NATIVE_INTERFACE_H_ */ + +/* + * *** connection interface *** + */ +uint32 wasm_open_connection(int32 name_offset, int32 args_offset, uint32 len); +void wasm_close_connection(uint32 handle); +int wasm_send_on_connection(uint32 handle, int32 data_offset, uint32 len); +bool wasm_config_connection(uint32 handle, int32 cfg_offset, uint32 len); + +#include "gui_api.h" + +#endif /* DEPS_SSG_MICRO_RUNTIME_WASM_PO +C_APP_LIBS_NATIVE_INTERFACE_NATIVE_INTERFACE_H_ */ diff --git a/core/iwasm/lib/native-interface/shared_utils.h b/core/iwasm/lib/native-interface/shared_utils.h index e4b9bc91..693dcf95 100644 --- a/core/iwasm/lib/native-interface/shared_utils.h +++ b/core/iwasm/lib/native-interface/shared_utils.h @@ -134,6 +134,8 @@ char * pack_response(response_t *response, int * size); response_t * unpack_response(char * packet, int size, response_t * response); void free_req_resp_packet(char * packet); +#include "wgl_shared_utils.h" + #ifdef __cplusplus } #endif diff --git a/core/iwasm/lib/native-interface/wasm_export.h b/core/iwasm/lib/native-interface/wasm_export.h new file mode 100644 index 00000000..ed9d570f --- /dev/null +++ b/core/iwasm/lib/native-interface/wasm_export.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _WASM_EXPORT_H +#define _WASM_EXPORT_H + +#include +#include + +/** + * API exported to WASM application + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get current WASM module instance of the current native thread + * + * @return current WASM module instance of the current native thread, 0 + * if not found + * Note: the return type is uint64_t but not pointer type, because that + * the we only supports WASM-32, in which the pointer type is + * compiled to WASM i32 type, but the pointer type in native can be + * 32-bit and 64-bit. And if the native pointer is 64-bit, data loss + * occurs after converting it to WASM i32 type. + */ +uint64_t +wasm_runtime_get_current_module_inst(); + +/** + * Validate the app address, check whether it belongs to WASM module + * instance's address space, or in its heap space or memory space. + * + * @param module_inst the WASM module instance + * @param app_offset the app address to validate, which is a relative address + * @param size the size bytes of the app address + * + * @return true if success, false otherwise. + */ +bool +wasm_runtime_validate_app_addr(uint64_t module_inst, + int32_t app_offset, uint32_t size); + +/** + * Validate the native address, check whether it belongs to WASM module + * instance's address space, or in its heap space or memory space. + * + * @param module_inst the WASM module instance + * @param native_ptr the native address to validate, which is an absolute + * address + * @param size the size bytes of the app address + * + * @return true if success, false otherwise. + */ +bool +wasm_runtime_validate_native_addr(uint64_t module_inst, + uint64_t native_ptr, uint32_t size); + +/** + * Convert app address(relative address) to native address(absolute address) + * + * @param module_inst the WASM module instance + * @param app_offset the app adress + * + * @return the native address converted + */ +uint64_t +wasm_runtime_addr_app_to_native(uint64_t module_inst, + int32_t app_offset); + +/** + * Convert native address(absolute address) to app address(relative address) + * + * @param module_inst the WASM module instance + * @param native_ptr the native address + * + * @return the app address converted + */ +int32_t +wasm_runtime_addr_native_to_app(uint64_t module_inst, + uint64_t native_ptr); + +#ifdef __cplusplus +} +#endif + +#endif /* end of _WASM_EXPORT_H */ diff --git a/core/iwasm/lib/native-interface/wgl_shared_utils.h b/core/iwasm/lib/native-interface/wgl_shared_utils.h new file mode 100644 index 00000000..0d64b436 --- /dev/null +++ b/core/iwasm/lib/native-interface/wgl_shared_utils.h @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WAMR_GRAPHIC_LIBRARY_SHARED_UTILS_H +#define WAMR_GRAPHIC_LIBRARY_SHARED_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "../3rdparty/lv_conf.h" + +typedef lv_coord_t wgl_coord_t; /* lv_coord_t is defined in lv_conf.h */ + +/** + * Represents a point on the screen. + */ +typedef struct +{ + lv_coord_t x; + lv_coord_t y; +} wgl_point_t; + +/** Represents an area of the screen. */ +typedef struct +{ + lv_coord_t x1; + lv_coord_t y1; + lv_coord_t x2; + lv_coord_t y2; +} wgl_area_t; + + +/** Describes the properties of a glyph. */ +typedef struct +{ + uint16_t adv_w; /**< The glyph needs this space. Draw the next glyph after this width. 8 bit integer, 4 bit fractional */ + uint8_t box_w; /**< Width of the glyph's bounding box*/ + uint8_t box_h; /**< Height of the glyph's bounding box*/ + int8_t ofs_x; /**< x offset of the bounding box*/ + int8_t ofs_y; /**< y offset of the bounding box*/ + uint8_t bpp; /**< Bit-per-pixel: 1, 2, 4, 8*/ +}wgl_font_glyph_dsc_t; + +/*Describe the properties of a font*/ +typedef struct _wgl_font_struct +{ + /** Get a glyph's descriptor from a font*/ + bool (*get_glyph_dsc)(const struct _wgl_font_struct *, wgl_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next); + + /** Get a glyph's bitmap from a font*/ + const uint8_t * (*get_glyph_bitmap)(const struct _wgl_font_struct *, uint32_t); + + /*Pointer to the font in a font pack (must have the same line height)*/ + uint8_t line_height; /**< The real line height where any text fits*/ + uint8_t base_line; /**< Base line measured from the top of the line_height*/ + void * dsc; /**< Store implementation specific data here*/ +#if LV_USE_USER_DATA + wgl_font_user_data_t user_data; /**< Custom user data for font. */ +#endif +} wgl_font_t; + +#if LV_COLOR_DEPTH == 1 +#define LV_COLOR_SIZE 8 +#elif LV_COLOR_DEPTH == 8 +#define LV_COLOR_SIZE 8 +#elif LV_COLOR_DEPTH == 16 +#define LV_COLOR_SIZE 16 +#elif LV_COLOR_DEPTH == 32 +#define LV_COLOR_SIZE 32 +#else +#error "Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!" +#endif + +/********************** + * TYPEDEFS + **********************/ + +typedef union +{ + uint8_t blue : 1; + uint8_t green : 1; + uint8_t red : 1; + uint8_t full : 1; +} wgl_color1_t; + +typedef union +{ + struct + { + uint8_t blue : 2; + uint8_t green : 3; + uint8_t red : 3; + } ch; + uint8_t full; +} wgl_color8_t; + +typedef union +{ + struct + { +#if LV_COLOR_16_SWAP == 0 + uint16_t blue : 5; + uint16_t green : 6; + uint16_t red : 5; +#else + uint16_t green_h : 3; + uint16_t red : 5; + uint16_t blue : 5; + uint16_t green_l : 3; +#endif + } ch; + uint16_t full; +} wgl_color16_t; + +typedef union +{ + struct + { + uint8_t blue; + uint8_t green; + uint8_t red; + uint8_t alpha; + } ch; + uint32_t full; +} wgl_color32_t; + +#if LV_COLOR_DEPTH == 1 +typedef uint8_t wgl_color_int_t; +typedef wgl_color1_t wgl_color_t; +#elif LV_COLOR_DEPTH == 8 +typedef uint8_t wgl_color_int_t; +typedef wgl_color8_t wgl_color_t; +#elif LV_COLOR_DEPTH == 16 +typedef uint16_t wgl_color_int_t; +typedef wgl_color16_t wgl_color_t; +#elif LV_COLOR_DEPTH == 32 +typedef uint32_t wgl_color_int_t; +typedef wgl_color32_t wgl_color_t; +#else +#error "Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!" +#endif + +typedef uint8_t wgl_opa_t; + + + +/*Border types (Use 'OR'ed values)*/ +enum { + WGL_BORDER_NONE = 0x00, + WGL_BORDER_BOTTOM = 0x01, + WGL_BORDER_TOP = 0x02, + WGL_BORDER_LEFT = 0x04, + WGL_BORDER_RIGHT = 0x08, + WGL_BORDER_FULL = 0x0F, + WGL_BORDER_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/ +}; +typedef uint8_t wgl_border_part_t; + +/*Shadow types*/ +enum { + WGL_SHADOW_BOTTOM = 0, /**< Only draw bottom shadow */ + WGL_SHADOW_FULL, /**< Draw shadow on all sides */ +}; +typedef uint8_t wgl_shadow_type_t; + +/** + * Objects in LittlevGL can be assigned a style - which holds information about + * how the object should be drawn. + * + * This allows for easy customization without having to modify the object's design + * function. + */ +typedef struct +{ + uint8_t glass : 1; /**< 1: Do not inherit this style*/ + + /** Object background. */ + struct + { + wgl_color_t main_color; /**< Object's main background color. */ + wgl_color_t grad_color; /**< Second color. If not equal to `main_color` a gradient will be drawn for the background. */ + wgl_coord_t radius; /**< Object's corner radius. You can use #WGL_RADIUS_CIRCLE if you want to draw a circle. */ + wgl_opa_t opa; /**< Object's opacity (0-255). */ + + struct + { + wgl_color_t color; /**< Border color */ + wgl_coord_t width; /**< Border width */ + wgl_border_part_t part; /**< Which borders to draw */ + wgl_opa_t opa; /**< Border opacity. */ + } border; + + + struct + { + wgl_color_t color; + wgl_coord_t width; + wgl_shadow_type_t type; /**< Which parts of the shadow to draw */ + } shadow; + + struct + { + wgl_coord_t top; + wgl_coord_t bottom; + wgl_coord_t left; + wgl_coord_t right; + wgl_coord_t inner; + } padding; + } body; + + /** Style for text drawn by this object. */ + struct + { + wgl_color_t color; /**< Text color */ + wgl_color_t sel_color; /**< Text selection background color. */ + const wgl_font_t * font; + wgl_coord_t letter_space; /**< Space between letters */ + wgl_coord_t line_space; /**< Space between lines (vertical) */ + wgl_opa_t opa; /**< Text opacity */ + } text; + + /**< Style of images. */ + struct + { + wgl_color_t color; /**< Color to recolor the image with */ + wgl_opa_t intense; /**< Opacity of recoloring (0 means no recoloring) */ + wgl_opa_t opa; /**< Opacity of whole image */ + } image; + + /**< Style of lines (not borders). */ + struct + { + wgl_color_t color; + wgl_coord_t width; + wgl_opa_t opa; + uint8_t rounded : 1; /**< 1: rounded line endings*/ + } line; +} wgl_style_t; + + + +/* Object native function IDs */ +enum { + OBJ_FUNC_ID_DEL, + OBJ_FUNC_ID_DEL_ASYNC, + OBJ_FUNC_ID_CLEAN, + OBJ_FUNC_ID_SET_EVT_CB, + OBJ_FUNC_ID_ALIGN, + + /* Number of functions */ + _OBJ_FUNC_ID_NUM, +}; + +/* Button native function IDs */ +enum { + BTN_FUNC_ID_CREATE, + BTN_FUNC_ID_SET_TOGGLE, + BTN_FUNC_ID_SET_STATE, + BTN_FUNC_ID_TOGGLE, + BTN_FUNC_ID_SET_INK_IN_TIME, + BTN_FUNC_ID_SET_INK_WAIT_TIME, + BTN_FUNC_ID_SET_INK_OUT_TIME, + BTN_FUNC_ID_GET_STATE, + BTN_FUNC_ID_GET_TOGGLE, + BTN_FUNC_ID_GET_INK_IN_TIME, + BTN_FUNC_ID_GET_INK_WAIT_TIME, + BTN_FUNC_ID_GET_INK_OUT_TIME, + /* Number of functions */ + _BTN_FUNC_ID_NUM, +}; + +/* Check box native function IDs */ +enum { + CB_FUNC_ID_CREATE, + CB_FUNC_ID_SET_TEXT, + CB_FUNC_ID_SET_STATIC_TEXT, + CB_FUNC_ID_GET_TEXT, + CB_FUNC_ID_GET_TEXT_LENGTH, + + /* Number of functions */ + _CB_FUNC_ID_NUM, +}; + +/* List native function IDs */ +enum { + LIST_FUNC_ID_CREATE, + LIST_FUNC_ID_ADD_BTN, + + /* Number of functions */ + _LIST_FUNC_ID_NUM, +}; + +/* Label native function IDs */ +enum { + LABEL_FUNC_ID_CREATE, + LABEL_FUNC_ID_SET_TEXT, + LABEL_FUNC_ID_SET_ARRAY_TEXT, + LABEL_FUNC_ID_SET_STATIC_TEXT, + LABEL_FUNC_ID_SET_LONG_MODE, + LABEL_FUNC_ID_SET_ALIGN, + LABEL_FUNC_ID_SET_RECOLOR, + LABEL_FUNC_ID_SET_BODY_DRAW, + LABEL_FUNC_ID_SET_ANIM_SPEED, + LABEL_FUNC_ID_SET_TEXT_SEL_START, + LABEL_FUNC_ID_SET_TEXT_SEL_END, + LABEL_FUNC_ID_GET_TEXT, + LABEL_FUNC_ID_GET_TEXT_LENGTH, + LABEL_FUNC_ID_GET_LONG_MODE, + LABEL_FUNC_ID_GET_ALIGN, + LABEL_FUNC_ID_GET_RECOLOR, + LABEL_FUNC_ID_GET_BODY_DRAW, + LABEL_FUNC_ID_GET_ANIM_SPEED, + LABEL_FUNC_ID_GET_LETTER_POS, + LABEL_FUNC_ID_GET_TEXT_SEL_START, + LABEL_FUNC_ID_GET_TEXT_SEL_END, + LABEL_FUNC_ID_INS_TEXT, + LABEL_FUNC_ID_CUT_TEXT, + /* Number of functions */ + _LABEL_FUNC_ID_NUM, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_SHARED_UTILS_H */ diff --git a/core/iwasm/lib/native/base/base_lib_export.c b/core/iwasm/lib/native/base/base_lib_export.c index 4392a7ba..353871b6 100644 --- a/core/iwasm/lib/native/base/base_lib_export.c +++ b/core/iwasm/lib/native/base/base_lib_export.c @@ -18,11 +18,116 @@ #include #include #include "lib_export.h" +#include "bh_platform.h" +#include "wasm_export.h" #ifdef WASM_ENABLE_BASE_LIB #include "base_lib_export.h" #endif +static uint64 +wasm_runtime_get_current_module_inst_wrapper() +{ + return (uint64)(uintptr_t) + wasm_runtime_get_current_module_inst(); +} + +static bool +wasm_runtime_validate_app_addr_wrapper(uint32 inst_part0, uint32 inst_part1, + int32 app_offset, uint32 size) +{ + bool ret; + wasm_module_inst_t module_inst = + wasm_runtime_get_current_module_inst(); + union { uint64 u64; uint32 parts[2]; } inst; + + inst.parts[0] = inst_part0; + inst.parts[1] = inst_part1; + + if (inst.u64 != (uint64)(uintptr_t)module_inst) { + printf("Invalid module instance\n"); + return false; + } + + ret = wasm_runtime_validate_app_addr(module_inst, app_offset, size); + if (!ret) + wasm_runtime_clear_exception(module_inst); + return ret; +} + +static bool +wasm_runtime_validate_native_addr_wrapper(uint32 inst_part0, uint32 inst_part1, + uint32 native_ptr_part0, + uint32 native_ptr_part1, + uint32 size) +{ + bool ret; + wasm_module_inst_t module_inst = + wasm_runtime_get_current_module_inst(); + union { uint64 u64; uint32 parts[2]; } inst; + union { uint64 u64; uint32 parts[2]; } native_ptr; + + inst.parts[0] = inst_part0; + inst.parts[1] = inst_part1; + + if (inst.u64 != (uint64)(uintptr_t)module_inst) { + printf("Invalid module instance\n"); + return false; + } + + native_ptr.parts[0] = native_ptr_part0; + native_ptr.parts[1] = native_ptr_part1; + ret = wasm_runtime_validate_native_addr(module_inst, + (void*)(uintptr_t)native_ptr.u64, + size); + if (!ret) + wasm_runtime_clear_exception(module_inst); + return ret; +} + +static uint64 +wasm_runtime_addr_app_to_native_wrapper(uint32 inst_part0, uint32 inst_part1, + int32 app_offset) +{ + wasm_module_inst_t module_inst = + wasm_runtime_get_current_module_inst(); + union { uint64 u64; uint32 parts[2]; } inst; + + inst.parts[0] = inst_part0; + inst.parts[1] = inst_part1; + + if (inst.u64 != (uint64)(uintptr_t)module_inst) { + printf("Invalid module instance\n"); + return 0; + } + return (uint64)(uintptr_t) + wasm_runtime_addr_app_to_native(module_inst, app_offset); +} + +static int32 +wasm_runtime_addr_native_to_app_wrapper(uint32 inst_part0, uint32 inst_part1, + uint32 native_ptr_part0, + uint32 native_ptr_part1) +{ + wasm_module_inst_t module_inst = + wasm_runtime_get_current_module_inst(); + union { uint64 u64; uint32 parts[2]; } inst; + union { uint64 u64; uint32 parts[2]; } native_ptr; + + inst.parts[0] = inst_part0; + inst.parts[1] = inst_part1; + + if (inst.u64 != (uint64)(uintptr_t)module_inst) { + printf("Invalid module instance\n"); + return 0; + } + + native_ptr.parts[0] = native_ptr_part0; + native_ptr.parts[1] = native_ptr_part1; + return wasm_runtime_addr_native_to_app(module_inst, + (void*)(uintptr_t)native_ptr.u64); +} + static NativeSymbol extended_native_symbol_defs[] = { /* TODO: use macro EXPORT_WASM_API() or EXPORT_WASM_API2() to add functions to register. */ @@ -38,6 +143,11 @@ static NativeSymbol extended_native_symbol_defs[] = { EXPORT_WASM_API(wasm_timer_restart), EXPORT_WASM_API(wasm_get_sys_tick_ms), #endif + EXPORT_WASM_API2(wasm_runtime_get_current_module_inst), + EXPORT_WASM_API2(wasm_runtime_validate_app_addr), + EXPORT_WASM_API2(wasm_runtime_validate_native_addr), + EXPORT_WASM_API2(wasm_runtime_addr_app_to_native), + EXPORT_WASM_API2(wasm_runtime_addr_native_to_app), }; int get_base_lib_export_apis(NativeSymbol **p_base_lib_apis) diff --git a/core/iwasm/lib/native/extension/connection/connection.inl b/core/iwasm/lib/native/extension/connection/connection.inl new file mode 100644 index 00000000..e7366509 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/connection.inl @@ -0,0 +1,20 @@ +/* +* Copyright (C) 2019 Intel Corporation. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +EXPORT_WASM_API(wasm_open_connection), +EXPORT_WASM_API(wasm_close_connection), +EXPORT_WASM_API(wasm_send_on_connection), +EXPORT_WASM_API(wasm_config_connection), diff --git a/core/iwasm/lib/native/extension/connection/connection_lib.h b/core/iwasm/lib/native/extension/connection/connection_lib.h new file mode 100644 index 00000000..49d2e397 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/connection_lib.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CONNECTION_LIB_H_ +#define CONNECTION_LIB_H_ + +#include "attr_container.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + ***************** + * This file defines connection library which should be implemented by different platforms + ***************** + */ + +/* + * @brief Open a connection. + * + * @param name name of the connection, "TCP", "UDP" or "UART" + * @param args connection arguments, such as: ip:127.0.0.1, port:8888 + * + * @return 0~0xFFFFFFFE means id of the connection, otherwise(-1) means fail + */ +typedef uint32 (*connection_open_f)(const char *name, attr_container_t *args); + +/* + * @brief Close a connection. + * + * @param handle of the connection + */ +typedef void (*connection_close_f)(uint32 handle); + +/* + * @brief Send data to the connection in non-blocking manner. + * + * @param handle of the connection + * @param data data buffer to be sent + * @param len length of the data in byte + * + * @return actual length sent, -1 if fail + */ +typedef int (*connection_send_f)(uint32 handle, const char *data, int len); + +/* + * @brief Configure connection. + * + * @param handle of the connection + * @param cfg configurations + * + * @return true if success, false otherwise + */ +typedef bool (*connection_config_f)(uint32 handle, attr_container_t *cfg); + +/* Raw connection interface for platform to implement */ +typedef struct _connection_interface { + connection_open_f _open; + connection_close_f _close; + connection_send_f _send; + connection_config_f _config; +} connection_interface_t; + +/* Platform must define this interface */ +extern connection_interface_t connection_impl; + +#ifdef __cplusplus +} +#endif + + +#endif /* CONNECTION_LIB_H_ */ diff --git a/core/iwasm/lib/native/extension/connection/connection_wrapper.c b/core/iwasm/lib/native/extension/connection/connection_wrapper.c new file mode 100644 index 00000000..7bcf5860 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/connection_wrapper.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "connection_lib.h" +#include "wasm_export.h" +#include "native_interface.h" + +/* Note: + * + * This file is the consumer of connection lib which is implemented by different platforms + */ + + +uint32 wasm_open_connection(int32 name_offset, int32 args_offset, uint32 len) +{ + wasm_module_inst_t module_inst = get_module_inst(); + attr_container_t *args; + char *name, *args_buf; + + if (!validate_app_addr(name_offset, 1) || + !validate_app_addr(args_offset, len) || + !(name = addr_app_to_native(name_offset)) || + !(args_buf = addr_app_to_native(args_offset))) + return -1; + + args = (attr_container_t *)args_buf; + + if (connection_impl._open != NULL) + return connection_impl._open(name, args); + + return -1; +} + +void wasm_close_connection(uint32 handle) +{ + if (connection_impl._close != NULL) + connection_impl._close(handle); +} + +int wasm_send_on_connection(uint32 handle, int32 data_offset, uint32 len) +{ + wasm_module_inst_t module_inst = get_module_inst(); + char *data; + + if (!validate_app_addr(data_offset, len) || + !(data = addr_app_to_native(data_offset))) + return -1; + + if (connection_impl._send != NULL) + return connection_impl._send(handle, data, len); + + return -1; +} + +bool wasm_config_connection(uint32 handle, int32 cfg_offset, uint32 len) +{ + wasm_module_inst_t module_inst = get_module_inst(); + char *cfg_buf; + attr_container_t *cfg; + + if (!validate_app_addr(cfg_offset, len) || + !(cfg_buf = addr_app_to_native(cfg_offset))) + return false; + + cfg = (attr_container_t *)cfg_buf; + + if (connection_impl._config != NULL) + return connection_impl._config(handle, cfg); + + return false; +} diff --git a/core/iwasm/lib/native/extension/connection/linux/conn_tcp.c b/core/iwasm/lib/native/extension/connection/linux/conn_tcp.c new file mode 100644 index 00000000..3a6bded2 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/conn_tcp.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "conn_tcp.h" + +#include +#include +#include +#include +#include + +int tcp_open(char *address, uint16 port) +{ + int sock, ret; + struct sockaddr_in servaddr; + + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr(address); + servaddr.sin_port = htons(port); + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock == -1) + return -1; + + ret = connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)); + if (ret == -1) { + close(sock); + return -1; + } + + /* Put the socket in non-blocking mode */ + if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) < 0) { + close(sock); + return -1; + } + + return sock; +} + +int tcp_send(int sock, const char *data, int size) +{ + return send(sock, data, size, 0); +} + +int tcp_recv(int sock, char *buffer, int buf_size) +{ + return recv(sock, buffer, buf_size, 0); +} diff --git a/core/iwasm/runtime/platform/include/wasm_types.h b/core/iwasm/lib/native/extension/connection/linux/conn_tcp.h similarity index 64% rename from core/iwasm/runtime/platform/include/wasm_types.h rename to core/iwasm/lib/native/extension/connection/linux/conn_tcp.h index a0bdbc16..84caf2a1 100644 --- a/core/iwasm/runtime/platform/include/wasm_types.h +++ b/core/iwasm/lib/native/extension/connection/linux/conn_tcp.h @@ -14,25 +14,24 @@ * limitations under the License. */ -#ifndef _WASM_TYPES_H -#define _WASM_TYPES_H +#ifndef CONN_LINUX_TCP_H_ +#define CONN_LINUX_TCP_H_ -#include "wasm_config.h" +#include "bh_platform.h" -typedef unsigned char uint8; -typedef char int8; -typedef unsigned short uint16; -typedef short int16; -typedef unsigned int uint32; -typedef int int32; - -#include "wasm_platform.h" - -#ifndef __cplusplus -#define true 1 -#define false 0 -#define inline __inline +#ifdef __cplusplus +extern "C" { #endif -#endif /* end of _WASM_TYPES_H */ +int tcp_open(char *address, uint16 port); +int tcp_send(int sock, const char *data, int size); + +int tcp_recv(int sock, char *buffer, int buf_size); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/core/iwasm/lib/native/extension/connection/linux/conn_uart.c b/core/iwasm/lib/native/extension/connection/linux/conn_uart.c new file mode 100644 index 00000000..6ca848b6 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/conn_uart.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "conn_uart.h" + +#include +#include +#include + +static int parse_baudrate(int baud) +{ + switch (baud) { + case 9600: + return B9600; + case 19200: + return B19200; + case 38400: + return B38400; + case 57600: + return B57600; + case 115200: + return B115200; + case 230400: + return B230400; + case 460800: + return B460800; + case 500000: + return B500000; + case 576000: + return B576000; + case 921600: + return B921600; + case 1000000: + return B1000000; + case 1152000: + return B1152000; + case 1500000: + return B1500000; + case 2000000: + return B2000000; + case 2500000: + return B2500000; + case 3000000: + return B3000000; + case 3500000: + return B3500000; + case 4000000: + return B4000000; + default: + return -1; + } +} + +int uart_open(char* device, int baudrate) +{ + int uart_fd; + struct termios uart_term; + + uart_fd = open(device, O_RDWR | O_NOCTTY); + + if (uart_fd <= 0) + return -1; + + memset(&uart_term, 0, sizeof(uart_term)); + uart_term.c_cflag = parse_baudrate(baudrate) | CS8 | CLOCAL | CREAD; + uart_term.c_iflag = IGNPAR; + uart_term.c_oflag = 0; + + /* set noncanonical mode */ + uart_term.c_lflag = 0; + uart_term.c_cc[VTIME] = 30; + uart_term.c_cc[VMIN] = 1; + tcflush(uart_fd, TCIFLUSH); + + if (tcsetattr(uart_fd, TCSANOW, &uart_term) != 0) { + close(uart_fd); + return -1; + } + + /* Put the fd in non-blocking mode */ + if (fcntl(uart_fd, F_SETFL, fcntl(uart_fd, F_GETFL) | O_NONBLOCK) < 0) { + close(uart_fd); + return -1; + } + + return uart_fd; +} + +int uart_send(int fd, const char *data, int size) +{ + return write(fd, data, size); +} + +int uart_recv(int fd, char *buffer, int buf_size) +{ + return read(fd, buffer, buf_size); +} diff --git a/core/iwasm/lib/native/extension/connection/linux/conn_uart.h b/core/iwasm/lib/native/extension/connection/linux/conn_uart.h new file mode 100644 index 00000000..1e67811d --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/conn_uart.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CONN_LINUX_UART_H_ +#define CONN_LINUX_UART_H_ + +#include "bh_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int uart_open(char* device, int baudrate); + +int uart_send(int fd, const char *data, int size); + +int uart_recv(int fd, char *buffer, int buf_size); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/core/iwasm/lib/native/extension/connection/linux/conn_udp.c b/core/iwasm/lib/native/extension/connection/linux/conn_udp.c new file mode 100644 index 00000000..d93c23f8 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/conn_udp.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "conn_udp.h" + +#include +#include +#include +#include +#include + +int udp_open(uint16 port) +{ + int sock, ret; + struct sockaddr_in addr; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == -1) + return -1; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(port); + + ret = bind(sock, (struct sockaddr*)&addr, sizeof(addr)); + if (ret == -1) + return -1; + + /* Put the socket in non-blocking mode */ + if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) < 0) { + close(sock); + return -1; + } + + return sock; +} + +int udp_send(int sock, struct sockaddr *dest, const char *data, int size) +{ + return sendto(sock, data, size, MSG_CONFIRM, dest, sizeof(*dest)); +} + +int udp_recv(int sock, char *buffer, int buf_size) +{ + struct sockaddr_in remaddr; + socklen_t addrlen = sizeof(remaddr); + + return recvfrom(sock, + buffer, + buf_size, + 0, + (struct sockaddr *)&remaddr, + &addrlen); +} diff --git a/core/iwasm/lib/native/extension/connection/linux/conn_udp.h b/core/iwasm/lib/native/extension/connection/linux/conn_udp.h new file mode 100644 index 00000000..f3cbf4b1 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/conn_udp.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CONN_LINUX_UDP_H_ +#define CONN_LINUX_UDP_H_ + +#include "bh_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int udp_open(uint16 port); + +int udp_send(int sock, struct sockaddr *dest, const char *data, int size); + +int udp_recv(int sock, char *buffer, int buf_size); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/core/iwasm/lib/native/extension/connection/linux/connection_mgr.c b/core/iwasm/lib/native/extension/connection/linux/connection_mgr.c new file mode 100644 index 00000000..27c18cd7 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/connection_mgr.c @@ -0,0 +1,572 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Note: + * This file implements the linux version connection library which is + * defined in connection_lib.h. + * It also provides a reference implementation of connections manager. + */ + +#include "connection_lib.h" +#include "bh_thread.h" +#include "app_manager_export.h" +#include "module_wasm_app.h" +#include "conn_tcp.h" +#include "conn_udp.h" +#include "conn_uart.h" +#include "bh_definition.h" + +#include +#include +#include +#include +#include + +#define MAX_EVENTS 10 +#define IO_BUF_SIZE 256 + +/* Connection type */ +typedef enum conn_type { + CONN_TYPE_TCP, + CONN_TYPE_UDP, + CONN_TYPE_UART, + CONN_TYPE_UNKNOWN +} conn_type_t; + +/* Sys connection */ +typedef struct sys_connection { + /* Next connection */ + struct sys_connection *next; + + /* Type */ + conn_type_t type; + + /* Handle to interact with wasm app */ + uint32 handle; + + /* Underlying connection ID, may be socket fd */ + int fd; + + /* Module id that the connection belongs to */ + uint32 module_id; + + /* Argument, such as dest addr for udp */ + void *arg; +} sys_connection_t; + +/* Epoll instance */ +static int epollfd; + +/* Connections list */ +static sys_connection_t *g_connections = NULL; + +/* Max handle */ +static uint32 g_handle_max = 0; + +/* Lock to protect g_connections and g_handle_max */ +static korp_mutex g_lock; + +/* Epoll events */ +static struct epoll_event epoll_events[MAX_EVENTS]; + +/* Buffer to receive data */ +static char io_buf[IO_BUF_SIZE]; + +static uint32 _conn_open(const char *name, attr_container_t *args); +static void _conn_close(uint32 handle); +static int _conn_send(uint32 handle, const char *data, int len); +static bool _conn_config(uint32 handle, attr_container_t *cfg); + +/* + * Platform implementation of connection library + */ +connection_interface_t connection_impl = { + ._open = _conn_open, + ._close = _conn_close, + ._send = _conn_send, + ._config = _conn_config +}; + +static void add_connection(sys_connection_t *conn) +{ + vm_mutex_lock(&g_lock); + + g_handle_max++; + if (g_handle_max == -1) + g_handle_max++; + conn->handle = g_handle_max; + + if (g_connections) { + conn->next = g_connections; + g_connections = conn; + } else { + g_connections = conn; + } + + vm_mutex_unlock(&g_lock); +} + +#define FREE_CONNECTION(conn) do { \ + if (conn->arg) \ + bh_free(conn->arg); \ + bh_free(conn); \ +} while (0) + +static int get_app_conns_num(uint32 module_id) +{ + sys_connection_t *conn; + int num = 0; + + vm_mutex_lock(&g_lock); + + conn = g_connections; + while (conn) { + if (conn->module_id == module_id) + num++; + conn = conn->next; + } + + vm_mutex_unlock(&g_lock); + + return num; +} + +static sys_connection_t *find_connection(uint32 handle, bool remove_found) +{ + sys_connection_t *conn, *prev = NULL; + + vm_mutex_lock(&g_lock); + + conn = g_connections; + while (conn) { + if (conn->handle == handle) { + if (remove_found) { + if (prev != NULL) { + prev->next = conn->next; + } else { + g_connections = conn->next; + } + } + vm_mutex_unlock(&g_lock); + return conn; + } else { + prev = conn; + conn = conn->next; + } + } + + vm_mutex_unlock(&g_lock); + + return NULL; +} + +static void cleanup_connections(uint32 module_id) +{ + sys_connection_t *conn, *prev = NULL; + + vm_mutex_lock(&g_lock); + + conn = g_connections; + while (conn) { + if (conn->module_id == module_id) { + epoll_ctl(epollfd, EPOLL_CTL_DEL, conn->fd, NULL); + close(conn->fd); + + if (prev != NULL) { + prev->next = conn->next; + FREE_CONNECTION(conn); + conn = prev->next; + } else { + g_connections = conn->next; + FREE_CONNECTION(conn); + conn = g_connections; + } + } else { + prev = conn; + conn = conn->next; + } + } + + vm_mutex_unlock(&g_lock); +} + +static conn_type_t get_conn_type(const char *name) +{ + if (strcmp(name, "TCP") == 0) + return CONN_TYPE_TCP; + if (strcmp(name, "UDP") == 0) + return CONN_TYPE_UDP; + if (strcmp(name, "UART") == 0) + return CONN_TYPE_UART; + + return CONN_TYPE_UNKNOWN; +} + +/* --- connection lib function --- */ +static uint32 _conn_open(const char *name, attr_container_t *args) +{ + int fd; + sys_connection_t *conn; + struct epoll_event ev; + uint32 module_id = app_manager_get_module_id(Module_WASM_App); + + if (get_app_conns_num(module_id) >= MAX_CONNECTION_PER_APP) + return -1; + + conn = (sys_connection_t *)bh_malloc(sizeof(*conn)); + if (conn == NULL) + return -1; + + memset(conn, 0, sizeof(*conn)); + conn->module_id = module_id; + conn->type = get_conn_type(name); + + /* Generate a handle and add to list */ + add_connection(conn); + + if (conn->type == CONN_TYPE_TCP) { + char *address; + uint16 port; + + /* Check and parse connection parameters */ + if (!attr_container_contain_key(args, "address") || + !attr_container_contain_key(args, "port")) + goto fail; + + address = attr_container_get_as_string(args, "address"); + port = attr_container_get_as_uint16(args, "port"); + + /* Connect to TCP server */ + if ((fd = tcp_open(address, port)) == -1) + goto fail; + + } else if (conn->type == CONN_TYPE_UDP) { + uint16 port; + + /* Check and parse connection parameters */ + if (!attr_container_contain_key(args, "bind port")) + goto fail; + port = attr_container_get_as_uint16(args, "bind port"); + + /* Bind port */ + if ((fd = udp_open(port)) == -1) + goto fail; + + } else if (conn->type == CONN_TYPE_UART) { + char *device; + int baud; + + /* Check and parse connection parameters */ + if (!attr_container_contain_key(args, "device") || + !attr_container_contain_key(args, "baudrate")) + goto fail; + device = attr_container_get_as_string(args, "device"); + baud = attr_container_get_as_int(args, "baudrate"); + + /* Open device */ + if ((fd = uart_open(device, baud)) == -1) + goto fail; + + } + + conn->fd = fd; + + /* Set current connection as event data */ + ev.events = EPOLLIN; + ev.data.ptr = conn; + + /* Monitor incoming data */ + if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { + close(fd); + goto fail; + } + + return conn->handle; + +fail: + find_connection(conn->handle, true); + bh_free(conn); + return -1; +} + +/* --- connection lib function --- */ +static void _conn_close(uint32 handle) +{ + sys_connection_t *conn = find_connection(handle, true); + + if (conn != NULL) { + epoll_ctl(epollfd, EPOLL_CTL_DEL, conn->fd, NULL); + close(conn->fd); + FREE_CONNECTION(conn); + } +} + +/* --- connection lib function --- */ +static int _conn_send(uint32 handle, const char *data, int len) +{ + sys_connection_t *conn = find_connection(handle, false); + + if (conn == NULL) + return -1; + + if (conn->type == CONN_TYPE_TCP) + return tcp_send(conn->fd, data, len); + + if (conn->type == CONN_TYPE_UDP) { + struct sockaddr *addr = (struct sockaddr *)conn->arg; + return udp_send(conn->fd, addr, data, len); + } + + if (conn->type == CONN_TYPE_UART) + return uart_send(conn->fd, data, len); + + return -1; +} + +/* --- connection lib function --- */ +static bool _conn_config(uint32 handle, attr_container_t *cfg) +{ + sys_connection_t *conn = find_connection(handle, false); + + if (conn == NULL) + return false; + + if (conn->type == CONN_TYPE_UDP) { + char *address; + uint16_t port; + struct sockaddr_in *addr; + + /* Parse remote address/port */ + if (!attr_container_contain_key(cfg, "address") || + !attr_container_contain_key(cfg, "port")) + return false; + address = attr_container_get_as_string(cfg, "address"); + port = attr_container_get_as_uint16(cfg, "port"); + + if (conn->arg == NULL) { + addr = (struct sockaddr_in *)bh_malloc(sizeof(*addr)); + if (addr == NULL) + return false; + + memset(addr, 0, sizeof(*addr)); + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = inet_addr(address); + addr->sin_port = htons(port); + + /* Set remote address as connection arg */ + conn->arg = addr; + } else { + addr = (struct sockaddr_in *)conn->arg; + addr->sin_addr.s_addr = inet_addr(address); + addr->sin_port = htons(port); + } + + return true; + } + + return false; +} + +/* --- connection manager reference implementation ---*/ + +typedef struct connection_event { + uint32 handle; + char *data; + uint32 len; +} connection_event_t; + +static void connection_event_cleaner(connection_event_t *conn_event) +{ + if (conn_event->data != NULL) + bh_free(conn_event->data); + bh_free(conn_event); +} + +static void post_msg_to_module(sys_connection_t *conn, + char *data, + uint32 len) +{ + module_data *module = module_data_list_lookup_id(conn->module_id); + char *data_copy = NULL; + connection_event_t *conn_data_event; + bh_message_t msg; + + if (module == NULL) + return; + + conn_data_event = (connection_event_t *)bh_malloc(sizeof(*conn_data_event)); + if (conn_data_event == NULL) + return; + + if (len > 0) { + data_copy = (char *)bh_malloc(len); + if (data_copy == NULL) { + bh_free(conn_data_event); + return; + } + memcpy(data_copy, data, len); + } + + memset(conn_data_event, 0, sizeof(*conn_data_event)); + conn_data_event->handle = conn->handle; + conn_data_event->data = data_copy; + conn_data_event->len = len; + + msg = bh_new_msg(CONNECTION_EVENT_WASM, + conn_data_event, + sizeof(*conn_data_event), + connection_event_cleaner); + if (!msg) { + connection_event_cleaner(conn_data_event); + return; + } + + bh_post_msg2(module->queue, msg); +} + +static void* polling_thread_routine (void *arg) +{ + while (true) { + int i, n; + + n = epoll_wait(epollfd, epoll_events, MAX_EVENTS, -1); + + if (n == -1 && errno != EINTR) + continue; + + for (i = 0; i < n; i++) { + sys_connection_t *conn + = (sys_connection_t *)epoll_events[i].data.ptr; + + if (conn->type == CONN_TYPE_TCP) { + int count = tcp_recv(conn->fd, io_buf, IO_BUF_SIZE); + if (count <= 0) { + /* Connection is closed by peer */ + post_msg_to_module(conn, NULL, 0); + _conn_close(conn->handle); + } else { + /* Data is received */ + post_msg_to_module(conn, io_buf, count); + } + } else if (conn->type == CONN_TYPE_UDP) { + int count = udp_recv(conn->fd, io_buf, IO_BUF_SIZE); + if (count > 0) + post_msg_to_module(conn, io_buf, count); + } else if (conn->type == CONN_TYPE_UART) { + int count = uart_recv(conn->fd, io_buf, IO_BUF_SIZE); + if (count > 0) + post_msg_to_module(conn, io_buf, count); + } + } + } + + return NULL; +} + +void app_mgr_connection_event_callback(module_data *m_data, bh_message_t msg) +{ + uint32 argv[3]; + wasm_function_inst_t func_on_conn_data; + bh_assert(CONNECTION_EVENT_WASM == bh_message_type(msg)); + wasm_data *wasm_app_data = (wasm_data*) m_data->internal_data; + wasm_module_inst_t inst = wasm_app_data->wasm_module_inst; + connection_event_t *conn_event + = (connection_event_t *)bh_message_payload(msg); + int32 data_offset; + + if (conn_event == NULL) + return; + + func_on_conn_data = wasm_runtime_lookup_function(inst, "_on_connection_data", + "(i32i32i32)"); + if (!func_on_conn_data) { + printf("Cannot find function _on_connection_data\n"); + return; + } + + /* 0 len means connection closed */ + if (conn_event->len == 0) { + argv[0] = conn_event->handle; + argv[1] = 0; + argv[2] = 0; + if (!wasm_runtime_call_wasm(inst, NULL, func_on_conn_data, 3, argv)) { + printf(":Got exception running wasm code: %s\n", + wasm_runtime_get_exception(inst)); + wasm_runtime_clear_exception(inst); + return; + } + } else { + data_offset = wasm_runtime_module_dup_data(inst, + conn_event->data, + conn_event->len); + if (data_offset == 0) { + printf("Got exception running wasm code: %s\n", + wasm_runtime_get_exception(inst)); + wasm_runtime_clear_exception(inst); + return; + } + + argv[0] = conn_event->handle; + argv[1] = (uint32) data_offset; + argv[2] = conn_event->len; + if (!wasm_runtime_call_wasm(inst, NULL, func_on_conn_data, 3, argv)) { + printf(":Got exception running wasm code: %s\n", + wasm_runtime_get_exception(inst)); + wasm_runtime_clear_exception(inst); + wasm_runtime_module_free(inst, data_offset); + return; + } + wasm_runtime_module_free(inst, data_offset); + } +} + +bool init_connection_framework() +{ + korp_thread tid; + + epollfd = epoll_create(MAX_EVENTS); + if (epollfd == -1) + return false; + + if (vm_mutex_init(&g_lock) != BH_SUCCESS) { + close(epollfd); + return false; + } + + if (!wasm_register_cleanup_callback(cleanup_connections)) { + goto fail; + } + + if (!wasm_register_msg_callback(CONNECTION_EVENT_WASM, + app_mgr_connection_event_callback)) { + goto fail; + } + + if (vm_thread_create(&tid, + polling_thread_routine, + NULL, + BH_APPLET_PRESERVED_STACK_SIZE) != BH_SUCCESS) { + goto fail; + } + + return true; + +fail: + vm_mutex_destroy(&g_lock); + close(epollfd); + return false; +} diff --git a/core/iwasm/lib/native/extension/connection/linux/connection_mgr.cmake b/core/iwasm/lib/native/extension/connection/linux/connection_mgr.cmake new file mode 100644 index 00000000..72ab4554 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/linux/connection_mgr.cmake @@ -0,0 +1,24 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set (WASM_LIB_CONN_MGR_DIR ${CMAKE_CURRENT_LIST_DIR}) + +include_directories(${WASM_LIB_CONN_MGR_DIR}) + + +file (GLOB_RECURSE source_all ${WASM_LIB_CONN_MGR_DIR}/*.c) + +set (WASM_LIB_CONN_MGR_SOURCE ${source_all}) + + diff --git a/core/iwasm/lib/native/extension/connection/wasm_lib_conn.cmake b/core/iwasm/lib/native/extension/connection/wasm_lib_conn.cmake new file mode 100644 index 00000000..2018706e --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/wasm_lib_conn.cmake @@ -0,0 +1,23 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set (WASM_LIB_CONN_DIR ${CMAKE_CURRENT_LIST_DIR}) + +include_directories(${WASM_LIB_CONN_DIR}) + + +file (GLOB source_all ${WASM_LIB_CONN_DIR}/*.c) + +set (WASM_LIB_CONN_SOURCE ${source_all}) + diff --git a/core/iwasm/lib/native/extension/connection/zephyr/connection_lib_impl.c b/core/iwasm/lib/native/extension/connection/zephyr/connection_lib_impl.c new file mode 100644 index 00000000..37943707 --- /dev/null +++ b/core/iwasm/lib/native/extension/connection/zephyr/connection_lib_impl.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Note: + * This file implements the linux version connection library which is + * defined in connection_lib.h. + * It also provides a reference impl of connections manager. + */ + +#include "connection_lib.h" + +/* + * Platform implementation of connection library + */ +connection_interface_t connection_impl = { + ._open = NULL, + ._close = NULL, + ._send = NULL, + ._config = NULL +}; diff --git a/core/iwasm/lib/native/extension/gui/wamr_gui.inl b/core/iwasm/lib/native/extension/gui/wamr_gui.inl new file mode 100644 index 00000000..49ce5bff --- /dev/null +++ b/core/iwasm/lib/native/extension/gui/wamr_gui.inl @@ -0,0 +1,39 @@ +/* +* Copyright (C) 2019 Intel Corporation. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* button */ +EXPORT_WASM_API(wasm_btn_native_call), + +/* obj */ +EXPORT_WASM_API(wasm_obj_native_call), + +/* label */ +EXPORT_WASM_API(wasm_label_native_call), + +/* cont */ +//EXPORT_WASM_API(wasm_cont_native_call), + +/* page */ +//EXPORT_WASM_API(wasm_page_native_call), + +/* list */ +EXPORT_WASM_API(wasm_list_native_call), + +/* drop down list */ +//EXPORT_WASM_API(wasm_ddlist_native_call), + +/* check box */ +EXPORT_WASM_API(wasm_cb_native_call), diff --git a/core/iwasm/lib/native/extension/gui/wasm_lib_gui.cmake b/core/iwasm/lib/native/extension/gui/wasm_lib_gui.cmake new file mode 100644 index 00000000..d8af8c9e --- /dev/null +++ b/core/iwasm/lib/native/extension/gui/wasm_lib_gui.cmake @@ -0,0 +1,25 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set (WASM_LIB_GUI_DIR ${CMAKE_CURRENT_LIST_DIR}) + +set (THIRD_PARTY_DIR ${WASM_LIB_GUI_DIR}/../../../3rdparty) + +include_directories(${WASM_LIB_GUI_DIR} ${THIRD_PARTY_DIR} ${THIRD_PARTY_DIR}/lvgl) + +file (GLOB_RECURSE lvgl_source ${THIRD_PARTY_DIR}/lvgl/*.c) +file (GLOB_RECURSE wrapper_source ${WASM_LIB_GUI_DIR}/*.c) + +set (WASM_LIB_GUI_SOURCE ${wrapper_source} ${lvgl_source}) + diff --git a/core/iwasm/lib/native/extension/gui/wgl_btn_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_btn_wrapper.c new file mode 100644 index 00000000..7b41826d --- /dev/null +++ b/core/iwasm/lib/native/extension/gui/wgl_btn_wrapper.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "native_interface.h" +#include "lvgl.h" +#include "module_wasm_app.h" +#include "wgl_native_utils.h" + +/* ------------------------------------------------------------------------- + * Button widget native function wrappers + * -------------------------------------------------------------------------*/ +static int32 _btn_create(lv_obj_t *par, lv_obj_t *copy) +{ + return wgl_native_wigdet_create(WIDGET_TYPE_BTN, par, copy); +} + +static WGLNativeFuncDef btn_native_func_defs[] = { + { BTN_FUNC_ID_CREATE, _btn_create, HAS_RET, 2, {0 | NULL_OK, 1 | NULL_OK, -1}, {-1} }, + { BTN_FUNC_ID_SET_TOGGLE, lv_btn_set_toggle, NO_RET, 2, {0, -1}, {-1} }, + { BTN_FUNC_ID_SET_STATE, lv_btn_set_state, NO_RET, 2, {0, -1}, {-1} }, +// { BTN_FUNC_ID_SET_STYLE, _btn_set_style, NO_RET, 2, {0, -1}, {-1} }, + { BTN_FUNC_ID_SET_INK_IN_TIME, lv_btn_set_ink_in_time, NO_RET, 2, {0, -1}, {-1} }, + { BTN_FUNC_ID_SET_INK_OUT_TIME, lv_btn_set_ink_out_time, NO_RET, 2, {0, -1}, {-1} }, + { BTN_FUNC_ID_SET_INK_WAIT_TIME, lv_btn_set_ink_wait_time, NO_RET, 2, {0, -1}, {-1} }, + { BTN_FUNC_ID_GET_INK_IN_TIME, lv_btn_get_ink_in_time, HAS_RET, 1, {0, -1}, {-1} }, + { BTN_FUNC_ID_GET_INK_OUT_TIME, lv_btn_get_ink_out_time, HAS_RET, 1, {0, -1}, {-1} }, + { BTN_FUNC_ID_GET_INK_WAIT_TIME, lv_btn_get_ink_wait_time, HAS_RET, 1, {0, -1}, {-1} }, + { BTN_FUNC_ID_GET_STATE, lv_btn_get_state, HAS_RET, 1, {0, -1}, {-1} }, + { BTN_FUNC_ID_GET_TOGGLE, lv_btn_get_toggle, HAS_RET, 1, {0, -1}, {-1} }, + { BTN_FUNC_ID_TOGGLE, lv_btn_toggle, NO_RET, 1, {0, -1}, {-1} }, + +}; + +/*************** Native Interface to Wasm App ***********/ +void wasm_btn_native_call(int32 func_id, uint32 argv_offset, uint32 argc) +{ + uint32 size = sizeof(btn_native_func_defs) / sizeof(WGLNativeFuncDef); + + wgl_native_func_call(btn_native_func_defs, + size, + func_id, + argv_offset, + argc); +} diff --git a/core/iwasm/lib/native/extension/gui/wgl_cb_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_cb_wrapper.c new file mode 100644 index 00000000..43564331 --- /dev/null +++ b/core/iwasm/lib/native/extension/gui/wgl_cb_wrapper.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lvgl.h" +#include "wasm_export.h" +#include "native_interface.h" +#include "module_wasm_app.h" +#include "wgl_native_utils.h" + +/* ------------------------------------------------------------------------- + * Label widget native function wrappers + * -------------------------------------------------------------------------*/ +static int32 _cb_create(lv_obj_t *par, lv_obj_t *copy) +{ + return wgl_native_wigdet_create(WIDGET_TYPE_CB, par, copy); +} + +static int32 _cb_get_text_length(lv_obj_t *cb) +{ + const char *text = lv_cb_get_text(cb); + + if (text == NULL) + return 0; + + return strlen(text); +} + +static int32 _cb_get_text(lv_obj_t *cb, char *buffer, int buffer_len) +{ + wasm_module_inst_t module_inst = get_module_inst(); + const char *text = lv_cb_get_text(cb); + + if (text == NULL) + return 0; + + strncpy(buffer, text, buffer_len - 1); + buffer[buffer_len - 1] = '\0'; + + return addr_native_to_app(buffer); +} + +static WGLNativeFuncDef cb_native_func_defs[] = { + { CB_FUNC_ID_CREATE, _cb_create, HAS_RET, 2, {0 | NULL_OK, 1 | NULL_OK, -1}, {-1} }, + { CB_FUNC_ID_SET_TEXT, lv_cb_set_text, NO_RET, 2, {0, -1}, {1, -1} }, + { CB_FUNC_ID_SET_STATIC_TEXT, lv_cb_set_static_text, NO_RET, 2, {0, -1}, {1, -1} }, + { CB_FUNC_ID_GET_TEXT_LENGTH, _cb_get_text_length, HAS_RET, 1, {0, -1}, {-1} }, + { CB_FUNC_ID_GET_TEXT, _cb_get_text, HAS_RET, 3, {0, -1}, {1, -1} }, +}; + +/*************** Native Interface to Wasm App ***********/ +void wasm_cb_native_call(int32 func_id, uint32 argv_offset, uint32 argc) +{ + uint32 size = sizeof(cb_native_func_defs) / sizeof(WGLNativeFuncDef); + + wgl_native_func_call(cb_native_func_defs, + size, + func_id, + argv_offset, + argc); +} diff --git a/core/iwasm/lib/native/extension/gui/wgl_cont_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_cont_wrapper.c new file mode 100644 index 00000000..709ed753 --- /dev/null +++ b/core/iwasm/lib/native/extension/gui/wgl_cont_wrapper.c @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lvgl.h" +#include "module_wasm_app.h" diff --git a/core/iwasm/lib/native/extension/gui/wgl_label_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_label_wrapper.c new file mode 100644 index 00000000..edf5ba49 --- /dev/null +++ b/core/iwasm/lib/native/extension/gui/wgl_label_wrapper.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lvgl.h" +#include "wasm_export.h" +#include "native_interface.h" +#include "module_wasm_app.h" +#include "wgl_native_utils.h" + +/* ------------------------------------------------------------------------- + * Label widget native function wrappers + * -------------------------------------------------------------------------*/ +static int32 _label_create(lv_obj_t *par, lv_obj_t *copy) +{ + return wgl_native_wigdet_create(WIDGET_TYPE_LABEL, par, copy); +} + +static int32 _label_get_text_length(lv_obj_t *label) +{ + char *text = lv_label_get_text(label); + + if (text == NULL) + return 0; + + return strlen(text); +} + +static int32 _label_get_text(lv_obj_t *label, char *buffer, int buffer_len) +{ + wasm_module_inst_t module_inst = get_module_inst(); + char *text = lv_label_get_text(label); + + if (text == NULL) + return 0; + + strncpy(buffer, text, buffer_len - 1); + buffer[buffer_len - 1] = '\0'; + + return addr_native_to_app(buffer); +} + +static WGLNativeFuncDef label_native_func_defs[] = { + { LABEL_FUNC_ID_CREATE, _label_create, HAS_RET, 2, {0 | NULL_OK, 1 | NULL_OK, -1}, {-1} }, + { LABEL_FUNC_ID_SET_TEXT, lv_label_set_text, NO_RET, 2, {0, -1}, {1, -1} }, + { LABEL_FUNC_ID_GET_TEXT_LENGTH, _label_get_text_length, HAS_RET, 1, {0, -1}, {-1} }, + { LABEL_FUNC_ID_GET_TEXT, _label_get_text, HAS_RET, 3, {0, -1}, {1, -1} }, +}; + +/*************** Native Interface to Wasm App ***********/ +void wasm_label_native_call(int32 func_id, uint32 argv_offset, uint32 argc) +{ + uint32 size = sizeof(label_native_func_defs) / sizeof(WGLNativeFuncDef); + + wgl_native_func_call(label_native_func_defs, + size, + func_id, + argv_offset, + argc); +} diff --git a/core/iwasm/lib/native/extension/gui/wgl_list_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_list_wrapper.c new file mode 100644 index 00000000..88223077 --- /dev/null +++ b/core/iwasm/lib/native/extension/gui/wgl_list_wrapper.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "native_interface.h" +#include "lvgl.h" +#include "module_wasm_app.h" +#include "wgl_native_utils.h" + +/* ------------------------------------------------------------------------- + * List widget native function wrappers + * -------------------------------------------------------------------------*/ +static int32 _list_create(lv_obj_t *par, lv_obj_t *copy) +{ + return wgl_native_wigdet_create(WIDGET_TYPE_LIST, par, copy); +} + +static int32 _list_add_btn(lv_obj_t *list, const char *text) +{ + uint32 btn_obj_id; + lv_obj_t *btn; + + btn = lv_list_add_btn(list, NULL, text); + + if (btn == NULL) + return 0; + + if (wgl_native_add_object(btn, + app_manager_get_module_id(Module_WASM_App), + &btn_obj_id)) + return btn_obj_id; /* success return */ + + return 0; +} + +static WGLNativeFuncDef list_native_func_defs[] = { + { LIST_FUNC_ID_CREATE, _list_create, HAS_RET, 2, {0 | NULL_OK, 1 | NULL_OK, -1}, {-1} }, + { LIST_FUNC_ID_ADD_BTN, _list_add_btn, HAS_RET, 2, {0, -1}, {1, -1} }, +}; + +/*************** Native Interface to Wasm App ***********/ +void wasm_list_native_call(int32 func_id, uint32 argv_offset, uint32 argc) +{ + uint32 size = sizeof(list_native_func_defs) / sizeof(WGLNativeFuncDef); + + wgl_native_func_call(list_native_func_defs, + size, + func_id, + argv_offset, + argc); +} diff --git a/core/iwasm/lib/native/extension/gui/wgl_native_utils.c b/core/iwasm/lib/native/extension/gui/wgl_native_utils.c new file mode 100644 index 00000000..98bd85c6 --- /dev/null +++ b/core/iwasm/lib/native/extension/gui/wgl_native_utils.c @@ -0,0 +1,201 @@ + + +#include "wgl_native_utils.h" +#include "lvgl.h" +#include "module_wasm_app.h" +#include "wasm_export.h" + +#include + +#define THROW_EXC(msg) wasm_runtime_set_exception(get_module_inst(), msg); + +void +wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception); + +uint32 wgl_native_wigdet_create(int8 widget_type, lv_obj_t *par, lv_obj_t *copy) +{ + uint32 obj_id; + lv_obj_t *wigdet; + + //TODO: limit total widget number + + if (par == NULL) + par = lv_disp_get_scr_act(NULL); + + if (widget_type == WIDGET_TYPE_BTN) + wigdet = lv_btn_create(par, copy); + else if (widget_type == WIDGET_TYPE_LABEL) + wigdet = lv_label_create(par, copy); + else if (widget_type == WIDGET_TYPE_CB) + wigdet = lv_cb_create(par, copy); + else if (widget_type == WIDGET_TYPE_LIST) + wigdet = lv_list_create(par, copy); + else if (widget_type == WIDGET_TYPE_DDLIST) + wigdet = lv_ddlist_create(par, copy); + + if (wigdet == NULL) + return 0; + + if (wgl_native_add_object(wigdet, + app_manager_get_module_id(Module_WASM_App), + &obj_id)) + return obj_id; /* success return */ + + return 0; +} + +static void invokeNative(intptr_t argv[], uint32 argc, void (*native_code)()) +{ + switch(argc) { + case 0: + native_code(); + break; + case 1: + native_code(argv[0]); + break; + case 2: + native_code(argv[0], argv[1]); + break; + case 3: + native_code(argv[0], argv[1], argv[2]); + break; + case 4: + native_code(argv[0], argv[1], argv[2], argv[3]); + break; + case 5: + native_code(argv[0], argv[1], argv[2], argv[3], argv[4]); + break; + case 6: + native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); + break; + case 7: + native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], + argv[6]); + break; + case 8: + native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], + argv[6], argv[7]); + break; + case 9: + native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], + argv[6], argv[7], argv[8]); + break; + case 10: + native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], + argv[6], argv[7], argv[8], argv[9]); + break; + + default: + /* FIXME: If this happen, add more cases. */ + wasm_runtime_set_exception(get_module_inst(), + "the argument number of native function exceeds maximum"); + return; + } +} + +typedef void (*GenericFunctionPointer)(); +typedef int32 (*Int32FuncPtr)(intptr_t *, uint32, GenericFunctionPointer); +typedef void (*VoidFuncPtr)(intptr_t *, uint32, GenericFunctionPointer); + +static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative; +static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative; + +void wgl_native_func_call(WGLNativeFuncDef *funcs, + uint32 size, + int32 func_id, + uint32 argv_offset, + uint32 argc) +{ + WGLNativeFuncDef *func_def = funcs; + WGLNativeFuncDef *func_def_end = func_def + size; + uint32 *argv; + wasm_module_inst_t module_inst = get_module_inst(); + + if (!validate_app_addr(argv_offset, argc * sizeof(uint32))) + return; + + argv = addr_app_to_native(argv_offset); + + while (func_def < func_def_end) { + if (func_def->func_id == func_id) { + int i, obj_arg_num = 0, ptr_arg_num = 0; + intptr_t argv_copy_buf[16]; + intptr_t *argv_copy = argv_copy_buf; + + if (func_def->arg_num > 16) { + argv_copy = (intptr_t *)bh_malloc(func_def->arg_num * + sizeof(intptr_t)); + if (argv_copy == NULL) + return; + } + + /* Init argv_copy */ + for (i = 0; i < func_def->arg_num; i++) + argv_copy[i] = (intptr_t)argv[i]; + + /* Validate object arguments */ + i = 0; + for (; i < OBJ_ARG_NUM_MAX && func_def->obj_arg_indexes[i] != 0xff; + i++, obj_arg_num++) { + uint8 index = func_def->obj_arg_indexes[i]; + bool null_ok = index & NULL_OK; + + index = index & (~NULL_OK); + + /* Some API's allow to pass NULL obj, such as xxx_create() */ + if (argv[index] == 0) { + if (!null_ok) { + THROW_EXC("the object id is 0 and invalid"); + goto fail; + } + /* Continue so that to pass null object validation */ + continue; + } + + if (!wgl_native_validate_object(argv[index], (lv_obj_t **)&argv_copy[index])) { + THROW_EXC("the object is invalid"); + goto fail; + } + } + + /* Validate address arguments */ + i = 0; + for (; i < PTR_ARG_NUM_MAX && func_def->ptr_arg_indexes[i] != 0xff; + i++, ptr_arg_num++) { + uint8 index = func_def->ptr_arg_indexes[i]; + + /* The index+1 arg is the data size to be validated */ + if (!validate_app_addr(argv[index], argv[index + 1])) + goto fail; + + /* Convert to native address before call lvgl function */ + argv_copy[index] = (intptr_t)addr_app_to_native(argv[index]); + } + + if (func_def->has_ret == NO_RET) + invokeNative_Void(argv_copy, + func_def->arg_num, + func_def->func_ptr); + else + argv[0] = invokeNative_Int32(argv_copy, + func_def->arg_num, + func_def->func_ptr); + + if (argv_copy != argv_copy_buf) + bh_free(argv_copy); + + /* success return */ + return; + + fail: + if (argv_copy != argv_copy_buf) + bh_free(argv_copy); + return; + } + + func_def++; + } + + THROW_EXC("the native widget function is not found!"); +} + diff --git a/core/iwasm/lib/native/extension/gui/wgl_native_utils.h b/core/iwasm/lib/native/extension/gui/wgl_native_utils.h new file mode 100644 index 00000000..e3d73b52 --- /dev/null +++ b/core/iwasm/lib/native/extension/gui/wgl_native_utils.h @@ -0,0 +1,73 @@ + + +#ifndef WAMR_GRAPHIC_LIBRARY_NATIVE_UTILS_H +#define WAMR_GRAPHIC_LIBRARY_NATIVE_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "bh_platform.h" +#include "lvgl.h" + +#define OBJ_ARG_NUM_MAX 4 +#define PTR_ARG_NUM_MAX 4 + +#define NULL_OK 0x80 + +enum { + HAS_RET, + NO_RET +}; + +enum { + WIDGET_TYPE_BTN, + WIDGET_TYPE_LABEL, + WIDGET_TYPE_CB, + WIDGET_TYPE_LIST, + WIDGET_TYPE_DDLIST, + + _WIDGET_TYPE_NUM, +}; + +typedef struct WGLNativeFuncDef { + /* Function id */ + int32 func_id; + + /* Native function pointer */ + void *func_ptr; + + /* whether has return value */ + uint8 has_ret; + + /* argument number */ + uint8 arg_num; + + /* low 7 bit: obj argument index + * highest 1 bit: allow obj be null or not + * -1 means the end of this array */ + uint8 obj_arg_indexes[OBJ_ARG_NUM_MAX]; + + /* pointer argument indexes, -1 means the end of this array */ + uint8 ptr_arg_indexes[PTR_ARG_NUM_MAX]; +} WGLNativeFuncDef; + +bool wgl_native_validate_object(int32 obj_id, lv_obj_t **obj); + +bool wgl_native_add_object(lv_obj_t *obj, uint32 module_id, uint32 *obj_id); + +uint32 wgl_native_wigdet_create(int8 widget_type, + lv_obj_t *par, + lv_obj_t *copy); + +void wgl_native_func_call(WGLNativeFuncDef *funcs, + uint32 size, + int32 func_id, + uint32 argv_offset, + uint32 argc); + +#ifdef __cplusplus +} +#endif + +#endif /* WAMR_GRAPHIC_LIBRARY_NATIVE_UTILS_H */ diff --git a/core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c b/core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c new file mode 100644 index 00000000..cd9c724b --- /dev/null +++ b/core/iwasm/lib/native/extension/gui/wgl_obj_wrapper.c @@ -0,0 +1,353 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lvgl.h" +#include "app_manager_export.h" +#include "module_wasm_app.h" +#include "bh_list.h" +#include "bh_thread.h" +#include "wgl_native_utils.h" + + +typedef struct { + bh_list_link l; + + /* The object id. */ + uint32 obj_id; + + /* The lv object */ + lv_obj_t *obj; + + /* Module id that the obj belongs to */ + uint32 module_id; +} object_node_t; + +typedef struct { + int32 obj_id; + lv_event_t event; +} object_event_t; + +/* Max obj id */ +static uint32 g_obj_id_max = 0; + +static bh_list g_object_list; + +static korp_mutex g_object_list_mutex; + +static void app_mgr_object_event_callback(module_data *m_data, bh_message_t msg) +{ + uint32 argv[2]; + wasm_function_inst_t func_on_object_event; + bh_assert(WIDGET_EVENT_WASM == bh_message_type(msg)); + wasm_data *wasm_app_data = (wasm_data*) m_data->internal_data; + wasm_module_inst_t inst = wasm_app_data->wasm_module_inst; + object_event_t *object_event + = (object_event_t *)bh_message_payload(msg); + + if (object_event == NULL) + return; + + func_on_object_event = wasm_runtime_lookup_function(inst, "_on_widget_event", + "(i32i32)"); + if (!func_on_object_event) { + printf("Cannot find function _on_object_event\n"); + return; + } + + argv[0] = object_event->obj_id; + argv[1] = object_event->event; + if (!wasm_runtime_call_wasm(inst, NULL, func_on_object_event, 2, argv)) { + printf(":Got exception running wasm code: %s\n", + wasm_runtime_get_exception(inst)); + wasm_runtime_clear_exception(inst); + return; + } +} + +static void cleanup_object_list(uint32 module_id) +{ + object_node_t *elem; + + vm_mutex_lock(&g_object_list_mutex); + + while (true) { + bool found = false; + elem = (object_node_t *)bh_list_first_elem(&g_object_list); + while (elem) { + /* delete the leaf node belongs to the module firstly */ + if (module_id == elem->module_id && + lv_obj_count_children(elem->obj) == 0) { + object_node_t *next = (object_node_t *)bh_list_elem_next(elem); + + found = true; + lv_obj_del(elem->obj); + bh_list_remove(&g_object_list, elem); + bh_free(elem); + elem = next; + } else { + elem = (object_node_t *)bh_list_elem_next(elem); + } + } + + if (!found) + break; + } + + vm_mutex_unlock(&g_object_list_mutex); +} + +static bool init_object_event_callback_framework() +{ + if (!wasm_register_cleanup_callback(cleanup_object_list)) { + goto fail; + } + + if (!wasm_register_msg_callback(WIDGET_EVENT_WASM, + app_mgr_object_event_callback)) { + goto fail; + } + + return true; + +fail: + return false; +} + +bool wgl_native_validate_object(int32 obj_id, lv_obj_t **obj) +{ + object_node_t *elem; + + vm_mutex_lock(&g_object_list_mutex); + + elem = (object_node_t *)bh_list_first_elem(&g_object_list); + while (elem) { + if (obj_id == elem->obj_id) { + if (obj != NULL) + *obj = elem->obj; + vm_mutex_unlock(&g_object_list_mutex); + return true; + } + elem = (object_node_t *) bh_list_elem_next(elem); + } + + vm_mutex_unlock(&g_object_list_mutex); + + return false; +} + +bool wgl_native_add_object(lv_obj_t *obj, uint32 module_id, uint32 *obj_id) +{ + object_node_t *node; + + node = (object_node_t *) bh_malloc(sizeof(object_node_t)); + + if (node == NULL) + return false; + + /* Generate an obj id */ + g_obj_id_max++; + if (g_obj_id_max == -1) + g_obj_id_max = 1; + + memset(node, 0, sizeof(*node)); + node->obj = obj; + node->obj_id = g_obj_id_max; + node->module_id = module_id; + + vm_mutex_lock(&g_object_list_mutex); + bh_list_insert(&g_object_list, node); + vm_mutex_unlock(&g_object_list_mutex); + + if (obj_id != NULL) + *obj_id = node->obj_id; + + return true; +} + +static void _obj_del_recursive(lv_obj_t *obj) +{ + object_node_t *elem; + lv_obj_t * i; + lv_obj_t * i_next; + + i = lv_ll_get_head(&(obj->child_ll)); + + while (i != NULL) { + /*Get the next object before delete this*/ + i_next = lv_ll_get_next(&(obj->child_ll), i); + + /*Call the recursive del to the child too*/ + _obj_del_recursive(i); + + /*Set i to the next node*/ + i = i_next; + } + + vm_mutex_lock(&g_object_list_mutex); + + elem = (object_node_t *)bh_list_first_elem(&g_object_list); + while (elem) { + if (obj == elem->obj) { + bh_list_remove(&g_object_list, elem); + bh_free(elem); + vm_mutex_unlock(&g_object_list_mutex); + return; + } + elem = (object_node_t *) bh_list_elem_next(elem); + } + + vm_mutex_unlock(&g_object_list_mutex); +} + +static void _obj_clean_recursive(lv_obj_t *obj) +{ + lv_obj_t * i; + lv_obj_t * i_next; + + i = lv_ll_get_head(&(obj->child_ll)); + + while (i != NULL) { + /*Get the next object before delete this*/ + i_next = lv_ll_get_next(&(obj->child_ll), i); + + /*Call the recursive del to the child too*/ + _obj_del_recursive(i); + + /*Set i to the next node*/ + i = i_next; + } +} + +static void post_widget_msg_to_module(object_node_t *object_node, lv_event_t event) +{ + module_data *module = module_data_list_lookup_id(object_node->module_id); + object_event_t *object_event; + + if (module == NULL) + return; + + object_event = (object_event_t *)bh_malloc(sizeof(*object_event)); + if (object_event == NULL) + return; + + memset(object_event, 0, sizeof(*object_event)); + object_event->obj_id = object_node->obj_id; + object_event->event = event; + + bh_post_msg(module->queue, + WIDGET_EVENT_WASM, + object_event, + sizeof(*object_event)); +} + +static void internal_lv_obj_event_cb(lv_obj_t *obj, lv_event_t event) +{ + object_node_t *elem; + + vm_mutex_lock(&g_object_list_mutex); + + elem = (object_node_t *)bh_list_first_elem(&g_object_list); + while (elem) { + if (obj == elem->obj) { + post_widget_msg_to_module(elem, event); + vm_mutex_unlock(&g_object_list_mutex); + return; + } + elem = (object_node_t *) bh_list_elem_next(elem); + } + + vm_mutex_unlock(&g_object_list_mutex); +} + +static void* lv_task_handler_thread_routine (void *arg) +{ + korp_sem sem; + + vm_sem_init(&sem, 0); + + while (true) { + vm_sem_reltimedwait(&sem, 100); + lv_task_handler(); + } + + return NULL; +} + +void wgl_init(void) +{ + korp_thread tid; + + lv_init(); + + bh_list_init(&g_object_list); + vm_recursive_mutex_init(&g_object_list_mutex); + init_object_event_callback_framework(); + + /* new a thread, call lv_task_handler periodically */ + vm_thread_create(&tid, + lv_task_handler_thread_routine, + NULL, + BH_APPLET_PRESERVED_STACK_SIZE); +} + +/* ------------------------------------------------------------------------- + * Obj native function wrappers + * -------------------------------------------------------------------------*/ +static lv_res_t _obj_del(lv_obj_t *obj) +{ + /* Recursively delete object node in the list belong to this + * parent object including itself */ + _obj_del_recursive(obj); + + return lv_obj_del(obj); +} + +static void _obj_clean(lv_obj_t *obj) +{ + /* Recursively delete child object node in the list belong to this + * parent object */ + _obj_clean_recursive(obj); + + /* Delete all of its children */ + lv_obj_clean(obj); +} + +static void _obj_set_event_cb(lv_obj_t *obj) +{ + lv_obj_set_event_cb(obj, internal_lv_obj_event_cb); +} +/* ------------------------------------------------------------------------- */ + + +static WGLNativeFuncDef obj_native_func_defs[] = { + { OBJ_FUNC_ID_DEL, _obj_del, HAS_RET, 1, {0, -1}, {-1} }, + { OBJ_FUNC_ID_DEL_ASYNC, lv_obj_del_async, NO_RET, 1, {0, -1}, {-1} }, + { OBJ_FUNC_ID_CLEAN, _obj_clean, NO_RET, 1, {0, -1}, {-1} }, + { OBJ_FUNC_ID_ALIGN, lv_obj_align, NO_RET, 5, {0, 1 | NULL_OK, -1}, {-1} }, + { OBJ_FUNC_ID_SET_EVT_CB, _obj_set_event_cb, NO_RET, 1, {0, -1}, {-1} }, +}; + +/*************** Native Interface to Wasm App ***********/ +void wasm_obj_native_call(int32 func_id, uint32 argv_offset, uint32 argc) +{ + uint32 size = sizeof(obj_native_func_defs) / sizeof(WGLNativeFuncDef); + + wgl_native_func_call(obj_native_func_defs, + size, + func_id, + argv_offset, + argc); +} diff --git a/core/iwasm/lib/native/libc/libc_wrapper.c b/core/iwasm/lib/native/libc/libc_wrapper.c index fabc8b89..8972356e 100644 --- a/core/iwasm/lib/native/libc/libc_wrapper.c +++ b/core/iwasm/lib/native/libc/libc_wrapper.c @@ -52,6 +52,29 @@ wasm_runtime_set_llvm_stack(wasm_module_inst_t module, uint32 llvm_stack); #define module_free(offset) \ wasm_runtime_module_free(module_inst, offset) +static bool +validate_str_addr(wasm_module_inst_t module_inst, int32 str_offset) +{ + int32 app_end_offset; + char *str, *str_end; + + if (!wasm_runtime_get_app_addr_range(module_inst, str_offset, + NULL, &app_end_offset)) + goto fail; + + str = addr_app_to_native(str_offset); + str_end = str + (app_end_offset - str_offset); + while (str < str_end && *str != '\0') + str++; + if (str == str_end) + goto fail; + return true; + +fail: + wasm_runtime_set_exception(module_inst, "out of bounds memory access"); + return false; +} + typedef int (*out_func_t)(int c, void *ctx); enum pad_type { @@ -64,9 +87,14 @@ enum pad_type { typedef char *_va_list; #define _INTSIZEOF(n) \ ((sizeof(n) + 3) & ~3) -#define _va_arg(ap,t) \ +#define _va_arg(ap, t) \ (*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t))) +#define CHECK_VA_ARG(ap, t) do { \ + if ((uint8*)ap + _INTSIZEOF(t) > native_end_addr) \ + goto fail; \ +} while (0) + /** * @brief Output an unsigned int in hex format * @@ -172,14 +200,19 @@ print_err(out_func_t out, void *ctx) out('R', ctx); } -static void -_vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, - wasm_module_inst_t module_inst) +static bool +_vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap, + wasm_module_inst_t module_inst) { int might_format = 0; /* 1 if encountered a '%' */ enum pad_type padding = PAD_NONE; int min_width = -1; int long_ctr = 0; + uint8 *native_end_addr; + + if (!wasm_runtime_get_native_addr_range(module_inst, (uint8*)ap, + NULL, &native_end_addr)) + goto fail; /* fmt has already been adjusted if needed */ @@ -232,10 +265,13 @@ _vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, int32 d; if (long_ctr < 2) { + CHECK_VA_ARG(ap, int32); d = _va_arg(ap, int32); } else { - int64 lld = _va_arg(ap, int64); + int64 lld; + CHECK_VA_ARG(ap, int64); + lld = _va_arg(ap, int64); if (lld > INT32_MAX || lld < INT32_MIN) { print_err(out, ctx); break; @@ -255,10 +291,13 @@ _vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, uint32 u; if (long_ctr < 2) { + CHECK_VA_ARG(ap, uint32); u = _va_arg(ap, uint32); } else { - uint64 llu = _va_arg(ap, uint64); + uint64 llu; + CHECK_VA_ARG(ap, uint64); + llu = _va_arg(ap, uint64); if (llu > INT32_MAX) { print_err(out, ctx); break; @@ -281,8 +320,10 @@ _vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, bool is_ptr = (*fmt == 'p') ? true : false; if (long_ctr < 2) { + CHECK_VA_ARG(ap, uint32); x = _va_arg(ap, uint32); } else { + CHECK_VA_ARG(ap, uint64); x = _va_arg(ap, uint64); } _printf_hex_uint(out, ctx, x, !is_ptr, padding, min_width); @@ -292,11 +333,13 @@ _vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, case 's': { char *s; char *start; - int32 s_offset = _va_arg(ap, uint32); + int32 s_offset; - if (!validate_app_addr(s_offset, 1)) { - wasm_runtime_set_exception(module_inst, "out of bounds memory access"); - return; + CHECK_VA_ARG(ap, uint32); + s_offset = _va_arg(ap, uint32); + + if (!validate_str_addr(module_inst, s_offset)) { + return false; } s = start = addr_app_to_native(s_offset); @@ -314,7 +357,9 @@ _vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, } case 'c': { - int c = _va_arg(ap, int); + int c; + CHECK_VA_ARG(ap, int); + c = _va_arg(ap, int); out(c, ctx); break; } @@ -336,6 +381,11 @@ _vprintf(out_func_t out, void *ctx, const char *fmt, _va_list ap, still_might_format: ++fmt; } + return true; + +fail: + wasm_runtime_set_exception(module_inst, "out of bounds memory access"); + return false; } struct str_context { @@ -364,7 +414,7 @@ sprintf_out(int c, struct str_context *ctx) static int printf_out(int c, struct str_context *ctx) { - printf("%c", c); + bh_printf("%c", c); ctx->count++; return c; } @@ -391,7 +441,7 @@ parse_printf_args(wasm_module_inst_t module_inst, int32 fmt_offset, _va_list v; } u; - if (!validate_app_addr(fmt_offset, 1) + if (!validate_str_addr(module_inst, fmt_offset) || !validate_app_addr(va_list_offset, sizeof(int32))) return false; @@ -414,7 +464,8 @@ _printf_wrapper(int32 fmt_offset, int32 va_list_offset) if (!parse_printf_args(module_inst, fmt_offset, va_list_offset, &fmt, &va_args)) return 0; - _vprintf((out_func_t) printf_out, &ctx, fmt, va_args, module_inst); + if (!_vprintf_wa((out_func_t)printf_out, &ctx, fmt, va_args, module_inst)) + return 0; return ctx.count; } @@ -422,13 +473,17 @@ static int _sprintf_wrapper(int32 str_offset, int32 fmt_offset, int32 va_list_offset) { wasm_module_inst_t module_inst = get_module_inst(); + int32 app_end_offset; struct str_context ctx; char *str; const char *fmt; _va_list va_args; - if (!validate_app_addr(str_offset, 1)) - return 0; + if (!wasm_runtime_get_app_addr_range(module_inst, str_offset, + NULL, &app_end_offset)) { + wasm_runtime_set_exception(module_inst, "out of bounds memory access"); + return false; + } str = addr_app_to_native(str_offset); @@ -436,10 +491,11 @@ _sprintf_wrapper(int32 str_offset, int32 fmt_offset, int32 va_list_offset) return 0; ctx.str = str; - ctx.max = INT_MAX; + ctx.max = app_end_offset - str_offset; ctx.count = 0; - _vprintf((out_func_t) sprintf_out, &ctx, fmt, va_args, module_inst); + if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, fmt, va_args, module_inst)) + return 0; if (ctx.count < ctx.max) { str[ctx.count] = '\0'; @@ -470,7 +526,8 @@ _snprintf_wrapper(int32 str_offset, int32 size, int32 fmt_offset, ctx.max = size; ctx.count = 0; - _vprintf((out_func_t) sprintf_out, &ctx, fmt, va_args, module_inst); + if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, fmt, va_args, module_inst)) + return 0; if (ctx.count < ctx.max) { str[ctx.count] = '\0'; @@ -485,17 +542,17 @@ _puts_wrapper(int32 str_offset) wasm_module_inst_t module_inst = get_module_inst(); const char *str; - if (!validate_app_addr(str_offset, 1)) + if (!validate_str_addr(module_inst, str_offset)) return 0; str = addr_app_to_native(str_offset); - return printf("%s\n", str); + return bh_printf("%s\n", str); } static int _putchar_wrapper(int c) { - printf("%c", c); + bh_printf("%c", c); return 1; } @@ -507,7 +564,7 @@ _strdup_wrapper(int32 str_offset) uint32 len; int32 str_ret_offset = 0; - if (!validate_app_addr(str_offset, 1)) + if (!validate_str_addr(module_inst, str_offset)) return 0; str = addr_app_to_native(str_offset); @@ -596,7 +653,7 @@ _strchr_wrapper(int32 s_offset, int32 c) const char *s; char *ret; - if (!validate_app_addr(s_offset, 1)) + if (!validate_str_addr(module_inst, s_offset)) return s_offset; s = addr_app_to_native(s_offset); @@ -610,8 +667,8 @@ _strcmp_wrapper(int32 s1_offset, int32 s2_offset) wasm_module_inst_t module_inst = get_module_inst(); void *s1, *s2; - if (!validate_app_addr(s1_offset, 1) - || !validate_app_addr(s2_offset, 1)) + if (!validate_str_addr(module_inst, s1_offset) + || !validate_str_addr(module_inst, s2_offset)) return 0; s1 = addr_app_to_native(s1_offset); @@ -639,14 +696,19 @@ _strcpy_wrapper(int32 dst_offset, int32 src_offset) { wasm_module_inst_t module_inst = get_module_inst(); char *dst, *src; + uint32 len; - if (!validate_app_addr(dst_offset, 1) - || !validate_app_addr(src_offset, 1)) + if (!validate_str_addr(module_inst, src_offset)) + return 0; + + src = addr_app_to_native(src_offset); + len = strlen(src); + + if (!validate_app_addr(dst_offset, len + 1)) return 0; dst = addr_app_to_native(dst_offset); - src = addr_app_to_native(src_offset); - strcpy(dst, src); + strncpy(dst, src, len + 1); return dst_offset; } @@ -672,7 +734,7 @@ _strlen_wrapper(int32 s_offset) wasm_module_inst_t module_inst = get_module_inst(); char *s; - if (!validate_app_addr(s_offset, 1)) + if (!validate_str_addr(module_inst, s_offset)) return 0; s = addr_app_to_native(s_offset); @@ -789,7 +851,7 @@ static void _llvm_stackrestore_wrapper(uint32 llvm_stack) { wasm_module_inst_t module_inst = get_module_inst(); - printf("_llvm_stackrestore called!\n"); + bh_printf("_llvm_stackrestore called!\n"); wasm_runtime_set_llvm_stack(module_inst, llvm_stack); } @@ -797,7 +859,7 @@ static uint32 _llvm_stacksave_wrapper() { wasm_module_inst_t module_inst = get_module_inst(); - printf("_llvm_stacksave called!\n"); + bh_printf("_llvm_stacksave called!\n"); return wasm_runtime_get_llvm_stack(module_inst); } @@ -846,6 +908,22 @@ nullFunc_X_wrapper(int32 code) wasm_runtime_set_exception(module_inst, buf); } +/*#define ENABLE_SPEC_TEST 1*/ + +#ifdef ENABLE_SPEC_TEST +static void +print_i32_wrapper(int i32) +{ + bh_printf("%d\n", i32); +} + +static void +print_wrapper(int i32) +{ + bh_printf("%d\n", i32); +} +#endif + /* TODO: add function parameter/result types check */ #define REG_NATIVE_FUNC(module_name, func_name) \ { #module_name, #func_name, func_name##_wrapper } @@ -857,6 +935,10 @@ typedef struct WASMNativeFuncDef { } WASMNativeFuncDef; static WASMNativeFuncDef native_func_defs[] = { +#ifdef ENABLE_SPEC_TEST + REG_NATIVE_FUNC(spectest, print_i32), + REG_NATIVE_FUNC(spectest, print), +#endif REG_NATIVE_FUNC(env, _printf), REG_NATIVE_FUNC(env, _sprintf), REG_NATIVE_FUNC(env, _snprintf), @@ -927,6 +1009,9 @@ typedef struct WASMNativeGlobalDef { } WASMNativeGlobalDef; static WASMNativeGlobalDef native_global_defs[] = { +#ifdef ENABLE_SPEC_TEST + { "spectest", "global_i32", .global_data.u32 = 0 }, +#endif { "env", "STACKTOP", .global_data.u32 = 0 }, { "env", "STACK_MAX", .global_data.u32 = 0 }, { "env", "ABORT", .global_data.u32 = 0 }, @@ -961,23 +1046,6 @@ wasm_native_global_lookup(const char *module_name, const char *global_name, global_def++; } - /* Lookup non-constant globals which cannot be defined by table */ - if (!strcmp(module_name, "env")) { - if (!strcmp(global_name, "_stdin")) { - global->global_data_linked.addr = (uintptr_t)stdin; - global->is_addr = true; - return true; - } else if (!strcmp(global_name, "_stdout")) { - global->global_data_linked.addr = (uintptr_t)stdout; - global->is_addr = true; - return true; - } else if (!strcmp(global_name, "_stderr")) { - global->global_data_linked.addr = (uintptr_t)stderr; - global->is_addr = true; - return true; - } - } - return false; } diff --git a/core/iwasm/products/alios-things/iwasm.mk b/core/iwasm/products/alios-things/iwasm.mk index 030502ef..803578c1 100644 --- a/core/iwasm/products/alios-things/iwasm.mk +++ b/core/iwasm/products/alios-things/iwasm.mk @@ -28,9 +28,7 @@ GLOBAL_INCLUDES += ${IWASM_ROOT}/runtime/include \ $(NAME)_SOURCES := ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c \ ${IWASM_ROOT}/runtime/utils/wasm_log.c \ ${IWASM_ROOT}/runtime/utils/wasm_dlfcn.c \ - ${IWASM_ROOT}/runtime/platform/alios/wasm_math.c \ - ${IWASM_ROOT}/runtime/platform/alios/wasm_platform.c \ - ${IWASM_ROOT}/runtime/platform/alios/wasm-native.c \ + ${IWASM_ROOT}/runtime/platform/alios/wasm_native.c \ ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_application.c \ ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_interp.c \ ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_loader.c \ @@ -41,6 +39,7 @@ $(NAME)_SOURCES := ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c \ ${SHARED_LIB_ROOT}/platform/alios/bh_platform.c \ ${SHARED_LIB_ROOT}/platform/alios/bh_assert.c \ ${SHARED_LIB_ROOT}/platform/alios/bh_thread.c \ + ${SHARED_LIB_ROOT}/platform/alios/bh_math.c \ ${SHARED_LIB_ROOT}/mem-alloc/bh_memory.c \ ${SHARED_LIB_ROOT}/mem-alloc/mem_alloc.c \ ${SHARED_LIB_ROOT}/mem-alloc/ems/ems_kfc.c \ diff --git a/core/iwasm/products/alios-things/src/main.c b/core/iwasm/products/alios-things/src/main.c index f9b19c47..33624785 100644 --- a/core/iwasm/products/alios-things/src/main.c +++ b/core/iwasm/products/alios-things/src/main.c @@ -16,9 +16,9 @@ #include #include +#include "bh_platform.h" #include "wasm_assert.h" #include "wasm_log.h" -#include "wasm_platform.h" #include "wasm_platform_log.h" #include "wasm_thread.h" #include "wasm_export.h" @@ -29,6 +29,20 @@ 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) { diff --git a/core/iwasm/products/darwin/CMakeLists.txt b/core/iwasm/products/darwin/CMakeLists.txt new file mode 100644 index 00000000..a88b155a --- /dev/null +++ b/core/iwasm/products/darwin/CMakeLists.txt @@ -0,0 +1,107 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required (VERSION 2.8) + +project (iwasm) + +set (PLATFORM "darwin") + +# Reset default linker flags +set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") + +# Enable repl mode if want to test spec cases +# add_definitions(-DWASM_ENABLE_REPL) + +if (NOT ("$ENV{VALGRIND}" STREQUAL "YES")) + add_definitions(-DNVALGRIND) +endif () + +# Currently build as 64-bit by default. +set (BUILD_AS_64BIT_SUPPORT "YES") + +if (CMAKE_SIZEOF_VOID_P EQUAL 8) +if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES") + # Add -fPIC flag if build as 64-bit + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC") +else () + add_definitions (-m32) + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") + set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32") +endif () +endif () + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif (NOT CMAKE_BUILD_TYPE) +message ("CMAKE_BUILD_TYPE = " ${CMAKE_BUILD_TYPE}) + +set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -Wno-pedantic") + +set (CMAKE_MACOSX_RPATH True) + +set (SHARED_LIB_DIR ../../../shared-lib) + +include_directories (. + ../../runtime/include + ../../runtime/platform/include + ${SHARED_LIB_DIR}/include) + +enable_language (ASM) + +include (../../runtime/platform/${PLATFORM}/platform.cmake) +include (../../runtime/utils/utils.cmake) +include (../../runtime/vmcore-wasm/vmcore.cmake) +include (../../lib/native/base/wasm_lib_base.cmake) +include (../../lib/native/libc/wasm_libc.cmake) +include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake) +include (${SHARED_LIB_DIR}/mem-alloc/mem_alloc.cmake) +include (${SHARED_LIB_DIR}/utils/shared_utils.cmake) + +add_library (vmlib + ${WASM_PLATFORM_LIB_SOURCE} + ${WASM_UTILS_LIB_SOURCE} + ${VMCORE_LIB_SOURCE} + ${WASM_LIB_BASE_DIR}/base_lib_export.c + ${WASM_LIBC_SOURCE} + ${PLATFORM_SHARED_SOURCE} + ${MEM_ALLOC_SHARED_SOURCE} + ${UTILS_SHARED_SOURCE}) + +add_executable (iwasm main.c ext_lib_export.c) + +install (TARGETS iwasm DESTINATION bin) + +target_link_libraries (iwasm vmlib -lm -ldl -lpthread) + +add_library (libiwasm SHARED + ${WASM_PLATFORM_LIB_SOURCE} + ${WASM_UTILS_LIB_SOURCE} + ${VMCORE_LIB_SOURCE} + ${WASM_LIB_BASE_DIR}/base_lib_export.c + ${WASM_LIBC_SOURCE} + ${PLATFORM_SHARED_SOURCE} + ${MEM_ALLOC_SHARED_SOURCE} + ${UTILS_SHARED_SOURCE} + ext_lib_export.c) + +install (TARGETS libiwasm DESTINATION lib) + +set_target_properties (libiwasm PROPERTIES OUTPUT_NAME iwasm) + +target_link_libraries (libiwasm -lm -ldl -lpthread) + diff --git a/core/iwasm/products/darwin/ext_lib_export.c b/core/iwasm/products/darwin/ext_lib_export.c new file mode 100644 index 00000000..8d78f3ae --- /dev/null +++ b/core/iwasm/products/darwin/ext_lib_export.c @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lib_export.h" + +static NativeSymbol extended_native_symbol_defs[] = { }; + +#include "ext_lib_export.h" diff --git a/core/iwasm/products/darwin/main.c b/core/iwasm/products/darwin/main.c new file mode 100644 index 00000000..65f464c0 --- /dev/null +++ b/core/iwasm/products/darwin/main.c @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include +#include "bh_platform.h" +#include "wasm_application.h" +#include "wasm_assert.h" +#include "wasm_log.h" +#include "wasm_platform_log.h" +#include "wasm_thread.h" +#include "wasm_export.h" +#include "wasm_memory.h" +#include "bh_memory.h" + +static int app_argc; +static char **app_argv; + +static int print_help() +{ + wasm_printf("Usage: iwasm [-options] wasm_file [args...]\n"); + wasm_printf("options:\n"); + wasm_printf(" -f|--function name Specify function name to run in module\n" + " rather than main\n"); +#if WASM_ENABLE_LOG != 0 + wasm_printf(" -v=X Set log verbose level (0 to 2, default is 1),\n" + " larger level with more log\n"); +#endif + wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n" + " that runs commands in the form of `FUNC ARG...`\n"); + return 1; +} + +static void* +app_instance_main(wasm_module_inst_t module_inst) +{ + const char *exception; + + wasm_application_execute_main(module_inst, app_argc, app_argv); + if ((exception = wasm_runtime_get_exception(module_inst))) + wasm_printf("%s\n", exception); + return NULL; +} + +static void* +app_instance_func(wasm_module_inst_t module_inst, const char *func_name) +{ + const char *exception; + + wasm_application_execute_func(module_inst, func_name, app_argc - 1, + app_argv + 1); + if ((exception = wasm_runtime_get_exception(module_inst))) + wasm_printf("%s\n", exception); + return NULL; +} + +/** + * Split a space separated strings into an array of strings + * Returns NULL on failure + * Memory must be freed by caller + * Based on: http://stackoverflow.com/a/11198630/471795 + */ +static char ** +split_string(char *str, int *count) +{ + char **res = NULL; + char *p; + int idx = 0; + + /* split string and append tokens to 'res' */ + do { + p = strtok(str, " "); + str = NULL; + res = (char**) realloc(res, sizeof(char*) * (idx + 1)); + if (res == NULL) { + return NULL; + } + res[idx++] = p; + } while (p); + + if (count) { + *count = idx - 1; + } + return res; +} + +static void* +app_instance_repl(wasm_module_inst_t module_inst) +{ + char *cmd = NULL; + size_t len = 0; + ssize_t n; + + while ((wasm_printf("webassembly> "), n = getline(&cmd, &len, stdin)) != -1) { + wasm_assert(n > 0); + if (cmd[n - 1] == '\n') { + if (n == 1) + continue; + else + cmd[n - 1] = '\0'; + } + app_argv = split_string(cmd, &app_argc); + if (app_argv == NULL) { + LOG_ERROR("Wasm prepare param failed: split string failed.\n"); + break; + } + if (app_argc != 0) { + wasm_application_execute_func(module_inst, app_argv[0], + app_argc - 1, app_argv + 1); + } + free(app_argv); + } + free(cmd); + return NULL; +} + +#define USE_GLOBAL_HEAP_BUF 0 + +#if USE_GLOBAL_HEAP_BUF != 0 +static char global_heap_buf[10 * 1024 * 1024] = { 0 }; +#endif + +int main(int argc, char *argv[]) +{ + char *wasm_file = NULL; + const char *func_name = NULL; + uint8 *wasm_file_buf = NULL; + int wasm_file_size; + wasm_module_t wasm_module = NULL; + wasm_module_inst_t wasm_module_inst = NULL; + char error_buf[128]; +#if WASM_ENABLE_LOG != 0 + int log_verbose_level = 1; +#endif + bool is_repl_mode = false; + + /* Process options. */ + for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) { + if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) { + argc--, argv++; + if (argc < 2) { + print_help(); + return 0; + } + func_name = argv[0]; + } +#if WASM_ENABLE_LOG != 0 + else if (!strncmp(argv[0], "-v=", 3)) { + log_verbose_level = atoi(argv[0] + 3); + if (log_verbose_level < 0 || log_verbose_level > 2) + return print_help(); + } +#endif + else if (!strcmp(argv[0], "--repl")) + is_repl_mode = true; + else + return print_help(); + } + + if (argc == 0) + return print_help(); + + wasm_file = argv[0]; + app_argc = argc; + app_argv = argv; + +#if USE_GLOBAL_HEAP_BUF != 0 + if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf)) + != 0) { + wasm_printf("Init memory with global heap buffer failed.\n"); + return -1; + } +#else + if (bh_memory_init_with_allocator(malloc, free)) { + wasm_printf("Init memory with memory allocator failed.\n"); + return -1; + } +#endif + + /* initialize runtime environment */ + if (!wasm_runtime_init()) + goto fail1; + + wasm_log_set_verbose_level(log_verbose_level); + + /* load WASM byte buffer from WASM bin file */ + if (!(wasm_file_buf = (uint8*) bh_read_file_to_buffer(wasm_file, + &wasm_file_size))) + goto fail2; + + /* load WASM module */ + if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, + error_buf, sizeof(error_buf)))) { + wasm_printf("%s\n", error_buf); + goto fail3; + } + + /* instantiate the module */ + if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, + 64 * 1024, /* stack size */ + 64 * 1024, /* heap size */ + error_buf, + sizeof(error_buf)))) { + wasm_printf("%s\n", error_buf); + goto fail4; + } + + if (is_repl_mode) + app_instance_repl(wasm_module_inst); + else if (func_name) + app_instance_func(wasm_module_inst, func_name); + else + app_instance_main(wasm_module_inst); + + /* destroy the module instance */ + wasm_runtime_deinstantiate(wasm_module_inst); + +fail4: + /* unload the module */ + wasm_runtime_unload(wasm_module); + +fail3: + /* free the file buffer */ + wasm_free(wasm_file_buf); + +fail2: + /* destroy runtime environment */ + wasm_runtime_destroy(); + +fail1: + bh_memory_destroy(); + return 0; +} + diff --git a/core/iwasm/products/linux-sgx/CMakeLists.txt b/core/iwasm/products/linux-sgx/CMakeLists.txt new file mode 100644 index 00000000..4d590a8e --- /dev/null +++ b/core/iwasm/products/linux-sgx/CMakeLists.txt @@ -0,0 +1,90 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required (VERSION 2.8) + +project (iwasm) + +set (PLATFORM "linux-sgx") + +# Reset default linker flags +set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") + +add_definitions(-DUSE_SGX=1) +add_definitions(-DOPS_INPUT_OUTPUT=1) +add_definitions(-DOPS_UNSAFE_BUFFERS=0) +add_definitions(-DWASM_ENABLE_LOG=0) +add_definitions(-Dbh_printf=bh_printf_sgx) + +# Enable repl mode if want to test spec cases +# add_definitions(-DWASM_ENABLE_REPL) + +if (NOT ("$ENV{VALGRIND}" STREQUAL "YES")) + add_definitions(-DNVALGRIND) +endif () + +# Currently build as 64-bit by default. +set (BUILD_AS_64BIT_SUPPORT "YES") + +if (CMAKE_SIZEOF_VOID_P EQUAL 8) +if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES") + # Add -fPIC flag if build as 64-bit + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC") +else () + add_definitions (-m32) + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") + set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32") +endif () +endif () + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif (NOT CMAKE_BUILD_TYPE) +message ("CMAKE_BUILD_TYPE = " ${CMAKE_BUILD_TYPE}) + +set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -Wno-pedantic") + +set (SHARED_LIB_DIR ../../../shared-lib) + +include_directories (. + ../../runtime/include + ../../runtime/platform/include + ${SHARED_LIB_DIR}/include + $ENV{SGX_SDK}/include) + +enable_language (ASM) + +include (../../runtime/platform/${PLATFORM}/platform.cmake) +include (../../runtime/utils/utils.cmake) +include (../../runtime/vmcore-wasm/vmcore.cmake) +include (../../lib/native/base/wasm_lib_base.cmake) +include (../../lib/native/libc/wasm_libc.cmake) +include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake) +include (${SHARED_LIB_DIR}/mem-alloc/mem_alloc.cmake) +include (${SHARED_LIB_DIR}/utils/shared_utils.cmake) + +add_library (vmlib + ${WASM_PLATFORM_LIB_SOURCE} + ${WASM_UTILS_LIB_SOURCE} + ${VMCORE_LIB_SOURCE} + ${WASM_LIB_BASE_DIR}/base_lib_export.c + ${WASM_LIBC_SOURCE} + ${PLATFORM_SHARED_SOURCE} + ${MEM_ALLOC_SHARED_SOURCE} + ${UTILS_SHARED_SOURCE}) + +add_library (extlib ext_lib_export.c) diff --git a/core/iwasm/products/linux-sgx/ext_lib_export.c b/core/iwasm/products/linux-sgx/ext_lib_export.c new file mode 100644 index 00000000..8d78f3ae --- /dev/null +++ b/core/iwasm/products/linux-sgx/ext_lib_export.c @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lib_export.h" + +static NativeSymbol extended_native_symbol_defs[] = { }; + +#include "ext_lib_export.h" diff --git a/core/iwasm/products/linux/CMakeLists.txt b/core/iwasm/products/linux/CMakeLists.txt index a2510790..6e893670 100644 --- a/core/iwasm/products/linux/CMakeLists.txt +++ b/core/iwasm/products/linux/CMakeLists.txt @@ -68,6 +68,7 @@ include (../../lib/native/base/wasm_lib_base.cmake) include (../../lib/native/libc/wasm_libc.cmake) include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake) include (${SHARED_LIB_DIR}/mem-alloc/mem_alloc.cmake) +include (${SHARED_LIB_DIR}/utils/shared_utils.cmake) add_library (vmlib ${WASM_PLATFORM_LIB_SOURCE} @@ -76,7 +77,8 @@ add_library (vmlib ${WASM_LIB_BASE_DIR}/base_lib_export.c ${WASM_LIBC_SOURCE} ${PLATFORM_SHARED_SOURCE} - ${MEM_ALLOC_SHARED_SOURCE}) + ${MEM_ALLOC_SHARED_SOURCE} + ${UTILS_SHARED_SOURCE}) add_executable (iwasm main.c ext_lib_export.c) @@ -91,7 +93,8 @@ add_library (libiwasm SHARED ${WASM_LIB_BASE_DIR}/base_lib_export.c ${WASM_LIBC_SOURCE} ${PLATFORM_SHARED_SOURCE} - ${MEM_ALLOC_SHARED_SOURCE}) + ${MEM_ALLOC_SHARED_SOURCE} + ${UTILS_SHARED_SOURCE}) install (TARGETS libiwasm DESTINATION lib) diff --git a/core/iwasm/products/linux/main.c b/core/iwasm/products/linux/main.c index 22fe692c..86c6e5e7 100644 --- a/core/iwasm/products/linux/main.c +++ b/core/iwasm/products/linux/main.c @@ -19,9 +19,9 @@ #endif #include #include +#include "bh_platform.h" #include "wasm_assert.h" #include "wasm_log.h" -#include "wasm_platform.h" #include "wasm_platform_log.h" #include "wasm_thread.h" #include "wasm_export.h" @@ -46,6 +46,35 @@ static int print_help() return 1; } +/** + * 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[]); + +/** + * Find the specified function in argv[0] from WASM module of current instance + * and execute that function. + * + * @param module_inst the WASM module instance + * @param name the name of the function to execute + * @param argc the number of arguments + * @param argv the arguments array + * + * @return true if the specified function is called, false otherwise. + */ +bool +wasm_application_execute_func(wasm_module_inst_t module_inst, + const char *name, int argc, char *argv[]); + static void* app_instance_main(wasm_module_inst_t module_inst) { @@ -129,7 +158,11 @@ app_instance_repl(wasm_module_inst_t module_inst) return NULL; } -static char global_heap_buf[512 * 1024] = { 0 }; +#define USE_GLOBAL_HEAP_BUF 0 + +#if USE_GLOBAL_HEAP_BUF != 0 +static char global_heap_buf[10 * 1024 * 1024] = { 0 }; +#endif int main(int argc, char *argv[]) { @@ -175,11 +208,18 @@ int main(int argc, char *argv[]) app_argc = argc; app_argv = argv; +#if USE_GLOBAL_HEAP_BUF != 0 if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf)) != 0) { - wasm_printf("Init global heap failed.\n"); + wasm_printf("Init memory with global heap buffer failed.\n"); return -1; } +#else + if (bh_memory_init_with_allocator(malloc, free)) { + wasm_printf("Init memory with memory allocator failed.\n"); + return -1; + } +#endif /* initialize runtime environment */ if (!wasm_runtime_init()) @@ -188,8 +228,8 @@ int main(int argc, char *argv[]) wasm_log_set_verbose_level(log_verbose_level); /* load WASM byte buffer from WASM bin file */ - if (!(wasm_file_buf = (uint8*) wasm_read_file_to_buffer(wasm_file, - &wasm_file_size))) + if (!(wasm_file_buf = (uint8*) bh_read_file_to_buffer(wasm_file, + &wasm_file_size))) goto fail2; /* load WASM module */ @@ -201,8 +241,8 @@ int main(int argc, char *argv[]) /* instantiate the module */ if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, - 16 * 1024, /* stack size */ - 8 * 1024, /* heap size */ + 64 * 1024, /* stack size */ + 64 * 1024, /* heap size */ error_buf, sizeof(error_buf)))) { wasm_printf("%s\n", error_buf); diff --git a/core/iwasm/products/vxworks/CMakeLists.txt b/core/iwasm/products/vxworks/CMakeLists.txt new file mode 100644 index 00000000..d8019e98 --- /dev/null +++ b/core/iwasm/products/vxworks/CMakeLists.txt @@ -0,0 +1,107 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required (VERSION 2.8) + +project (iwasm) + +set (PLATFORM "vxworks") + +# Specify the compiler driver provided in the VSB +SET(CMAKE_C_COMPILER vx-cc) +SET(CMAKE_AR vx-ar) +SET(CMAKE_RANLIB vx-ranlib) + +# Reset default linker flags +set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") + +# Enable repl mode if want to test spec cases +# add_definitions(-DWASM_ENABLE_REPL) + +if (NOT ("$ENV{VALGRIND}" STREQUAL "YES")) + add_definitions(-DNVALGRIND) +endif () + +# Currently build as 64-bit by default. +set (BUILD_AS_64BIT_SUPPORT "YES") + +if (CMAKE_SIZEOF_VOID_P EQUAL 8) +if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES") + # Add -fPIC flag if build as 64-bit + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC") +else () + add_definitions (-m32) + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") + set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32") +endif () +endif () + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif (NOT CMAKE_BUILD_TYPE) +message ("CMAKE_BUILD_TYPE = " ${CMAKE_BUILD_TYPE}) + +set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -Wno-pedantic") + +set (SHARED_LIB_DIR ../../../shared-lib) + +include_directories (. + ../../runtime/include + ../../runtime/platform/include + ${SHARED_LIB_DIR}/include) + +include (../../runtime/platform/${PLATFORM}/platform.cmake) +include (../../runtime/utils/utils.cmake) +include (../../runtime/vmcore-wasm/vmcore.cmake) +include (../../lib/native/base/wasm_lib_base.cmake) +include (../../lib/native/libc/wasm_libc.cmake) +include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake) +include (${SHARED_LIB_DIR}/mem-alloc/mem_alloc.cmake) +include (${SHARED_LIB_DIR}/utils/shared_utils.cmake) + +add_library (vmlib + ${WASM_PLATFORM_LIB_SOURCE} + ${WASM_UTILS_LIB_SOURCE} + ${VMCORE_LIB_SOURCE} + ${WASM_LIB_BASE_DIR}/base_lib_export.c + ${WASM_LIBC_SOURCE} + ${PLATFORM_SHARED_SOURCE} + ${MEM_ALLOC_SHARED_SOURCE} + ${UTILS_SHARED_SOURCE}) + +add_executable (iwasm main.c ext_lib_export.c) + +install (TARGETS iwasm DESTINATION bin) + +target_link_libraries (iwasm vmlib -lm -ldl -lunix) + +add_library (libiwasm SHARED + ${WASM_PLATFORM_LIB_SOURCE} + ${WASM_UTILS_LIB_SOURCE} + ${VMCORE_LIB_SOURCE} + ${WASM_LIB_BASE_DIR}/base_lib_export.c + ${WASM_LIBC_SOURCE} + ${PLATFORM_SHARED_SOURCE} + ${MEM_ALLOC_SHARED_SOURCE} + ${UTILS_SHARED_SOURCE}) + +install (TARGETS libiwasm DESTINATION lib) + +set_target_properties (libiwasm PROPERTIES OUTPUT_NAME iwasm) + +target_link_libraries (libiwasm -lm -ldl -lunix) + diff --git a/core/iwasm/products/vxworks/ext_lib_export.c b/core/iwasm/products/vxworks/ext_lib_export.c new file mode 100644 index 00000000..8d78f3ae --- /dev/null +++ b/core/iwasm/products/vxworks/ext_lib_export.c @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lib_export.h" + +static NativeSymbol extended_native_symbol_defs[] = { }; + +#include "ext_lib_export.h" diff --git a/core/iwasm/products/vxworks/main.c b/core/iwasm/products/vxworks/main.c new file mode 100644 index 00000000..a1a503f3 --- /dev/null +++ b/core/iwasm/products/vxworks/main.c @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include "wasm_assert.h" +#include "wasm_log.h" +#include "wasm_platform.h" +#include "wasm_platform_log.h" +#include "wasm_thread.h" +#include "wasm_export.h" +#include "wasm_memory.h" +#include "bh_memory.h" + +static int app_argc; +static char **app_argv; + +static int print_help() +{ + wasm_printf("Usage: iwasm [-options] wasm_file [args...]\n"); + wasm_printf("options:\n"); + wasm_printf(" -f|--function name Specify function name to run in module\n" + " rather than main\n"); +#if WASM_ENABLE_LOG != 0 + wasm_printf(" -v=X Set log verbose level (0 to 2, default is 1),\n" + " larger level with more log\n"); +#endif + wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n" + " that runs commands in the form of `FUNC ARG...`\n"); + return 1; +} + +/** + * 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[]); + +/** + * Find the specified function in argv[0] from WASM module of current instance + * and execute that function. + * + * @param module_inst the WASM module instance + * @param name the name of the function to execute + * @param argc the number of arguments + * @param argv the arguments array + * + * @return true if the specified function is called, false otherwise. + */ +bool +wasm_application_execute_func(wasm_module_inst_t module_inst, + const char *name, int argc, char *argv[]); + +static void* +app_instance_main(wasm_module_inst_t module_inst) +{ + const char *exception; + + wasm_application_execute_main(module_inst, app_argc, app_argv); + if ((exception = wasm_runtime_get_exception(module_inst))) + wasm_printf("%s\n", exception); + return NULL; +} + +static void* +app_instance_func(wasm_module_inst_t module_inst, const char *func_name) +{ + const char *exception; + + wasm_application_execute_func(module_inst, func_name, app_argc - 1, + app_argv + 1); + if ((exception = wasm_runtime_get_exception(module_inst))) + wasm_printf("%s\n", exception); + return NULL; +} + +/** + * Split a space separated strings into an array of strings + * Returns NULL on failure + * Memory must be freed by caller + * Based on: http://stackoverflow.com/a/11198630/471795 + */ +static char ** +split_string(char *str, int *count) +{ + char **res = NULL; + char *p; + int idx = 0; + + /* split string and append tokens to 'res' */ + do { + p = strtok(str, " "); + str = NULL; + res = (char**) realloc(res, sizeof(char*) * (idx + 1)); + if (res == NULL) { + return NULL; + } + res[idx++] = p; + } while (p); + + if (count) { + *count = idx - 1; + } + return res; +} + +static void* +app_instance_repl(wasm_module_inst_t module_inst) +{ + char *cmd = NULL; + size_t len = 0; + ssize_t n; + + while ((wasm_printf("webassembly> "), n = getline(&cmd, &len, stdin)) != -1) { + wasm_assert(n > 0); + if (cmd[n - 1] == '\n') { + if (n == 1) + continue; + else + cmd[n - 1] = '\0'; + } + app_argv = split_string(cmd, &app_argc); + if (app_argv == NULL) { + LOG_ERROR("Wasm prepare param failed: split string failed.\n"); + break; + } + if (app_argc != 0) { + wasm_application_execute_func(module_inst, app_argv[0], + app_argc - 1, app_argv + 1); + } + free(app_argv); + } + free(cmd); + return NULL; +} + +static char global_heap_buf[512 * 1024] = { 0 }; + +int main(int argc, char *argv[]) +{ + char *wasm_file = NULL; + const char *func_name = NULL; + uint8 *wasm_file_buf = NULL; + int wasm_file_size; + wasm_module_t wasm_module = NULL; + wasm_module_inst_t wasm_module_inst = NULL; + char error_buf[128]; +#if WASM_ENABLE_LOG != 0 + int log_verbose_level = 1; +#endif + bool is_repl_mode = false; + + /* Process options. */ + for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) { + if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) { + argc--, argv++; + if (argc < 2) { + print_help(); + return 0; + } + func_name = argv[0]; + } +#if WASM_ENABLE_LOG != 0 + else if (!strncmp(argv[0], "-v=", 3)) { + log_verbose_level = atoi(argv[0] + 3); + if (log_verbose_level < 0 || log_verbose_level > 2) + return print_help(); + } +#endif + else if (!strcmp(argv[0], "--repl")) + is_repl_mode = true; + else + return print_help(); + } + + if (argc == 0) + return print_help(); + + wasm_file = argv[0]; + app_argc = argc; + app_argv = argv; + + if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf)) + != 0) { + wasm_printf("Init global heap failed.\n"); + return -1; + } + + /* initialize runtime environment */ + if (!wasm_runtime_init()) + goto fail1; + + wasm_log_set_verbose_level(log_verbose_level); + + /* load WASM byte buffer from WASM bin file */ + if (!(wasm_file_buf = (uint8*) bh_read_file_to_buffer(wasm_file, + &wasm_file_size))) + goto fail2; + + /* load WASM module */ + if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, + error_buf, sizeof(error_buf)))) { + wasm_printf("%s\n", error_buf); + goto fail3; + } + + /* instantiate the module */ + if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, + 16 * 1024, /* stack size */ + 8 * 1024, /* heap size */ + error_buf, + sizeof(error_buf)))) { + wasm_printf("%s\n", error_buf); + goto fail4; + } + + if (is_repl_mode) + app_instance_repl(wasm_module_inst); + else if (func_name) + app_instance_func(wasm_module_inst, func_name); + else + app_instance_main(wasm_module_inst); + + /* destroy the module instance */ + wasm_runtime_deinstantiate(wasm_module_inst); + +fail4: + /* unload the module */ + wasm_runtime_unload(wasm_module); + +fail3: + /* free the file buffer */ + wasm_free(wasm_file_buf); + +fail2: + /* destroy runtime environment */ + wasm_runtime_destroy(); + +fail1: + bh_memory_destroy(); + return 0; +} + diff --git a/core/iwasm/products/zephyr/simple/CMakeLists.txt b/core/iwasm/products/zephyr/simple/CMakeLists.txt index d9e91e4c..0363741b 100644 --- a/core/iwasm/products/zephyr/simple/CMakeLists.txt +++ b/core/iwasm/products/zephyr/simple/CMakeLists.txt @@ -35,8 +35,6 @@ include_directories (${IWASM_ROOT}/runtime/include set (IWASM_SRCS ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c ${IWASM_ROOT}/runtime/utils/wasm_log.c ${IWASM_ROOT}/runtime/utils/wasm_dlfcn.c - ${IWASM_ROOT}/runtime/platform/zephyr/wasm_math.c - ${IWASM_ROOT}/runtime/platform/zephyr/wasm_platform.c ${IWASM_ROOT}/runtime/platform/zephyr/wasm_native.c ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_application.c ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_interp.c @@ -48,6 +46,7 @@ set (IWASM_SRCS ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c ${SHARED_LIB_ROOT}/platform/zephyr/bh_platform.c ${SHARED_LIB_ROOT}/platform/zephyr/bh_assert.c ${SHARED_LIB_ROOT}/platform/zephyr/bh_thread.c + ${SHARED_LIB_ROOT}/platform/zephyr/bh_math.c ${SHARED_LIB_ROOT}/mem-alloc/bh_memory.c ${SHARED_LIB_ROOT}/mem-alloc/mem_alloc.c ${SHARED_LIB_ROOT}/mem-alloc/ems/ems_kfc.c diff --git a/core/iwasm/products/zephyr/simple/src/main.c b/core/iwasm/products/zephyr/simple/src/main.c index fb183e38..da85a3bb 100644 --- a/core/iwasm/products/zephyr/simple/src/main.c +++ b/core/iwasm/products/zephyr/simple/src/main.c @@ -16,9 +16,9 @@ #include #include +#include "bh_platform.h" #include "wasm_assert.h" #include "wasm_log.h" -#include "wasm_platform.h" #include "wasm_platform_log.h" #include "wasm_thread.h" #include "wasm_export.h" @@ -26,9 +26,28 @@ #include "bh_memory.h" #include "test_wasm.h" +#define CONFIG_GLOBAL_HEAP_BUF_SIZE 131072 +#define CONFIG_APP_STACK_SIZE 8192 +#define CONFIG_APP_HEAP_SIZE 8192 +#define CONFIG_MAIN_THREAD_STACK_SIZE 4096 + 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) { @@ -40,7 +59,7 @@ app_instance_main(wasm_module_inst_t module_inst) return NULL; } -static char global_heap_buf[512 * 1024] = { 0 }; +static char global_heap_buf[CONFIG_GLOBAL_HEAP_BUF_SIZE] = { 0 }; void iwasm_main(void *arg1, void *arg2, void *arg3) { @@ -58,7 +77,7 @@ void iwasm_main(void *arg1, void *arg2, void *arg3) (void) arg3; if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf)) - != 0) { + != 0) { wasm_printf("Init global heap failed.\n"); return; } @@ -77,14 +96,17 @@ void iwasm_main(void *arg1, void *arg2, void *arg3) /* load WASM module */ if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, - error_buf, sizeof(error_buf)))) { + error_buf, sizeof(error_buf)))) { wasm_printf("%s\n", error_buf); goto fail2; } /* instantiate the module */ - if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, 8 * 1024, - 8 * 1024, error_buf, sizeof(error_buf)))) { + if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, + CONFIG_APP_STACK_SIZE, + CONFIG_APP_HEAP_SIZE, + error_buf, + sizeof(error_buf)))) { wasm_printf("%s\n", error_buf); goto fail3; } @@ -105,24 +127,23 @@ void iwasm_main(void *arg1, void *arg2, void *arg3) fail1: bh_memory_destroy(); } -#define DEFAULT_THREAD_STACKSIZE (6 * 1024) -#define DEFAULT_THREAD_PRIORITY 5 +#define MAIN_THREAD_STACK_SIZE (CONFIG_MAIN_THREAD_STACK_SIZE) +#define MAIN_THREAD_PRIORITY 5 -K_THREAD_STACK_DEFINE(iwasm_main_thread_stack, DEFAULT_THREAD_STACKSIZE); +K_THREAD_STACK_DEFINE(iwasm_main_thread_stack, MAIN_THREAD_STACK_SIZE); static struct k_thread iwasm_main_thread; bool iwasm_init(void) { k_tid_t tid = k_thread_create(&iwasm_main_thread, iwasm_main_thread_stack, - DEFAULT_THREAD_STACKSIZE, iwasm_main, NULL, NULL, NULL, - DEFAULT_THREAD_PRIORITY, 0, K_NO_WAIT); + MAIN_THREAD_STACK_SIZE, + iwasm_main, NULL, NULL, NULL, + MAIN_THREAD_PRIORITY, 0, K_NO_WAIT); return tid ? true : false; } -#ifndef CONFIG_AEE_ENABLE void main(void) { iwasm_init(); } -#endif diff --git a/core/iwasm/runtime/include/bh_memory.h b/core/iwasm/runtime/include/bh_memory.h new file mode 100644 index 00000000..352137a3 --- /dev/null +++ b/core/iwasm/runtime/include/bh_memory.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _BH_MEMORY_H +#define _BH_MEMORY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define BH_KB (1024) +#define BH_MB ((BH_KB)*1024) +#define BH_GB ((BH_MB)*1024) + +/** + * Initialize memory allocator with a pool, the bh_malloc/bh_free function + * will malloc/free memory from the pool + * + * @param mem the pool buffer + * @param bytes the size bytes of the buffer + * + * @return 0 if success, -1 otherwise + */ +int bh_memory_init_with_pool(void *mem, unsigned int bytes); + +/** + * Initialize memory allocator with memory allocator, the bh_malloc/bh_free + * function will malloc/free memory with the allocator passed + * + * @param malloc_func the malloc function + * @param free_func the free function + * + * @return 0 if success, -1 otherwise + */ +int bh_memory_init_with_allocator(void *malloc_func, void *free_func); + +/** + * Destroy memory + */ +void bh_memory_destroy(); + +/** + * Get the pool size of memory, if memory is initialized with allocator, + * return 1GB by default. + */ +int bh_memory_pool_size(); + +#if BEIHAI_ENABLE_MEMORY_PROFILING == 0 + +/** + * This function allocates a memory chunk from system + * + * @param size bytes need allocate + * + * @return the pointer to memory allocated + */ +void* bh_malloc(unsigned int size); + +/** + * This function frees memory chunk + * + * @param ptr the pointer to memory need free + */ +void bh_free(void *ptr); + +#else + +void* bh_malloc_profile(const char *file, int line, const char *func, unsigned int size); +void bh_free_profile(const char *file, int line, const char *func, void *ptr); + +#define bh_malloc(size) bh_malloc_profile(__FILE__, __LINE__, __func__, size) +#define bh_free(ptr) bh_free_profile(__FILE__, __LINE__, __func__, ptr) + +/** + * Print current memory profiling data + * + * @param file file name of the caller + * @param line line of the file of the caller + * @param func function name of the caller + */ +void memory_profile_print(const char *file, int line, const char *func, int alloc); + +/** + * Summarize memory usage and print it out + * Can use awk to analyze the output like below: + * awk -F: '{print $2,$4,$6,$8,$9}' OFS="\t" ./out.txt | sort -n -r -k 1 + */ +void memory_usage_summarize(); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef _BH_MEMORY_H */ + diff --git a/core/iwasm/runtime/include/lib_export.h b/core/iwasm/runtime/include/lib_export.h index d6b335f2..e5eb6b7e 100644 --- a/core/iwasm/runtime/include/lib_export.h +++ b/core/iwasm/runtime/include/lib_export.h @@ -40,7 +40,13 @@ int get_base_lib_export_apis(NativeSymbol **p_base_lib_apis); /** - * Get the exported APIs of extend lib + * Get the exported APIs of extended lib, this API isn't provided by WASM VM, + * it must be provided by developer to register the extended native APIs, + * for example, developer can register his native APIs to extended_native_symbol_defs, + * array, and include file ext_lib_export.h which implements this API. + * And if developer hasn't any native API to register, he can define an empty + * extended_native_symbol_defs array, and then include file ext_lib_export.h to + * implements this API. * * @param p_base_lib_apis return the exported API array of extend lib * diff --git a/core/iwasm/runtime/include/wasm_application.h b/core/iwasm/runtime/include/wasm_application.h new file mode 100644 index 00000000..31813b2e --- /dev/null +++ b/core/iwasm/runtime/include/wasm_application.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2019 Taobao (China) Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _WASM_APPLICATION_H +#define _WASM_APPLICATION_H + +//#include "wasm_runtime.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +struct WASMModuleInstance; + +/** + * 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 and exception will be thrown, + * the caller can call wasm_runtime_get_exception to get exception info. + */ +bool +wasm_application_execute_main(struct WASMModuleInstance *module_inst, + int argc, char *argv[]); + +/** + * Find the specified function in argv[0] from a WASM module instance + * and execute that function. + * + * @param module_inst the WASM module instance + * @param name the name of the function to execute + * @param argc the number of arguments + * @param argv the arguments array + * + * @return true if the specified function is called, false otherwise and exception will be thrown, + * the caller can call wasm_runtime_get_exception to get exception info. + */ +bool +wasm_application_execute_func(struct WASMModuleInstance *module_inst, + char *name, int argc, char *argv[]); + +#ifdef __cplusplus +} +#endif + +#endif /* end of _WASM_APPLICATION_H */ + diff --git a/core/iwasm/runtime/platform/alios/wasm_platform.c b/core/iwasm/runtime/include/wasm_dlfcn.h similarity index 69% rename from core/iwasm/runtime/platform/alios/wasm_platform.c rename to core/iwasm/runtime/include/wasm_dlfcn.h index e643377c..ce45de2b 100644 --- a/core/iwasm/runtime/platform/alios/wasm_platform.c +++ b/core/iwasm/runtime/include/wasm_dlfcn.h @@ -14,27 +14,19 @@ * limitations under the License. */ -#include "wasm_platform.h" +#ifndef _WASM_DLFCN_H +#define _WASM_DLFCN_H -bool is_little_endian = false; +#ifdef __cplusplus +extern "C" { +#endif -bool __is_little_endian() -{ - union w - { - int a; - char b; - }c; +void * +wasm_dlsym(void *handle, const char *symbol); - c.a = 1; - return (c.b == 1); +#ifdef __cplusplus } +#endif -int wasm_platform_init() -{ - if (__is_little_endian()) - is_little_endian = true; - - return 0; -} +#endif /* end of _WASM_DLFCN_H */ diff --git a/core/iwasm/runtime/include/wasm_export.h b/core/iwasm/runtime/include/wasm_export.h index 0492fcb4..e6c9df5d 100644 --- a/core/iwasm/runtime/include/wasm_export.h +++ b/core/iwasm/runtime/include/wasm_export.h @@ -152,6 +152,13 @@ wasm_runtime_instantiate(const wasm_module_t module, void wasm_runtime_deinstantiate(wasm_module_inst_t module_inst); +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 +bool +wasm_runtime_set_ext_memory(wasm_module_inst_t module_inst, + uint8_t *ext_mem_data, uint32_t ext_mem_size, + char *error_buf, uint32_t error_buf_size); +#endif + /** * Load WASM module instance from AOT file. * @@ -385,34 +392,36 @@ wasm_runtime_addr_native_to_app(wasm_module_inst_t module_inst, void *native_ptr); /** - * Find the unique main function from a WASM module instance - * and execute that function. + * Get the app address range (relative address) that a app address belongs to * * @param module_inst the WASM module instance - * @param argc the number of arguments - * @param argv the arguments array + * @param app_offset the app address to retrieve + * @param p_app_start_offset buffer to output the app start offset if not NULL + * @param p_app_end_offset buffer to output the app end offset if not NULL * - * @return true if the main function is called, false otherwise. + * @return true if success, false otherwise. */ bool -wasm_application_execute_main(wasm_module_inst_t module_inst, - int argc, char *argv[]); +wasm_runtime_get_app_addr_range(wasm_module_inst_t module_inst, + int32_t app_offset, + int32_t *p_app_start_offset, + int32_t *p_app_end_offset); /** - * Find the specified function in argv[0] from WASM module of current instance - * and execute that function. + * Get the native address range (absolute address) that a native address belongs to * * @param module_inst the WASM module instance - * @param name the name of the function to execute - * @param argc the number of arguments - * @param argv the arguments array + * @param native_ptr the native address to retrieve + * @param p_native_start_addr buffer to output the native start address if not NULL + * @param p_native_end_addr buffer to output the native end address if not NULL * - * @return true if the specified function is called, false otherwise. + * @return true if success, false otherwise. */ bool -wasm_application_execute_func(wasm_module_inst_t module_inst, - const char *name, int argc, char *argv[]); - +wasm_runtime_get_native_addr_range(wasm_module_inst_t module_inst, + uint8_t *native_ptr, + uint8_t **p_native_start_addr, + uint8_t **p_native_end_addr); #ifdef __cplusplus } diff --git a/core/iwasm/runtime/include/wasm_hashmap.h b/core/iwasm/runtime/include/wasm_hashmap.h index c9f71912..2296b1c3 100644 --- a/core/iwasm/runtime/include/wasm_hashmap.h +++ b/core/iwasm/runtime/include/wasm_hashmap.h @@ -17,7 +17,7 @@ #ifndef WASM_HASHMAP_H #define WASM_HASHMAP_H -#include "wasm_platform.h" +#include "bh_platform.h" #ifdef __cplusplus diff --git a/core/iwasm/runtime/include/wasm_log.h b/core/iwasm/runtime/include/wasm_log.h index 112db2f1..cba03b04 100644 --- a/core/iwasm/runtime/include/wasm_log.h +++ b/core/iwasm/runtime/include/wasm_log.h @@ -30,7 +30,7 @@ #ifndef _WASM_LOG_H #define _WASM_LOG_H -#include "wasm_platform.h" +#include "bh_platform.h" #ifdef __cplusplus diff --git a/core/iwasm/runtime/include/wasm_vector.h b/core/iwasm/runtime/include/wasm_vector.h index 4723ff68..e11832ed 100644 --- a/core/iwasm/runtime/include/wasm_vector.h +++ b/core/iwasm/runtime/include/wasm_vector.h @@ -17,7 +17,7 @@ #ifndef _WASM_VECTOR_H #define _WASM_VECTOR_H -#include "wasm_platform.h" +#include "bh_platform.h" #ifdef __cplusplus diff --git a/core/iwasm/runtime/platform/alios/wasm-native.c b/core/iwasm/runtime/platform/alios/wasm_native.c similarity index 100% rename from core/iwasm/runtime/platform/alios/wasm-native.c rename to core/iwasm/runtime/platform/alios/wasm_native.c diff --git a/core/iwasm/runtime/platform/alios/wasm_platform.h b/core/iwasm/runtime/platform/alios/wasm_platform.h deleted file mode 100644 index 50bba6de..00000000 --- a/core/iwasm/runtime/platform/alios/wasm_platform.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2019 Intel Corporation. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _WASM_PLATFORM_H -#define _WASM_PLATFORM_H - -#include "wasm_config.h" -#include "wasm_types.h" -#include -#include - -#include -typedef uint64_t uint64; -typedef int64_t int64; -typedef float float32; -typedef double float64; - -#ifndef NULL -# define NULL ((void*) 0) -#endif - -#define WASM_PLATFORM "AliOS" -#define __ALIOS__ 1 - -#include -#include -#include -#include -#include -#include - -/** - * Return the offset of the given field in the given type. - * - * @param Type the type containing the filed - * @param field the field in the type - * - * @return the offset of field in Type - */ -#ifndef offsetof -#define offsetof(Type, field) ((size_t)(&((Type *)0)->field)) -#endif - -typedef aos_task_t korp_thread; -typedef korp_thread *korp_tid; -typedef aos_mutex_t korp_mutex; - -int wasm_platform_init(); - -extern bool is_little_endian; - -#include - -/* The following operations declared in string.h may be defined as - macros on Linux, so don't declare them as functions here. */ -/* memset */ -/* memcpy */ -/* memmove */ - -/* #include */ - -/* Unit test framework is based on C++, where the declaration of - snprintf is different. */ -#ifndef __cplusplus -int snprintf(char *buffer, size_t count, const char *format, ...); -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* math functions */ -double sqrt(double x); -double floor(double x); -double ceil(double x); -double fmin(double x, double y); -double fmax(double x, double y); -double rint(double x); -double fabs(double x); -double trunc(double x); -int signbit(double x); -int isnan(double x); - -void* -wasm_dlsym(void *handle, const char *symbol); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/core/iwasm/runtime/platform/darwin/platform.cmake b/core/iwasm/runtime/platform/darwin/platform.cmake new file mode 100644 index 00000000..ea7f7497 --- /dev/null +++ b/core/iwasm/runtime/platform/darwin/platform.cmake @@ -0,0 +1,25 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200809L) + +set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR}) + +include_directories(${PLATFORM_LIB_DIR}) +include_directories(${PLATFORM_LIB_DIR}/../include) + +file (GLOB_RECURSE source_all ${PLATFORM_LIB_DIR}/*.c) + +set (WASM_PLATFORM_LIB_SOURCE ${source_all}) + diff --git a/core/iwasm/runtime/platform/darwin/wasm_native.c b/core/iwasm/runtime/platform/darwin/wasm_native.c new file mode 100644 index 00000000..8feb8412 --- /dev/null +++ b/core/iwasm/runtime/platform/darwin/wasm_native.c @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wasm_native.h" + +void* +wasm_platform_native_func_lookup(const char *module_name, + const char *func_name) +{ + return NULL; +} + diff --git a/core/iwasm/runtime/platform/include/wasm_platform_log.h b/core/iwasm/runtime/platform/include/wasm_platform_log.h index 3fe55bf5..e74de3ff 100644 --- a/core/iwasm/runtime/platform/include/wasm_platform_log.h +++ b/core/iwasm/runtime/platform/include/wasm_platform_log.h @@ -17,7 +17,9 @@ #ifndef _WASM_PLATFORM_LOG #define _WASM_PLATFORM_LOG -#define wasm_printf printf +#include "bh_platform.h" + +#define wasm_printf bh_printf #define wasm_vprintf vprintf diff --git a/core/iwasm/runtime/platform/linux-sgx/platform.cmake b/core/iwasm/runtime/platform/linux-sgx/platform.cmake new file mode 100644 index 00000000..c01fd0e5 --- /dev/null +++ b/core/iwasm/runtime/platform/linux-sgx/platform.cmake @@ -0,0 +1,25 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199309L) + +set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR}) + +include_directories(${PLATFORM_LIB_DIR}) +include_directories(${PLATFORM_LIB_DIR}/../include) + +file (GLOB_RECURSE source_all ${PLATFORM_LIB_DIR}/*.c) + +set (WASM_PLATFORM_LIB_SOURCE ${source_all}) + diff --git a/core/iwasm/runtime/platform/linux-sgx/wasm_native.c b/core/iwasm/runtime/platform/linux-sgx/wasm_native.c new file mode 100644 index 00000000..59b081b7 --- /dev/null +++ b/core/iwasm/runtime/platform/linux-sgx/wasm_native.c @@ -0,0 +1,332 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE /* for O_DIRECT */ +#endif + +#include "wasm_native.h" +#include "wasm_runtime.h" +#include "wasm_log.h" +#include "wasm_memory.h" +#include "wasm_platform_log.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define get_module_inst() \ + wasm_runtime_get_current_module_inst() + +#define validate_app_addr(offset, size) \ + wasm_runtime_validate_app_addr(module_inst, offset, size) + +#define addr_app_to_native(offset) \ + wasm_runtime_addr_app_to_native(module_inst, offset) + +#define addr_native_to_app(ptr) \ + wasm_runtime_addr_native_to_app(module_inst, ptr) + +#define module_malloc(size) \ + wasm_runtime_module_malloc(module_inst, size) + +#define module_free(offset) \ + wasm_runtime_module_free(module_inst, offset) + + +static int32 +__syscall0_wrapper(int32 arg0) +{ + switch (arg0) { + case 199: /* getuid */ + /* TODO */ + default: + bh_printf("##_syscall0 called, syscall id: %d\n", arg0); + } + return 0; +} + +static int32 +__syscall1_wrapper(int32 arg0, int32 arg1) +{ + switch (arg0) { + case 6: /* close */ + /* TODO */ + default: + bh_printf("##_syscall1 called, syscall id: %d\n", arg0); + } + return 0; +} + +static int32 +__syscall2_wrapper(int32 arg0, int32 arg1, int32 arg2) +{ + switch (arg0) { + case 183: /* getcwd */ + /* TODO */ + default: + bh_printf("##_syscall2 called, syscall id: %d\n", arg0); + } + return 0; +} + +static int32 +__syscall3_wrapper(int32 arg0, int32 arg1, int32 arg2, int32 arg3) +{ + WASMModuleInstance *module_inst = get_module_inst(); + + switch (arg0) { + case 146: /* writev */ + { + /* Implement syscall 54 and syscall 146 to support printf() + for non SIDE_MODULE=1 mode */ + struct iovec_app { + int32 iov_base_offset; + uint32 iov_len; + } *vec; + int32 vec_offset = arg2, str_offset; + uint32 iov_count = arg3, i; + int32 count = 0; + char *iov_base, *str; + + if (!validate_app_addr(vec_offset, sizeof(struct iovec_app))) + return 0; + + vec = (struct iovec_app *)addr_app_to_native(vec_offset); + for (i = 0; i < iov_count; i++, vec++) { + if (vec->iov_len > 0) { + if (!validate_app_addr(vec->iov_base_offset, 1)) + return 0; + iov_base = (char*)addr_app_to_native(vec->iov_base_offset); + + if (!(str_offset = module_malloc(vec->iov_len + 1))) + return 0; + + str = addr_app_to_native(str_offset); + + memcpy(str, iov_base, vec->iov_len); + str[vec->iov_len] = '\0'; + count += wasm_printf("%s", str); + + module_free(str_offset); + } + } + return count; + } + case 145: /* readv */ + case 3: /* read*/ + case 5: /* open */ + case 221: /* fcntl */ + /* TODO */ + default: + bh_printf("##_syscall3 called, syscall id: %d\n", arg0); + } + return 0; +} + +static int32 +__syscall4_wrapper(int32 arg0, int32 arg1, int32 arg2, + int32 arg3, int32 arg4) +{ + bh_printf("##_syscall4 called, syscall id: %d\n", arg0); + return 0; +} + +static int32 +__syscall5_wrapper(int32 arg0, int32 arg1, int32 arg2, + int32 arg3, int32 arg4, int32 arg5) +{ + switch (arg0) { + case 140: /* llseek */ + /* TODO */ + default: + bh_printf("##_syscall5 called, args[0]: %d\n", arg0); + } + return 0; +} + +#define GET_EMCC_SYSCALL_ARGS() \ + WASMModuleInstance *module_inst = get_module_inst(); \ + int32 *args; \ + if (!validate_app_addr(args_off, 1)) \ + return 0; \ + args = addr_app_to_native(args_off) \ + +#define EMCC_SYSCALL_WRAPPER0(id) \ + static int32 ___syscall##id##_wrapper(int32 _id) { \ + return __syscall0_wrapper(id); \ + } + +#define EMCC_SYSCALL_WRAPPER1(id) \ + static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall1_wrapper(id, args[0]); \ + } + +#define EMCC_SYSCALL_WRAPPER2(id) \ + static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall2_wrapper(id, args[0], args[1]); \ + } + +#define EMCC_SYSCALL_WRAPPER3(id) \ + static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall3_wrapper(id, args[0], args[1], args[2]); \ + } + +#define EMCC_SYSCALL_WRAPPER4(id) \ + static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall4_wrapper(id, args[0], args[1], args[2], args[3]);\ + } + +#define EMCC_SYSCALL_WRAPPER5(id) \ + static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\ + GET_EMCC_SYSCALL_ARGS(); \ + return __syscall5_wrapper(id, args[0], args[1], args[2], \ + args[3], args[4]); \ + } + +EMCC_SYSCALL_WRAPPER0(199) + +EMCC_SYSCALL_WRAPPER1(6) + +EMCC_SYSCALL_WRAPPER2(183) + +EMCC_SYSCALL_WRAPPER3(3) +EMCC_SYSCALL_WRAPPER3(5) +EMCC_SYSCALL_WRAPPER3(54) +EMCC_SYSCALL_WRAPPER3(145) +EMCC_SYSCALL_WRAPPER3(146) +EMCC_SYSCALL_WRAPPER3(221) + +EMCC_SYSCALL_WRAPPER5(140) + +static int32 +getTotalMemory_wrapper() +{ + WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst(); + WASMMemoryInstance *memory = module_inst->default_memory; + return NumBytesPerPage * memory->cur_page_count; +} + +static int32 +enlargeMemory_wrapper() +{ + bool ret; + WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst(); + WASMMemoryInstance *memory = module_inst->default_memory; + uint32 DYNAMICTOP_PTR_offset = module_inst->DYNAMICTOP_PTR_offset; + uint32 addr_data_offset = *(uint32*)(memory->global_data + DYNAMICTOP_PTR_offset); + uint32 *DYNAMICTOP_PTR = (uint32*)(memory->memory_data + addr_data_offset); + uint32 memory_size_expected = *DYNAMICTOP_PTR; + uint32 total_page_count = (memory_size_expected + NumBytesPerPage - 1) / NumBytesPerPage; + + if (total_page_count < memory->cur_page_count) { + return 1; + } + else { + ret = wasm_runtime_enlarge_memory(module_inst, total_page_count - + memory->cur_page_count); + return ret ? 1 : 0; + } +} + +static void +_abort_wrapper(int32 code) +{ + WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst(); + char buf[32]; + + snprintf(buf, sizeof(buf), "env.abort(%i)", code); + wasm_runtime_set_exception(module_inst, buf); +} + +static void +abortOnCannotGrowMemory_wrapper() +{ + WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst(); + wasm_runtime_set_exception(module_inst, "abort on cannot grow memory"); +} + +static void +___setErrNo_wrapper(int32 error_no) +{ + errno = error_no; +} + +/* TODO: add function parameter/result types check */ +#define REG_NATIVE_FUNC(module_name, func_name) \ + {#module_name, #func_name, func_name##_wrapper} + +typedef struct WASMNativeFuncDef { + const char *module_name; + const char *func_name; + void *func_ptr; +} WASMNativeFuncDef; + +static WASMNativeFuncDef native_func_defs[] = { + REG_NATIVE_FUNC(env, __syscall0), + REG_NATIVE_FUNC(env, __syscall1), + REG_NATIVE_FUNC(env, __syscall2), + REG_NATIVE_FUNC(env, __syscall3), + REG_NATIVE_FUNC(env, __syscall4), + REG_NATIVE_FUNC(env, __syscall5), + REG_NATIVE_FUNC(env, ___syscall3), + REG_NATIVE_FUNC(env, ___syscall5), + REG_NATIVE_FUNC(env, ___syscall6), + REG_NATIVE_FUNC(env, ___syscall54), + REG_NATIVE_FUNC(env, ___syscall140), + REG_NATIVE_FUNC(env, ___syscall145), + REG_NATIVE_FUNC(env, ___syscall146), + REG_NATIVE_FUNC(env, ___syscall183), + REG_NATIVE_FUNC(env, ___syscall199), + REG_NATIVE_FUNC(env, ___syscall221), + REG_NATIVE_FUNC(env, _abort), + REG_NATIVE_FUNC(env, abortOnCannotGrowMemory), + REG_NATIVE_FUNC(env, enlargeMemory), + REG_NATIVE_FUNC(env, getTotalMemory), + REG_NATIVE_FUNC(env, ___setErrNo), +}; + +void* +wasm_platform_native_func_lookup(const char *module_name, + const char *func_name) +{ + uint32 size = sizeof(native_func_defs) / sizeof(WASMNativeFuncDef); + WASMNativeFuncDef *func_def = native_func_defs; + WASMNativeFuncDef *func_def_end = func_def + size; + + if (!module_name || !func_name) + return NULL; + + while (func_def < func_def_end) { + if (!strcmp(func_def->module_name, module_name) + && !strcmp(func_def->func_name, func_name)) + return (void*)(uintptr_t)func_def->func_ptr; + func_def++; + } + + return NULL; +} diff --git a/core/iwasm/runtime/platform/vxworks/platform.cmake b/core/iwasm/runtime/platform/vxworks/platform.cmake new file mode 100644 index 00000000..c01fd0e5 --- /dev/null +++ b/core/iwasm/runtime/platform/vxworks/platform.cmake @@ -0,0 +1,25 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199309L) + +set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR}) + +include_directories(${PLATFORM_LIB_DIR}) +include_directories(${PLATFORM_LIB_DIR}/../include) + +file (GLOB_RECURSE source_all ${PLATFORM_LIB_DIR}/*.c) + +set (WASM_PLATFORM_LIB_SOURCE ${source_all}) + diff --git a/core/iwasm/runtime/platform/vxworks/wasm_native.c b/core/iwasm/runtime/platform/vxworks/wasm_native.c new file mode 100644 index 00000000..43276fe6 --- /dev/null +++ b/core/iwasm/runtime/platform/vxworks/wasm_native.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wasm_native.h" + + +void* +wasm_platform_native_func_lookup(const char *module_name, + const char *func_name) +{ + return NULL; +} + diff --git a/core/iwasm/runtime/platform/zephyr/wasm_platform.h b/core/iwasm/runtime/platform/zephyr/wasm_platform.h deleted file mode 100644 index e14d213d..00000000 --- a/core/iwasm/runtime/platform/zephyr/wasm_platform.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2019 Intel Corporation. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _WASM_PLATFORM_H -#define _WASM_PLATFORM_H - -#include "wasm_config.h" -#include "wasm_types.h" -#include -#include -#include -#include - -#include -typedef uint64_t uint64; -typedef int64_t int64; -typedef float float32; -typedef double float64; - -#ifndef NULL -# define NULL ((void*) 0) -#endif - -#define WASM_PLATFORM "Zephyr" - -#include -#include -#include -#include -#include -#include - -/** - * Return the offset of the given field in the given type. - * - * @param Type the type containing the filed - * @param field the field in the type - * - * @return the offset of field in Type - */ -#ifndef offsetof -#define offsetof(Type, field) ((size_t)(&((Type *)0)->field)) -#endif - -typedef struct k_thread korp_thread; -typedef korp_thread *korp_tid; -typedef struct k_mutex korp_mutex; - -int wasm_platform_init(); - -extern bool is_little_endian; - -#include - -/* The following operations declared in string.h may be defined as - macros on Linux, so don't declare them as functions here. */ -/* memset */ -/* memcpy */ -/* memmove */ - -/* #include */ - -/* Unit test framework is based on C++, where the declaration of - snprintf is different. */ -#ifndef __cplusplus -int snprintf(char *buffer, size_t count, const char *format, ...); -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* math functions */ -double sqrt(double x); -double floor(double x); -double ceil(double x); -double fmin(double x, double y); -double fmax(double x, double y); -double rint(double x); -double fabs(double x); -double trunc(double x); -int signbit(double x); -int isnan(double x); - -void* -wasm_dlsym(void *handle, const char *symbol); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/core/iwasm/runtime/utils/wasm_dlfcn.c b/core/iwasm/runtime/utils/wasm_dlfcn.c index de712312..56439c71 100644 --- a/core/iwasm/runtime/utils/wasm_dlfcn.c +++ b/core/iwasm/runtime/utils/wasm_dlfcn.c @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "wasm_platform.h" +#include "bh_platform.h" static bool sort_flag = false; diff --git a/core/iwasm/runtime/vmcore-wasm/wasm.h b/core/iwasm/runtime/vmcore-wasm/wasm.h index e493da99..06b655e2 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm.h +++ b/core/iwasm/runtime/vmcore-wasm/wasm.h @@ -17,7 +17,7 @@ #ifndef _WASM_H_ #define _WASM_H_ -#include "wasm_platform.h" +#include "bh_platform.h" #include "wasm_hashmap.h" #include "wasm_assert.h" diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_application.c b/core/iwasm/runtime/vmcore-wasm/wasm_application.c index df67b3a0..d3aef0c6 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_application.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_application.c @@ -18,6 +18,7 @@ #include #include #include "wasm.h" +#include "wasm_application.h" #include "wasm_interp.h" #include "wasm_runtime.h" #include "wasm_thread.h" @@ -160,6 +161,13 @@ union ieee754_double { } ieee; }; +static union { + int a; + char b; +} __ue = { .a = 1 }; + +#define is_little_endian() (__ue.b == 1) + bool wasm_application_execute_func(WASMModuleInstance *module_inst, char *name, int argc, char *argv[]) @@ -222,7 +230,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst, union ieee754_float u; sig = strtoul(endptr + 1, &endptr, 0); u.f = f32; - if (is_little_endian) + if (is_little_endian()) u.ieee.ieee_little_endian.mantissa = sig; else u.ieee.ieee_big_endian.mantissa = sig; @@ -245,7 +253,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst, union ieee754_double ud; sig = strtoull(endptr + 1, &endptr, 0); ud.d = u.val; - if (is_little_endian) { + if (is_little_endian()) { ud.ieee.ieee_little_endian.mantissa0 = sig >> 32; ud.ieee.ieee_little_endian.mantissa1 = sig; } @@ -286,10 +294,15 @@ wasm_application_execute_func(WASMModuleInstance *module_inst, break; case VALUE_TYPE_I64: { + char buf[16]; union { uint64 val; uint32 parts[2]; } u; u.parts[0] = argv1[0]; u.parts[1] = argv1[1]; - wasm_printf("0x%llx:i64", u.val); + if (sizeof(long) == 4) + snprintf(buf, sizeof(buf), "%s", "0x%llx:i64"); + else + snprintf(buf, sizeof(buf), "%s", "0x%lx:i64"); + wasm_printf(buf, u.val); break; } case VALUE_TYPE_F32: diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c index 73163f32..04cf7440 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_interp.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_interp.c @@ -74,6 +74,24 @@ GET_F64_FROM_ADDR (uint32 *addr) } #endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */ +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 +#define CHECK_EXT_MEMORY_SPACE() \ + else if (module->ext_mem_data \ + && module->ext_mem_base_offset <= offset1 \ + && offset1 < module->ext_mem_base_offset \ + + module->ext_mem_size) { \ + maddr = module->ext_mem_data \ + + (offset1 - module->ext_mem_base_offset); \ + if (maddr < module->ext_mem_data) \ + goto out_of_bounds; \ + maddr1 = maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD]; \ + if (maddr1 > module->ext_mem_data_end) \ + goto out_of_bounds; \ + } +#else +#define CHECK_EXT_MEMORY_SPACE() +#endif + #define CHECK_MEMORY_OVERFLOW() do { \ uint32 offset1 = offset + addr; \ uint8 *maddr1; \ @@ -89,7 +107,8 @@ GET_F64_FROM_ADDR (uint32 *addr) if (maddr1 > memory->end_addr) \ goto out_of_bounds; \ } \ - else { \ + else if (offset1 < memory->heap_base_offset \ + + (memory->heap_data_end - memory->heap_data)) { \ maddr = memory->heap_data + offset1 - memory->heap_base_offset; \ if (maddr < memory->heap_data) \ goto out_of_bounds; \ @@ -97,6 +116,9 @@ GET_F64_FROM_ADDR (uint32 *addr) if (maddr1 > memory->heap_data_end) \ goto out_of_bounds; \ } \ + CHECK_EXT_MEMORY_SPACE() \ + else \ + goto out_of_bounds; \ } while (0) static inline uint32 @@ -588,7 +610,7 @@ ALLOC_FRAME(WASMThread *self, uint32 size, WASMInterpFrame *prev_frame) frame->prev_frame = prev_frame; else { wasm_runtime_set_exception(self->module_inst, - "WASM interp failed, alloc frame failed."); + "WASM interp failed: stack overflow."); } return frame; @@ -641,7 +663,7 @@ wasm_interp_call_func_native(WASMThread *self, else { if (!(argv = wasm_malloc(sizeof(uint32) * argc))) { wasm_runtime_set_exception(self->module_inst, - "WASM call native failed: alloc memory for argv failed."); + "WASM call native failed: allocate memory failed."); return; } } @@ -731,7 +753,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, uint32 i, depth, cond, count, fidx, tidx, frame_size = 0, all_cell_num = 0; int32 didx, val; uint8 *else_addr, *end_addr; - uint8 *maddr; + uint8 *maddr = NULL; #if WASM_ENABLE_LABELS_AS_VALUES != 0 #define HANDLE_OPCODE(op) &&HANDLE_##op @@ -768,7 +790,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, BLOCK_TYPE_BLOCK, &else_addr, &end_addr, NULL, 0)) { - wasm_runtime_set_exception(module, "find block addr failed"); + wasm_runtime_set_exception(module, "find block address failed"); goto got_exception; } @@ -783,7 +805,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, BLOCK_TYPE_LOOP, &else_addr, &end_addr, NULL, 0)) { - wasm_runtime_set_exception(module, "find block addr failed"); + wasm_runtime_set_exception(module, "find block address failed"); goto got_exception; } @@ -798,7 +820,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, BLOCK_TYPE_IF, &else_addr, &end_addr, NULL, 0)) { - wasm_runtime_set_exception(module, "find block addr failed"); + wasm_runtime_set_exception(module, "find block address failed"); goto got_exception; } @@ -855,8 +877,9 @@ wasm_interp_call_func_bytecode(WASMThread *self, depths = depth_buf; else { if (!(depths = wasm_malloc(sizeof(uint32) * count))) { - wasm_runtime_set_exception(module, "WASM interp failed, " - "alloc block memory for br_table failed."); + wasm_runtime_set_exception(module, + "WASM interp failed: " + "allocate memory failed."); goto got_exception; } } @@ -931,7 +954,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP (WASM_OP_DROP): { wasm_runtime_set_exception(module, - "wasm interp failed: unsupported opcode"); + "WASM interp failed: unsupported opcode."); goto got_exception; } @@ -950,7 +973,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP (WASM_OP_SELECT): { wasm_runtime_set_exception(module, - "wasm interp failed: unsupported opcode"); + "WASM interp failed: unsupported opcode."); goto got_exception; } @@ -997,7 +1020,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, break; default: wasm_runtime_set_exception(module, - "get local type is invalid"); + "invalid local type"); goto got_exception; } (void)local_count; @@ -1026,7 +1049,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, break; default: wasm_runtime_set_exception(module, - "set local type is invalid"); + "invalid local type"); goto got_exception; } (void)local_count; @@ -1054,7 +1077,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, SET_LOCAL_F64(local_idx, GET_F64_FROM_ADDR(frame_sp - 2)); break; default: - wasm_runtime_set_exception(module, "tee local type is invalid"); + wasm_runtime_set_exception(module, "invalid local type"); goto got_exception; } (void)local_count; @@ -1085,7 +1108,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, PUSH_F64(*(float64*)get_global_addr(memory, global)); break; default: - wasm_runtime_set_exception(module, "get global type is invalid"); + wasm_runtime_set_exception(module, "invalid global type"); goto got_exception; } HANDLE_OP_END (); @@ -1117,7 +1140,7 @@ wasm_interp_call_func_bytecode(WASMThread *self, PUT_F64_TO_ADDR((uint32*)global_addr, POP_F64()); break; default: - wasm_runtime_set_exception(module, "set global index is overflow"); + wasm_runtime_set_exception(module, "invalid global type"); goto got_exception; } HANDLE_OP_END (); @@ -1125,70 +1148,98 @@ wasm_interp_call_func_bytecode(WASMThread *self, /* memory load instructions */ HANDLE_OP (WASM_OP_I32_LOAD): - DEF_OP_LOAD(PUSH_I32(*(int32*)maddr)); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD): - DEF_OP_LOAD(PUSH_I64(GET_I64_FROM_ADDR((uint32*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_F32_LOAD): - DEF_OP_LOAD(PUSH_F32(*(float32*)maddr)); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_F64_LOAD): - DEF_OP_LOAD(PUSH_F64(GET_F64_FROM_ADDR((uint32*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I32_LOAD8_S): - DEF_OP_LOAD(PUSH_I32(sign_ext_8_32(*(int8*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I32_LOAD8_U): - DEF_OP_LOAD(PUSH_I32((uint32)(*(uint8*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I32_LOAD16_S): - DEF_OP_LOAD(PUSH_I32(sign_ext_16_32(*(int16*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I32_LOAD16_U): - DEF_OP_LOAD(PUSH_I32((uint32)(*(uint16*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD8_S): - DEF_OP_LOAD(PUSH_I64(sign_ext_8_64(*(int8*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD8_U): - DEF_OP_LOAD(PUSH_I64((uint64)(*(uint8*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD16_S): - DEF_OP_LOAD(PUSH_I64(sign_ext_16_64(*(int16*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD16_U): - DEF_OP_LOAD(PUSH_I64((uint64)(*(uint16*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD32_S): - DEF_OP_LOAD(PUSH_I64(sign_ext_32_64(*(int32*)maddr))); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_LOAD32_U): - DEF_OP_LOAD(PUSH_I64((uint64)(*(uint32*)maddr))); - HANDLE_OP_END (); + { + uint32 offset, flags, addr; + GET_OPCODE(); + read_leb_uint32(frame_ip, frame_ip_end, flags); + read_leb_uint32(frame_ip, frame_ip_end, offset); + addr = POP_I32(); + CHECK_MEMORY_OVERFLOW(); +#if WASM_ENABLE_LABELS_AS_VALUES != 0 + static const void *handle_load_table[] = { + &&HANDLE_LOAD_WASM_OP_I32_LOAD, + &&HANDLE_LOAD_WASM_OP_I64_LOAD, + &&HANDLE_LOAD_WASM_OP_F32_LOAD, + &&HANDLE_LOAD_WASM_OP_F64_LOAD, + &&HANDLE_LOAD_WASM_OP_I32_LOAD8_S, + &&HANDLE_LOAD_WASM_OP_I32_LOAD8_U, + &&HANDLE_LOAD_WASM_OP_I32_LOAD16_S, + &&HANDLE_LOAD_WASM_OP_I32_LOAD16_U, + &&HANDLE_LOAD_WASM_OP_I64_LOAD8_S, + &&HANDLE_LOAD_WASM_OP_I64_LOAD8_U, + &&HANDLE_LOAD_WASM_OP_I64_LOAD16_S, + &&HANDLE_LOAD_WASM_OP_I64_LOAD16_U, + &&HANDLE_LOAD_WASM_OP_I64_LOAD32_S, + &&HANDLE_LOAD_WASM_OP_I64_LOAD32_U + }; + #define HANDLE_OP_LOAD(opcode) HANDLE_LOAD_##opcode + goto *handle_load_table[opcode - WASM_OP_I32_LOAD]; +#else + #define HANDLE_OP_LOAD(opcode) case opcode + switch (opcode) +#endif + { + HANDLE_OP_LOAD(WASM_OP_I32_LOAD): + PUSH_I32(*(int32*)maddr); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD): + PUSH_I64(GET_I64_FROM_ADDR((uint32*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_F32_LOAD): + PUSH_F32(*(float32*)maddr); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_F64_LOAD): + PUSH_F64(GET_F64_FROM_ADDR((uint32*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I32_LOAD8_S): + PUSH_I32(sign_ext_8_32(*(int8*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I32_LOAD8_U): + PUSH_I32((uint32)(*(uint8*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I32_LOAD16_S): + PUSH_I32(sign_ext_16_32(*(int16*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I32_LOAD16_U): + PUSH_I32((uint32)(*(uint16*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD8_S): + PUSH_I64(sign_ext_8_64(*(int8*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD8_U): + PUSH_I64((uint64)(*(uint8*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD16_S): + PUSH_I64(sign_ext_16_64(*(int16*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD16_U): + PUSH_I64((uint64)(*(uint16*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD32_S): + PUSH_I64(sign_ext_32_64(*(int32*)maddr)); + HANDLE_OP_END(); + HANDLE_OP_LOAD(WASM_OP_I64_LOAD32_U): + PUSH_I64((uint64)(*(uint32*)maddr)); + HANDLE_OP_END(); + } + (void)flags; + HANDLE_OP_END (); + } /* memory store instructions */ - HANDLE_OP (WASM_OP_I32_STORE): - DEF_OP_STORE(uint32, I32, *(int32*)maddr = sval); - HANDLE_OP_END (); - - HANDLE_OP (WASM_OP_I64_STORE): - DEF_OP_STORE(uint64, I64, PUT_I64_TO_ADDR((uint32*)maddr, sval)); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_F32_STORE): { uint32 offset, flags, addr; @@ -1218,25 +1269,63 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP_END (); } + HANDLE_OP (WASM_OP_I32_STORE): HANDLE_OP (WASM_OP_I32_STORE8): - DEF_OP_STORE(uint32, I32, *(uint8*)maddr = (uint8)sval); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I32_STORE16): - DEF_OP_STORE(uint32, I32, *(uint16*)maddr = (uint16)sval); - HANDLE_OP_END (); + { + uint32 offset, flags, addr; + uint32 sval; + GET_OPCODE(); + read_leb_uint32(frame_ip, frame_ip_end, flags); + read_leb_uint32(frame_ip, frame_ip_end, offset); + sval = POP_I32(); + addr = POP_I32(); + CHECK_MEMORY_OVERFLOW(); + switch (opcode) { + case WASM_OP_I32_STORE: + *(int32*)maddr = sval; + break; + case WASM_OP_I32_STORE8: + *(uint8*)maddr = (uint8)sval; + break; + case WASM_OP_I32_STORE16: + *(uint16*)maddr = (uint16)sval; + break; + } + (void)flags; + HANDLE_OP_END (); + } + HANDLE_OP (WASM_OP_I64_STORE): HANDLE_OP (WASM_OP_I64_STORE8): - DEF_OP_STORE(uint64, I64, *(uint8*)maddr = (uint8)sval); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_STORE16): - DEF_OP_STORE(uint64, I64, *(uint16*)maddr = (uint16)sval); - HANDLE_OP_END (); - HANDLE_OP (WASM_OP_I64_STORE32): - DEF_OP_STORE(uint64, I64, *(uint32*)maddr = (uint32)sval); - HANDLE_OP_END (); + { + uint32 offset, flags, addr; + uint64 sval; + GET_OPCODE(); + read_leb_uint32(frame_ip, frame_ip_end, flags); + read_leb_uint32(frame_ip, frame_ip_end, offset); + sval = POP_I64(); + addr = POP_I32(); + CHECK_MEMORY_OVERFLOW(); + switch (opcode) { + case WASM_OP_I64_STORE: + PUT_I64_TO_ADDR((uint32*)maddr, sval); + break; + case WASM_OP_I64_STORE8: + *(uint8*)maddr = (uint8)sval; + break; + case WASM_OP_I64_STORE16: + *(uint16*)maddr = (uint16)sval; + break; + case WASM_OP_I64_STORE32: + *(uint32*)maddr = (uint32)sval; + break; + } + (void)flags; + HANDLE_OP_END (); + } /* memory size and memory grow instructions */ HANDLE_OP (WASM_OP_MEMORY_SIZE): @@ -1977,7 +2066,8 @@ wasm_interp_call_func_bytecode(WASMThread *self, #if WASM_ENABLE_LABELS_AS_VALUES == 0 default: - wasm_runtime_set_exception(module, "wasm interp failed: unsupported opcode"); + wasm_runtime_set_exception(module, + "WASM interp failed: unsupported opcode."); goto got_exception; } #endif @@ -2005,7 +2095,8 @@ wasm_interp_call_func_bytecode(WASMThread *self, HANDLE_OP (WASM_OP_UNUSED_0x26): HANDLE_OP (WASM_OP_UNUSED_0x27): { - wasm_runtime_set_exception(module, "wasm interp failed: unsupported opcode"); + wasm_runtime_set_exception(module, + "WASM interp failed: unsupported opcode."); goto got_exception; } #endif diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c index c03ddc3a..dbf8a4dc 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_loader.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_loader.c @@ -21,6 +21,7 @@ #include "wasm_runtime.h" #include "wasm_log.h" #include "wasm_memory.h" +#include "wasm_dlfcn.h" /* Read a value of given type from the address pointed to by the given pointer and increase the pointer to the position just after the @@ -140,7 +141,8 @@ const_str_set_insert(const uint8 *str, int32 len, WASMModule *module, if (!c_str) { set_error_buf(error_buf, error_buf_size, - "WASM module load failed: alloc memory failed."); + "WASM module load failed: " + "allocate memory failed."); return NULL; } @@ -233,7 +235,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, module->type_count = type_count; if (!(module->types = wasm_malloc(sizeof(WASMType*) * type_count))) { set_error_buf(error_buf, error_buf_size, - "Load type section failed: alloc memory failed."); + "Load type section failed: allocate memory failed."); return false; } @@ -255,13 +257,20 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, CHECK_BUF(p, p_end, param_count); p += param_count; read_leb_uint32(p, p_end, result_count); - wasm_assert(result_count <= 1); + if (result_count > 1) { + set_error_buf(error_buf, error_buf_size, + "Load type section failed: invalid result count."); + return false; + } CHECK_BUF(p, p_end, result_count); p = p_org; if (!(type = module->types[i] = wasm_malloc(offsetof(WASMType, types) + - sizeof(uint8) * (param_count + result_count)))) + sizeof(uint8) * (param_count + result_count)))) { + set_error_buf(error_buf, error_buf_size, + "Load type section failed: allocate memory failed."); return false; + } /* Resolve param types and result types */ type->param_count = param_count; @@ -412,7 +421,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, module->import_count = import_count; if (!(module->imports = wasm_malloc(sizeof(WASMImport) * import_count))) { set_error_buf(error_buf, error_buf_size, - "Load import section failed: alloc memory failed."); + "Load import section failed: allocate memory failed."); return false; } @@ -634,7 +643,7 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, module->function_count = func_count; if (!(module->functions = wasm_malloc(sizeof(WASMFunction*) * func_count))) { set_error_buf(error_buf, error_buf_size, - "Load function section failed: alloc memory failed."); + "Load function section failed: allocate memory failed."); return false; } @@ -651,7 +660,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, } read_leb_uint32(p_code, buf_code_end, code_size); - if (code_size == 0) { + if (code_size == 0 + || p_code + code_size > buf_code_end) { set_error_buf(error_buf, error_buf_size, "Load function section failed: " "invalid function code size."); @@ -677,7 +687,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, if (!(func = module->functions[i] = wasm_malloc(total_size))) { set_error_buf(error_buf, error_buf_size, - "Load function section failed: alloc memory failed."); + "Load function section failed: " + "allocate memory failed."); return false; } @@ -695,7 +706,20 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, local_type_index = 0; for (j = 0; j < local_set_count; j++) { read_leb_uint32(p_code, buf_code_end, sub_local_count); + if (local_type_index + sub_local_count <= local_type_index + || local_type_index + sub_local_count > local_count) { + set_error_buf(error_buf, error_buf_size, + "Load function section failed: " + "invalid local count."); + return false; + } read_leb_uint8(p_code, buf_code_end, type); + if (type < VALUE_TYPE_F64 || type > VALUE_TYPE_I32) { + set_error_buf(error_buf, error_buf_size, + "Load function section failed: " + "invalid local type."); + return false; + } for (k = 0; k < sub_local_count; k++) { func->local_types[local_type_index++] = type; } @@ -706,8 +730,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, if (p != p_end) { set_error_buf(error_buf, error_buf_size, - "Load function section failed: " - "invalid section size."); + "Load function section failed: " + "invalid section size."); return false; } @@ -734,7 +758,8 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, module->table_count = table_count; if (!(module->tables = wasm_malloc(sizeof(WASMTable) * table_count))) { set_error_buf(error_buf, error_buf_size, - "Load table section failed: alloc memory failed."); + "Load table section failed: " + "allocate memory failed."); return false; } @@ -776,7 +801,8 @@ load_memory_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, module->memory_count = memory_count; if (!(module->memories = wasm_malloc(sizeof(WASMMemory) * memory_count))) { set_error_buf(error_buf, error_buf_size, - "Load memory section failed: alloc memory failed."); + "Load memory section failed: " + "allocate memory failed."); return false; } @@ -813,7 +839,8 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, module->global_count = global_count; if (!(module->globals = wasm_malloc(sizeof(WASMGlobal) * global_count))) { set_error_buf(error_buf, error_buf_size, - "Load global section failed: alloc memory failed."); + "Load global section failed: " + "allocate memory failed."); return false; } @@ -858,7 +885,8 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, module->export_count = export_count; if (!(module->exports = wasm_malloc(sizeof(WASMExport) * export_count))) { set_error_buf(error_buf, error_buf_size, - "Load export section failed: alloc memory failed."); + "Load export section failed: " + "allocate memory failed."); return false; } @@ -951,7 +979,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m (sizeof(WASMTableSeg) * table_segment_count))) { set_error_buf(error_buf, error_buf_size, "Load table segment section failed: " - "alloc memory failed."); + "allocate memory failed."); return false; } @@ -973,7 +1001,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m wasm_malloc(sizeof(uint32) * function_count))) { set_error_buf(error_buf, error_buf_size, "Load table segment section failed: " - "alloc memory failed."); + "allocate memory failed."); return false; } for (j = 0; j < function_count; j++) { @@ -1011,8 +1039,8 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end, if (!(module->data_segments = wasm_malloc(sizeof(WASMDataSeg*) * data_seg_count))) { set_error_buf(error_buf, error_buf_size, - "Load data segment section failed, " - "alloc memory failed."); + "Load data segment section failed: " + "allocate memory failed."); return false; } @@ -1030,7 +1058,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end, wasm_malloc(sizeof(WASMDataSeg)))) { set_error_buf(error_buf, error_buf_size, "Load data segment section failed: " - "alloc memory failed."); + "allocate memory failed."); return false; } @@ -1116,12 +1144,6 @@ load_from_sections(WASMModule *module, WASMSection *sections, section = section->next; } - if (!buf_code) { - set_error_buf(error_buf, error_buf_size, - "WASM module load failed: find code section failed."); - return false; - } - section = sections; while (section) { buf = section->section_body; @@ -1139,8 +1161,13 @@ load_from_sections(WASMModule *module, WASMSection *sections, return false; break; case SECTION_TYPE_FUNC: + if (!buf_code) { + set_error_buf(error_buf, error_buf_size, + "WASM module load failed: find code section failed."); + return false; + } if (!load_function_section(buf, buf_end, buf_code, buf_code_end, - module, error_buf, error_buf_size)) + module, error_buf, error_buf_size)) return false; break; case SECTION_TYPE_TABLE: @@ -1228,7 +1255,8 @@ create_module(char *error_buf, uint32 error_buf_size) if (!module) { set_error_buf(error_buf, error_buf_size, - "WASM module load failed: alloc memory failed."); + "WASM module load failed: " + "allocate memory failed."); return NULL; } @@ -1308,7 +1336,8 @@ create_sections(const uint8 *buf, uint32 size, if (!(section = wasm_malloc(sizeof(WASMSection)))) { set_error_buf(error_buf, error_buf_size, - "WASM module load failed: alloc memory failed."); + "WASM module load failed: " + "allocate memory failed."); return false; } @@ -1335,6 +1364,25 @@ create_sections(const uint8 *buf, uint32 size, return true; } +static void +exchange32(uint8* p_data) +{ + uint8 value = *p_data; + *p_data = *(p_data + 3); + *(p_data + 3) = value; + + value = *(p_data + 1); + *(p_data + 1) = *(p_data + 2); + *(p_data + 2) = value; +} + +static union { + int a; + char b; +} __ue = { .a = 1 }; + +#define is_little_endian() (__ue.b == 1) + static bool load(const uint8 *buf, uint32 size, WASMModule *module, char *error_buf, uint32 error_buf_size) @@ -1345,13 +1393,21 @@ load(const uint8 *buf, uint32 size, WASMModule *module, WASMSection *section_list = NULL; CHECK_BUF(p, p_end, sizeof(uint32)); - if ((magic_number = read_uint32(p)) != WASM_MAGIC_NUMBER) { + magic_number = read_uint32(p); + if (!is_little_endian()) + exchange32((uint8*)&magic_number); + + if (magic_number != WASM_MAGIC_NUMBER) { set_error_buf(error_buf, error_buf_size, "magic header not detected"); return false; } CHECK_BUF(p, p_end, sizeof(uint32)); - if ((version = read_uint32(p)) != WASM_CURRENT_VERSION) { + version = read_uint32(p); + if (!is_little_endian()) + exchange32((uint8*)&version); + + if (version != WASM_CURRENT_VERSION) { set_error_buf(error_buf, error_buf_size, "unknown binary version"); return false; } @@ -1373,7 +1429,7 @@ wasm_loader_load(const uint8 *buf, uint32 size, char *error_buf, uint32 error_bu if (!module) { set_error_buf(error_buf, error_buf_size, - "WASM module load failed: alloc memory failed."); + "WASM module load failed: allocate memory failed."); return NULL; } @@ -1827,9 +1883,11 @@ wasm_loader_find_block_addr(WASMModule *module, break; default: - LOG_ERROR("WASM loader find block addr failed: invalid opcode %02x.\n", - opcode); - break; + if (error_buf) + snprintf(error_buf, error_buf_size, + "WASM loader find block addr failed: " + "invalid opcode %02x.", opcode); + return false; } } @@ -1874,7 +1932,7 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new) if (!mem_new) { \ set_error_buf(error_buf, error_buf_size, \ "WASM loader prepare bytecode failed: " \ - "alloc memory failed"); \ + "allocate memory failed."); \ goto fail; \ } \ mem = mem_new; \ @@ -2173,6 +2231,24 @@ pop_type(uint8 type, uint8 **p_frame_ref, uint32 *p_stack_cell_num, } \ } while (0) +static bool +check_memory(WASMModule *module, + char *error_buf, uint32 error_buf_size) +{ + if (module->memory_count == 0 + && module->import_memory_count == 0) { + set_error_buf(error_buf, error_buf_size, + "load or store in module without default memory"); + return false; + } + return true; +} + +#define CHECK_MEMORY() do { \ + if (!check_memory(module, error_buf, error_buf_size)) \ + goto fail; \ + } while (0) + static bool wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, char *error_buf, uint32 error_buf_size) @@ -2207,7 +2283,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, frame_ref_size = 32; if (!(frame_ref_bottom = frame_ref = wasm_malloc(frame_ref_size))) { set_error_buf(error_buf, error_buf_size, - "WASM loader prepare bytecode failed: alloc memory failed"); + "WASM loader prepare bytecode failed: " + "allocate memory failed"); goto fail; } memset(frame_ref_bottom, 0, frame_ref_size); @@ -2216,7 +2293,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, frame_csp_size = sizeof(BranchBlock) * 8; if (!(frame_csp_bottom = frame_csp = wasm_malloc(frame_csp_size))) { set_error_buf(error_buf, error_buf_size, - "WASM loader prepare bytecode failed: alloc memory failed"); + "WASM loader prepare bytecode failed: " + "allocate memory failed"); goto fail; } @@ -2309,7 +2387,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, if (!block) { set_error_buf(error_buf, error_buf_size, "WASM loader prepare bytecode failed: " - "alloc memory failed"); + "allocate memory failed."); goto fail; } @@ -2322,7 +2400,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, block)) { set_error_buf(error_buf, error_buf_size, "WASM loader prepare bytecode failed: " - "alloc memory failed"); + "allocate memory failed."); wasm_free(block); goto fail; } @@ -2454,12 +2532,20 @@ handle_op_br: WASMType *func_type; uint32 type_idx; + if (module->table_count == 0 + && module->import_table_count == 0) { + set_error_buf(error_buf, error_buf_size, + "call indirect without default table"); + goto fail; + } + read_leb_uint32(p, p_end, type_idx); read_leb_uint8(p, p_end, u8); /* 0x00 */ POP_I32(); if (type_idx >= module->type_count) { - set_error_buf(error_buf, error_buf_size, "function index is overflow"); + set_error_buf(error_buf, error_buf_size, + "function index is overflow"); goto fail; } @@ -2590,6 +2676,7 @@ handle_op_br: case WASM_OP_I32_LOAD8_U: case WASM_OP_I32_LOAD16_S: case WASM_OP_I32_LOAD16_U: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_I32(); @@ -2603,6 +2690,7 @@ handle_op_br: case WASM_OP_I64_LOAD16_U: case WASM_OP_I64_LOAD32_S: case WASM_OP_I64_LOAD32_U: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_I32(); @@ -2610,6 +2698,7 @@ handle_op_br: break; case WASM_OP_F32_LOAD: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_I32(); @@ -2617,6 +2706,7 @@ handle_op_br: break; case WASM_OP_F64_LOAD: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_I32(); @@ -2626,6 +2716,7 @@ handle_op_br: case WASM_OP_I32_STORE: case WASM_OP_I32_STORE8: case WASM_OP_I32_STORE16: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_I32(); @@ -2636,6 +2727,7 @@ handle_op_br: case WASM_OP_I64_STORE8: case WASM_OP_I64_STORE16: case WASM_OP_I64_STORE32: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_I64(); @@ -2643,6 +2735,7 @@ handle_op_br: break; case WASM_OP_F32_STORE: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_F32(); @@ -2650,6 +2743,7 @@ handle_op_br: break; case WASM_OP_F64_STORE: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* align */ read_leb_uint32(p, p_end, u32); /* offset */ POP_F64(); @@ -2657,11 +2751,13 @@ handle_op_br: break; case WASM_OP_MEMORY_SIZE: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* 0x00 */ PUSH_I32(); break; case WASM_OP_MEMORY_GROW: + CHECK_MEMORY(); read_leb_uint32(p, p_end, u32); /* 0x00 */ POP_I32(); PUSH_I32(); @@ -2943,15 +3039,24 @@ handle_op_br: break; default: - LOG_ERROR("WASM loader find block addr failed: invalid opcode %02x.\n", - opcode); - break; + if (error_buf != NULL) + snprintf(error_buf, error_buf_size, + "WASM module load failed: " + "invalid opcode %02x.", opcode); + goto fail; } if (opcode != WASM_OP_I32_CONST) is_i32_const = false; } + if (csp_num > 0) { + set_error_buf(error_buf, error_buf_size, + "WASM module load failed: " + "function body must end with END opcode."); + goto fail; + } + func->max_stack_cell_num = max_stack_cell_num; func->max_block_num = max_csp_num; return_value = true; diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c index ebfe14b5..eec38bcc 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c @@ -35,7 +35,7 @@ set_error_buf(char *error_buf, uint32 error_buf_size, const char *string) bool wasm_runtime_init() { - if (wasm_platform_init() != 0) + if (bh_platform_init() != 0) return false; if (wasm_log_init() != 0) @@ -877,8 +877,9 @@ wasm_runtime_instantiate(WASMModule *module, length = data_seg->data_length; memory_size = NumBytesPerPage * module_inst->default_memory->cur_page_count; - if (base_offset >= memory_size - || base_offset + length > memory_size) { + if (length > 0 + && (base_offset >= memory_size + || base_offset + length > memory_size)) { set_error_buf(error_buf, error_buf_size, "Instantiate module failed: data segment out of range."); wasm_runtime_deinstantiate(module_inst); @@ -946,18 +947,11 @@ wasm_runtime_instantiate(WASMModule *module, wasm_runtime_set_tlr(&module_inst->main_tlr); module_inst->main_tlr.handle = ws_self_thread(); - /* Execute __post_instantiate function */ - if (!execute_post_inst_function(module_inst)) { - const char *exception = wasm_runtime_get_exception(module_inst); - wasm_printf("%s\n", exception); - wasm_runtime_deinstantiate(module_inst); - return NULL; - } - - /* Execute start function */ - if (!execute_start_function(module_inst)) { - const char *exception = wasm_runtime_get_exception(module_inst); - wasm_printf("%s\n", exception); + /* Execute __post_instantiate and start function */ + if (!execute_post_inst_function(module_inst) + || !execute_start_function(module_inst)) { + set_error_buf(error_buf, error_buf_size, + module_inst->cur_exception); wasm_runtime_deinstantiate(module_inst); return NULL; } @@ -991,6 +985,37 @@ wasm_runtime_deinstantiate(WASMModuleInstance *module_inst) wasm_free(module_inst); } +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 +bool +wasm_runtime_set_ext_memory(WASMModuleInstance *module_inst, + uint8 *ext_mem_data, uint32 ext_mem_size, + char *error_buf, uint32 error_buf_size) +{ + if (module_inst->ext_mem_data) { + set_error_buf(error_buf, error_buf_size, + "Set external memory failed: " + "an external memory has been set."); + return false; + } + + if (!ext_mem_data + || ext_mem_size > 1 * BH_GB + || ext_mem_data + ext_mem_size < ext_mem_data) { + set_error_buf(error_buf, error_buf_size, + "Set external memory failed: " + "invalid input."); + return false; + } + + module_inst->ext_mem_data = ext_mem_data; + module_inst->ext_mem_data_end = ext_mem_data + ext_mem_size; + module_inst->ext_mem_size = ext_mem_size; + module_inst->ext_mem_base_offset = DEFAULT_EXT_MEM_BASE_OFFSET; + + return true; +} +#endif + bool wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count) { @@ -1165,24 +1190,40 @@ wasm_runtime_validate_app_addr(WASMModuleInstance *module_inst, uint8 *addr; /* integer overflow check */ - if(app_offset < 0 || - app_offset + size < app_offset) { + if(app_offset + size < app_offset) { goto fail; } memory = module_inst->default_memory; - if (app_offset < memory->heap_base_offset) { + if (0 <= app_offset + && app_offset < memory->heap_base_offset) { addr = memory->memory_data + app_offset; if (!(memory->base_addr <= addr && addr + size <= memory->end_addr)) goto fail; return true; } - else { + else if (memory->heap_base_offset < app_offset + && app_offset < memory->heap_base_offset + + (memory->heap_data_end - memory->heap_data)) { addr = memory->heap_data + (app_offset - memory->heap_base_offset); if (!(memory->heap_data <= addr && addr + size <= memory->heap_data_end)) goto fail; return true; } +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + else if (module_inst->ext_mem_data + && module_inst->ext_mem_base_offset <= app_offset + && app_offset < module_inst->ext_mem_base_offset + + module_inst->ext_mem_size) { + addr = module_inst->ext_mem_data + + (app_offset - module_inst->ext_mem_base_offset); + if (!(module_inst->ext_mem_data <= addr + && addr + size <= module_inst->ext_mem_data_end)) + goto fail; + + return true; + } +#endif fail: wasm_runtime_set_exception(module_inst, "out of bounds memory access"); @@ -1201,7 +1242,13 @@ wasm_runtime_validate_native_addr(WASMModuleInstance *module_inst, } if ((memory->base_addr <= addr && addr + size <= memory->end_addr) - || (memory->heap_data <= addr && addr + size <= memory->heap_data_end)) + || (memory->heap_data <= addr && addr + size <= memory->heap_data_end) +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + || (module_inst->ext_mem_data + && module_inst->ext_mem_data <= addr + && addr + size <= module_inst->ext_mem_data_end) +#endif + ) return true; fail: @@ -1214,10 +1261,22 @@ wasm_runtime_addr_app_to_native(WASMModuleInstance *module_inst, int32 app_offset) { WASMMemoryInstance *memory = module_inst->default_memory; - if (app_offset < memory->heap_base_offset) + if (0 <= app_offset && app_offset < memory->heap_base_offset) return memory->memory_data + app_offset; - else + else if (memory->heap_base_offset < app_offset + && app_offset < memory->heap_base_offset + + (memory->heap_data_end - memory->heap_data)) return memory->heap_data + (app_offset - memory->heap_base_offset); +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + else if (module_inst->ext_mem_data + && module_inst->ext_mem_base_offset <= app_offset + && app_offset < module_inst->ext_mem_base_offset + + module_inst->ext_mem_size) + return module_inst->ext_mem_data + + (app_offset - module_inst->ext_mem_base_offset); +#endif + else + return NULL; } int32 @@ -1225,13 +1284,102 @@ wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst, void *native_ptr) { WASMMemoryInstance *memory = module_inst->default_memory; - if ((uint8*)native_ptr < memory->heap_data) + if (memory->base_addr <= (uint8*)native_ptr + && (uint8*)native_ptr < memory->end_addr) return (uint8*)native_ptr - memory->memory_data; - else + else if (memory->heap_data <= (uint8*)native_ptr + && (uint8*)native_ptr < memory->heap_data_end) return memory->heap_base_offset + ((uint8*)native_ptr - memory->heap_data); +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + else if (module_inst->ext_mem_data + && module_inst->ext_mem_data <= (uint8*)native_ptr + && (uint8*)native_ptr < module_inst->ext_mem_data_end) + return module_inst->ext_mem_base_offset + + ((uint8*)native_ptr - module_inst->ext_mem_data); +#endif + else + return 0; } +bool +wasm_runtime_get_app_addr_range(WASMModuleInstance *module_inst, + int32 app_offset, + int32 *p_app_start_offset, + int32 *p_app_end_offset) +{ + int32 app_start_offset, app_end_offset; + WASMMemoryInstance *memory = module_inst->default_memory; + + if (0 <= app_offset && app_offset < memory->heap_base_offset) { + app_start_offset = 0; + app_end_offset = NumBytesPerPage * memory->cur_page_count; + } + else if (memory->heap_base_offset < app_offset + && app_offset < memory->heap_base_offset + + (memory->heap_data_end - memory->heap_data)) { + app_start_offset = memory->heap_base_offset; + app_end_offset = memory->heap_base_offset + + (memory->heap_data_end - memory->heap_data); + } +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + else if (module_inst->ext_mem_data + && module_inst->ext_mem_base_offset <= app_offset + && app_offset < module_inst->ext_mem_base_offset + + module_inst->ext_mem_size) { + app_start_offset = module_inst->ext_mem_base_offset; + app_end_offset = app_start_offset + module_inst->ext_mem_size; + } +#endif + else + return false; + + if (p_app_start_offset) + *p_app_start_offset = app_start_offset; + if (p_app_end_offset) + *p_app_end_offset = app_end_offset; + return true; +} + +bool +wasm_runtime_get_native_addr_range(WASMModuleInstance *module_inst, + uint8 *native_ptr, + uint8 **p_native_start_addr, + uint8 **p_native_end_addr) +{ + uint8 *native_start_addr, *native_end_addr; + WASMMemoryInstance *memory = module_inst->default_memory; + + if (memory->base_addr <= (uint8*)native_ptr + && (uint8*)native_ptr < memory->end_addr) { + native_start_addr = memory->memory_data; + native_end_addr = memory->memory_data + + NumBytesPerPage * memory->cur_page_count; + } + else if (memory->heap_data <= (uint8*)native_ptr + && (uint8*)native_ptr < memory->heap_data_end) { + native_start_addr = memory->heap_data; + native_end_addr = memory->heap_data_end; + } +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + else if (module_inst->ext_mem_data + && module_inst->ext_mem_data <= (uint8*)native_ptr + && (uint8*)native_ptr < module_inst->ext_mem_data_end) { + native_start_addr = module_inst->ext_mem_data; + native_end_addr = module_inst->ext_mem_data_end; + } +#endif + else + return false; + + if (p_native_start_addr) + *p_native_start_addr = native_start_addr; + if (p_native_end_addr) + *p_native_end_addr = native_end_addr; + return true; +} + + uint32 wasm_runtime_get_temp_ret(WASMModuleInstance *module_inst) { diff --git a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h index 56e806b9..30ef58c3 100644 --- a/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h +++ b/core/iwasm/runtime/vmcore-wasm/wasm_runtime.h @@ -148,6 +148,13 @@ typedef struct WASMModuleInstance { uint32 temp_ret; uint32 llvm_stack; +#if WASM_ENABLE_EXT_MEMORY_SPACE != 0 + int32 ext_mem_base_offset; + uint8 *ext_mem_data; + uint8 *ext_mem_data_end; + uint32 ext_mem_size; +#endif + /* Default WASM stack size of threads of this Module instance. */ uint32 wasm_stack_size; diff --git a/core/shared-lib/include/bh_common.h b/core/shared-lib/include/bh_common.h index 9a3366ce..a8176dc7 100755 --- a/core/shared-lib/include/bh_common.h +++ b/core/shared-lib/include/bh_common.h @@ -23,6 +23,9 @@ #include "bh_log.h" #include "bh_list.h" +typedef void (*bh_print_function_t)(const char* message); +void bh_set_print_function(bh_print_function_t pf); + #define bh_memcpy_s(dest, dlen, src, slen) do { \ int _ret = slen == 0 ? 0 : b_memcpy_s (dest, dlen, src, slen); \ (void)_ret; \ diff --git a/core/shared-lib/include/config.h b/core/shared-lib/include/config.h index 0c270cbc..a7c2a8b2 100644 --- a/core/shared-lib/include/config.h +++ b/core/shared-lib/include/config.h @@ -43,7 +43,9 @@ #endif /* WASM VM log system */ +#ifndef WASM_ENABLE_LOG #define WASM_ENABLE_LOG 1 +#endif /* WASM Interpreter labels-as-values feature */ #define WASM_ENABLE_LABELS_AS_VALUES 1 @@ -63,6 +65,9 @@ /* Max timer number in one app */ #define MAX_TIMERS_PER_APP 30 +/* Max connection number in one app */ +#define MAX_CONNECTION_PER_APP 20 + /* Max resource registration number in one app */ #define RESOURCE_REGISTRATION_NUM_MAX 16 @@ -95,7 +100,11 @@ #define APP_HEAP_SIZE_MAX (1024 * 1024) /* Default wasm stack size of each app */ +#ifdef __x86_64__ +#define DEFAULT_WASM_STACK_SIZE (12 * 1024) +#else #define DEFAULT_WASM_STACK_SIZE (8 * 1024) +#endif /* Default/min/max stack size of each app thread */ #ifndef __ZEPHYR__ @@ -108,3 +117,17 @@ #define APP_THREAD_STACK_SIZE_MAX (256 * 1024) #endif #endif + +/* External memory space provided by user, + but not wasm memory space and app heap space */ +#ifndef WASM_ENABLE_EXT_MEMORY_SPACE +#define WASM_ENABLE_EXT_MEMORY_SPACE 0 +#endif + +/* Default base offset of external memory space */ +#define DEFAULT_EXT_MEM_BASE_OFFSET (-2 * BH_GB) + +#ifndef bh_printf +#define bh_printf printf +#endif + diff --git a/core/shared-lib/mem-alloc/bh_memory.c b/core/shared-lib/mem-alloc/bh_memory.c index bca69705..f0a6641e 100644 --- a/core/shared-lib/mem-alloc/bh_memory.c +++ b/core/shared-lib/mem-alloc/bh_memory.c @@ -15,9 +15,9 @@ */ #include "bh_config.h" +#include "bh_platform.h" #include "bh_memory.h" #include "mem_alloc.h" -#include #include #if BEIHAI_ENABLE_MEMORY_PROFILING != 0 @@ -76,7 +76,7 @@ int bh_memory_init_with_pool(void *mem, unsigned int bytes) global_pool_size = bytes; return 0; } - printf("Init memory with pool (%p, %u) failed.\n", mem, bytes); + bh_printf("Init memory with pool (%p, %u) failed.\n", mem, bytes); return -1; } @@ -91,7 +91,7 @@ int bh_memory_init_with_allocator(void *_malloc_func, void *_free_func) #endif return 0; } - printf("Init memory with allocator (%p, %p) failed.\n", _malloc_func, + bh_printf("Init memory with allocator (%p, %p) failed.\n", _malloc_func, _free_func); return -1; } @@ -117,7 +117,7 @@ int bh_memory_pool_size() void* bh_malloc_internal(unsigned int size) { if (memory_mode == MEMORY_MODE_UNKNOWN) { - printf("bh_malloc failed: memory hasn't been initialize.\n"); + bh_printf("bh_malloc failed: memory hasn't been initialize.\n"); return NULL; } else if (memory_mode == MEMORY_MODE_POOL) { return mem_allocator_malloc(pool_allocator, size); @@ -129,7 +129,7 @@ void* bh_malloc_internal(unsigned int size) void bh_free_internal(void *ptr) { if (memory_mode == MEMORY_MODE_UNKNOWN) { - printf("bh_free failed: memory hasn't been initialize.\n"); + bh_printf("bh_free failed: memory hasn't been initialize.\n"); } else if (memory_mode == MEMORY_MODE_POOL) { mem_allocator_free(pool_allocator, ptr); } else { @@ -250,7 +250,7 @@ void memory_usage_summarize() profile = memory_profiles_list; while (profile) { - printf("malloc:%d:malloc_num:%d:free:%d:free_num:%d:%s\n", + bh_printf("malloc:%d:malloc_num:%d:free:%d:free_num:%d:%s\n", profile->total_malloc, profile->malloc_num, profile->total_free, @@ -267,7 +267,7 @@ void memory_profile_print(const char *file, const char *func, int alloc) { - printf("location:%s@%d:used:%d:contribution:%d\n", + bh_printf("location:%s@%d:used:%d:contribution:%d\n", func, line, memory_in_use, alloc); } @@ -328,4 +328,3 @@ void bh_free_profile(const char *file, int line, const char *func, void *ptr) } #endif /* end of BEIHAI_ENABLE_MEMORY_PROFILING */ #endif /* end of MALLOC_MEMORY_FROM_SYSTEM*/ - diff --git a/core/shared-lib/mem-alloc/ems/ems_alloc.c b/core/shared-lib/mem-alloc/ems/ems_alloc.c index d8682b6c..2c27b71c 100644 --- a/core/shared-lib/mem-alloc/ems/ems_alloc.c +++ b/core/shared-lib/mem-alloc/ems/ems_alloc.c @@ -118,7 +118,7 @@ static void unlink_hmu(gc_heap_t *heap, hmu_t *hmu) } if (!node) { - printf("[GC_ERROR]couldn't find the node in the normal list"); + bh_printf("[GC_ERROR]couldn't find the node in the normal list"); } } else { remove_tree_node((hmu_tree_node_t *) hmu); @@ -392,7 +392,7 @@ gc_object_t _gc_alloc_vo_i_heap(void *vheap, ret = hmu_to_obj(hmu); #if BH_ENABLE_MEMORY_PROFILING != 0 - printf("HEAP.ALLOC: heap: %p, size: %u", heap, size); + bh_printf("HEAP.ALLOC: heap: %p, size: %u", heap, size); #endif FINISH: @@ -434,7 +434,7 @@ gc_object_t _gc_alloc_jo_i_heap(void *vheap, ret = hmu_to_obj(hmu); #if BH_ENABLE_MEMORY_PROFILING != 0 - printf("HEAP.ALLOC: heap: %p, size: %u", heap, size); + bh_printf("HEAP.ALLOC: heap: %p, size: %u", heap, size); #endif FINISH: @@ -495,7 +495,7 @@ int gc_free_i_heap(void *vheap, gc_object_t obj ALLOC_EXTRA_PARAMETERS) heap->total_free_size += size; #endif #if BH_ENABLE_MEMORY_PROFILING != 0 - printf("HEAP.FREE, heap: %p, size: %u\n",heap, size); + bh_printf("HEAP.FREE, heap: %p, size: %u\n",heap, size); #endif if (!hmu_get_pinuse(hmu)) { @@ -538,12 +538,12 @@ int gc_free_i_heap(void *vheap, gc_object_t obj ALLOC_EXTRA_PARAMETERS) void gc_dump_heap_stats(gc_heap_t *heap) { - printf("heap: %p, heap start: %p\n", heap, heap->base_addr); - printf( + bh_printf("heap: %p, heap start: %p\n", heap, heap->base_addr); + bh_printf( "total malloc: totalfree: %u, current: %u, highmark: %u, gc cnt: %u\n", heap->total_free_size, heap->current_size, heap->highmark_size, heap->total_gc_count); - printf("g_total_malloc=%lu, g_total_free=%lu, occupied=%lu\n", + bh_printf("g_total_malloc=%lu, g_total_free=%lu, occupied=%lu\n", g_total_malloc, g_total_free, g_total_malloc - g_total_free); } diff --git a/core/shared-lib/mem-alloc/ems/ems_gc_internal.h b/core/shared-lib/mem-alloc/ems/ems_gc_internal.h index b717971a..51308d2a 100644 --- a/core/shared-lib/mem-alloc/ems/ems_gc_internal.h +++ b/core/shared-lib/mem-alloc/ems/ems_gc_internal.h @@ -21,6 +21,7 @@ extern "C" { #endif +#include "bh_platform.h" #include "bh_thread.h" #include "bh_memory.h" #include "bh_assert.h" @@ -279,4 +280,3 @@ extern int (*gct_vm_gc_finished)(void); #endif #endif - diff --git a/core/shared-lib/mem-alloc/ems/ems_kfc.c b/core/shared-lib/mem-alloc/ems/ems_kfc.c index 791a298a..4409d65d 100644 --- a/core/shared-lib/mem-alloc/ems/ems_kfc.c +++ b/core/shared-lib/mem-alloc/ems/ems_kfc.c @@ -30,7 +30,7 @@ int gci_check_platform() { #define CHECK(x, y) do { \ if((x) != (y)) { \ - printf("Platform checking failed on LINE %d at FILE %s.", \ + bh_printf("Platform checking failed on LINE %d at FILE %s.",\ __LINE__, __FILE__); \ return GC_ERROR; \ } \ @@ -62,12 +62,12 @@ gc_handle_t gc_init_with_pool(char *buf, gc_size_t buf_size) /* check system compatibility*/ if (gci_check_platform() == GC_ERROR) { - printf("Check platform compatibility failed"); + bh_printf("Check platform compatibility failed"); return NULL; } if (buf_size < 1024) { - printf("[GC_ERROR]heap_init_size(%d) < 1024", buf_size); + bh_printf("[GC_ERROR]heap_init_size(%d) < 1024", buf_size); return NULL; } @@ -79,12 +79,12 @@ gc_handle_t gc_init_with_pool(char *buf, gc_size_t buf_size) ret = gct_vm_mutex_init(&heap->lock); if (ret != BHT_OK) { - printf("[GC_ERROR]failed to init lock "); + bh_printf("[GC_ERROR]failed to init lock "); return NULL; } #ifdef BH_FOOTPRINT - printf("\nINIT HEAP 0x%08x %d\n", base_addr, heap_max_size); + bh_printf("\nINIT HEAP 0x%08x %d\n", base_addr, heap_max_size); #endif /* init all data structures*/ @@ -131,7 +131,7 @@ gc_handle_t gc_init_with_pool(char *buf, gc_size_t buf_size) && HMU_FC_NORMAL_MAX_SIZE < q->size); /*@NOTIFY*/ #if BH_ENABLE_MEMORY_PROFILING != 0 - printf("heap is successfully initialized with max_size=%u.", + bh_printf("heap is successfully initialized with max_size=%u.", heap_max_size); #endif return heap; diff --git a/core/iwasm/runtime/platform/alios/COPYRIGHT b/core/shared-lib/platform/alios/COPYRIGHT similarity index 100% rename from core/iwasm/runtime/platform/alios/COPYRIGHT rename to core/shared-lib/platform/alios/COPYRIGHT diff --git a/core/iwasm/runtime/platform/alios/wasm_math.c b/core/shared-lib/platform/alios/bh_math.c similarity index 90% rename from core/iwasm/runtime/platform/alios/wasm_math.c rename to core/shared-lib/platform/alios/bh_math.c index bad81eac..27e95311 100644 --- a/core/iwasm/runtime/platform/alios/wasm_math.c +++ b/core/shared-lib/platform/alios/bh_math.c @@ -28,10 +28,7 @@ * $FreeBSD$ */ -#include "wasm_log.h" -#include "wasm_platform.h" -#include "wasm_platform_log.h" -#include "wasm_memory.h" +#include "bh_platform.h" #define __FDLIBM_STDC__ @@ -99,6 +96,13 @@ typedef union { } bits; } IEEEd2bits_B; +static union { + int a; + char b; +} __ue = { .a = 1 }; + +#define is_little_endian() (__ue.b == 1) + #define __HIL(x) *(1+pdouble2pint(&x)) #define __LOL(x) *(pdouble2pint(&x)) #define __HIB(x) *(int*)&x @@ -179,39 +183,39 @@ do { \ } while (0) /* Macro wrappers. */ -#define EXTRACT_WORDS(ix0,ix1,d) do { \ - if (is_little_endian) \ - EXTRACT_WORDS_L(ix0,ix1,d); \ - else \ - EXTRACT_WORDS_B(ix0,ix1,d); \ +#define EXTRACT_WORDS(ix0,ix1,d) do { \ + if (is_little_endian()) \ + EXTRACT_WORDS_L(ix0,ix1,d); \ + else \ + EXTRACT_WORDS_B(ix0,ix1,d); \ } while (0) -#define INSERT_WORDS(d,ix0,ix1) do { \ - if (is_little_endian) \ - INSERT_WORDS_L(d,ix0,ix1); \ - else \ - INSERT_WORDS_B(d,ix0,ix1); \ +#define INSERT_WORDS(d,ix0,ix1) do { \ + if (is_little_endian()) \ + INSERT_WORDS_L(d,ix0,ix1); \ + else \ + INSERT_WORDS_B(d,ix0,ix1); \ } while (0) -#define GET_HIGH_WORD(i,d) \ -do { \ - if (is_little_endian) \ - GET_HIGH_WORD_L(i,d); \ - else \ - GET_HIGH_WORD_B(i,d); \ -} while (0) +#define GET_HIGH_WORD(i,d) \ + do { \ + if (is_little_endian()) \ + GET_HIGH_WORD_L(i,d); \ + else \ + GET_HIGH_WORD_B(i,d); \ + } while (0) -#define SET_HIGH_WORD(d,v) \ -do { \ - if (is_little_endian) \ - SET_HIGH_WORD_L(d,v); \ - else \ - SET_HIGH_WORD_B(d,v); \ -} while (0) +#define SET_HIGH_WORD(d,v) \ + do { \ + if (is_little_endian()) \ + SET_HIGH_WORD_L(d,v); \ + else \ + SET_HIGH_WORD_B(d,v); \ + } while (0) -#define __HI(x) (is_little_endian ? __HIL(x) : __HIB(x)) +#define __HI(x) (is_little_endian() ? __HIL(x) : __HIB(x)) -#define __LO(x) (is_little_endian ? __LOL(x) : __LOB(x)) +#define __LO(x) (is_little_endian() ? __LOL(x) : __LOB(x)) /* * Attempt to get strict C99 semantics for assignment with non-C99 compilers. @@ -509,7 +513,7 @@ static double freebsd_rint(double x) static int freebsd_isnan(double d) { - if (is_little_endian) { + if (is_little_endian()) { IEEEd2bits_L u; u.d = d; return (u.bits.exp == 2047 && (u.bits.manl != 0 || u.bits.manh != 0)); diff --git a/core/shared-lib/platform/alios/bh_platform.c b/core/shared-lib/platform/alios/bh_platform.c index fe05e8bd..f8ca5735 100644 --- a/core/shared-lib/platform/alios/bh_platform.c +++ b/core/shared-lib/platform/alios/bh_platform.c @@ -25,3 +25,9 @@ char *bh_strdup(const char *s) memcpy(s1, s, strlen(s) + 1); return s1; } + +int bh_platform_init() +{ + return 0; +} + diff --git a/core/shared-lib/platform/alios/bh_platform.h b/core/shared-lib/platform/alios/bh_platform.h index 15fd614f..e23958c9 100644 --- a/core/shared-lib/platform/alios/bh_platform.h +++ b/core/shared-lib/platform/alios/bh_platform.h @@ -43,8 +43,6 @@ /* Invalid thread tid */ #define INVALID_THREAD_ID NULL -#define INVALID_SEM_ID NULL - #define BH_WAIT_FOREVER AOS_WAIT_FOREVER typedef uint64_t uint64; @@ -79,6 +77,18 @@ int snprintf(char *buffer, size_t count, const char *format, ...); #define NULL ((void*)0) #endif +/** + * Return the offset of the given field in the given type. + * + * @param Type the type containing the filed + * @param field the field in the type + * + * @return the offset of field in Type + */ +#ifndef offsetof +#define offsetof(Type, field) ((size_t)(&((Type *)0)->field)) +#endif + extern void bh_assert_internal(int v, const char *file_name, int line_number, const char *expr_string); #define bh_assert(expr) bh_assert_internal((int)(expr), __FILE__, __LINE__, # expr) @@ -86,5 +96,19 @@ extern int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, unsigned i extern int b_strcat_s(char * s1, size_t s1max, const char * s2); extern int b_strcpy_s(char * s1, size_t s1max, const char * s2); +/* math functions */ +double sqrt(double x); +double floor(double x); +double ceil(double x); +double fmin(double x, double y); +double fmax(double x, double y); +double rint(double x); +double fabs(double x); +double trunc(double x); +int signbit(double x); +int isnan(double x); + +int bh_platform_init(); + #endif /* end of _BH_PLATFORM_H */ diff --git a/core/shared-lib/platform/darwin/bh_assert.c b/core/shared-lib/platform/darwin/bh_assert.c new file mode 100644 index 00000000..b52a9aa5 --- /dev/null +++ b/core/shared-lib/platform/darwin/bh_assert.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_platform.h" +#include "bh_assert.h" +#include +#include +#include + +#ifdef BH_TEST +#include +#endif + +#ifdef BH_TEST +/* for exception throwing */ +jmp_buf bh_test_jb; +#endif + +void bh_assert_internal(int v, const char *file_name, int line_number, + const char *expr_string) +{ + if (v) + return; + + if (!file_name) + file_name = "NULL FILENAME"; + if (!expr_string) + expr_string = "NULL EXPR_STRING"; + + printf("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string, + file_name, line_number); + +#ifdef BH_TEST + longjmp(bh_test_jb, 1); +#endif + + abort(); +} + +void bh_debug_internal(const char *file_name, int line_number, const char *fmt, + ...) +{ +#ifndef JEFF_TEST_VERIFIER + va_list args; + + va_start(args, fmt); + bh_assert(file_name); + + printf("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number); + vprintf(fmt, args); + + va_end(args); + printf("\n"); +#endif +} + diff --git a/core/shared-lib/platform/darwin/bh_definition.c b/core/shared-lib/platform/darwin/bh_definition.c new file mode 100644 index 00000000..47ee11ed --- /dev/null +++ b/core/shared-lib/platform/darwin/bh_definition.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_definition.h" +#include "bh_platform.h" + +int bh_return(int ret) +{ + return ret; +} + +#define RSIZE_MAX 0x7FFFFFFF +int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, unsigned int n) +{ + char *dest = (char*) s1; + char *src = (char*) s2; + if (n == 0) { + return 0; + } + + if (s1 == NULL || s1max > RSIZE_MAX) { + return -1; + } + if (s2 == NULL || n > s1max) { + memset(dest, 0, s1max); + return -1; + } + memcpy(dest, src, n); + return 0; +} + +int b_strcat_s(char * s1, size_t s1max, const char * s2) +{ + if (NULL + == s1|| NULL == s2 || s1max < (strlen(s1) + strlen(s2) + 1) || s1max > RSIZE_MAX) { + return -1; + } + + strcat(s1, s2); + + return 0; +} + +int b_strcpy_s(char * s1, size_t s1max, const char * s2) +{ + if (NULL + == s1|| NULL == s2 || s1max < (strlen(s2) + 1) || s1max > RSIZE_MAX) { + return -1; + } + + strcpy(s1, s2); + + return 0; +} + +int fopen_s(FILE ** pFile, const char *filename, const char *mode) +{ + if (NULL == pFile || NULL == filename || NULL == mode) { + return -1; + } + + *pFile = fopen(filename, mode); + + if (NULL == *pFile) + return -1; + + return 0; +} diff --git a/core/shared-lib/platform/darwin/bh_platform.c b/core/shared-lib/platform/darwin/bh_platform.c new file mode 100755 index 00000000..3ff600cf --- /dev/null +++ b/core/shared-lib/platform/darwin/bh_platform.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_platform.h" + +#include +#include +#include + +char *bh_strdup(const char *s) +{ + char *s1 = NULL; + if (s && (s1 = bh_malloc(strlen(s) + 1))) + memcpy(s1, s, strlen(s) + 1); + return s1; +} + +int bh_platform_init() +{ + return 0; +} + +char* +bh_read_file_to_buffer(const char *filename, int *ret_size) +{ + char *buffer; + int file; + int file_size, read_size; + struct stat stat_buf; + + if (!filename || !ret_size) { + printf("Read file to buffer failed: invalid filename or ret size.\n"); + return NULL; + } + + if ((file = open(filename, O_RDONLY, 0)) == -1) { + printf("Read file to buffer failed: open file %s failed.\n", + filename); + return NULL; + } + + if (fstat(file, &stat_buf) != 0) { + printf("Read file to buffer failed: fstat file %s failed.\n", + filename); + close(file); + return NULL; + } + + file_size = stat_buf.st_size; + + if (!(buffer = bh_malloc(file_size))) { + printf("Read file to buffer failed: alloc memory failed.\n"); + close(file); + return NULL; + } + + read_size = read(file, buffer, file_size); + close(file); + + if (read_size < file_size) { + printf("Read file to buffer failed: read file content failed.\n"); + bh_free(buffer); + return NULL; + } + + *ret_size = file_size; + return buffer; +} + diff --git a/core/shared-lib/platform/darwin/bh_platform.h b/core/shared-lib/platform/darwin/bh_platform.h new file mode 100644 index 00000000..2715670b --- /dev/null +++ b/core/shared-lib/platform/darwin/bh_platform.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _BH_PLATFORM_H +#define _BH_PLATFORM_H + +#include "bh_config.h" +#include "bh_types.h" +#include "bh_memory.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint64_t uint64; +typedef int64_t int64; + +extern void DEBUGME(void); + +#define DIE do{bh_debug("Die here\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); DEBUGME(void); while(1);}while(0) + +#define BH_PLATFORM "Darwin" + +/* NEED qsort */ + +#define _STACK_SIZE_ADJUSTMENT (32 * 1024) + +/* Stack size of applet threads's native part. */ +#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT) + +/* Default thread priority */ +#define BH_THREAD_DEFAULT_PRIORITY 0 + +#define BH_ROUTINE_MODIFIER + +#define BHT_TIMEDOUT ETIMEDOUT + +#define INVALID_THREAD_ID 0xFFffFFff + +typedef pthread_t korp_tid; +typedef pthread_mutex_t korp_mutex; +typedef sem_t korp_sem; +typedef pthread_cond_t korp_cond; +typedef pthread_t korp_thread; +typedef void* (*thread_start_routine_t)(void*); + +#define wa_malloc bh_malloc +#define wa_free bh_free +#define wa_strdup bh_strdup + +//int snprintf(char *buffer, size_t count, const char *format, ...); +double fmod(double x, double y); +float fmodf(float x, float y); +double sqrt(double x); + +#define BH_WAIT_FOREVER 0xFFFFFFFF + +#ifndef NULL +# define NULL ((void*) 0) +#endif + +/** + * Return the offset of the given field in the given type. + * + * @param Type the type containing the filed + * @param field the field in the type + * + * @return the offset of field in Type + */ +#ifndef offsetof +#define offsetof(Type, field) ((size_t)(&((Type *)0)->field)) +#endif + +#define bh_assert assert + +int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, + unsigned int n); +int b_strcat_s(char * s1, size_t s1max, const char * s2); +int b_strcpy_s(char * s1, size_t s1max, const char * s2); + +int fopen_s(FILE ** pFile, const char *filename, const char *mode); + +char *bh_read_file_to_buffer(const char *filename, int *ret_size); + +char *bh_strdup(const char *s); + +int bh_platform_init(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/shared-lib/platform/darwin/bh_platform_log.c b/core/shared-lib/platform/darwin/bh_platform_log.c new file mode 100644 index 00000000..4ff03192 --- /dev/null +++ b/core/shared-lib/platform/darwin/bh_platform_log.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_platform.h" +#include + +void bh_log_emit(const char *fmt, va_list ap) +{ + vprintf(fmt, ap); + fflush(stdout); +} + +int bh_fprintf(FILE *stream, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = vfprintf(stream ? stream : stdout, fmt, ap); + va_end(ap); + + return ret; +} + +int bh_fflush(void *stream) +{ + return fflush(stream ? stream : stdout); +} diff --git a/core/shared-lib/platform/darwin/bh_thread.c b/core/shared-lib/platform/darwin/bh_thread.c new file mode 100755 index 00000000..97879aa7 --- /dev/null +++ b/core/shared-lib/platform/darwin/bh_thread.c @@ -0,0 +1,405 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_thread.h" +#include "bh_assert.h" +#include "bh_log.h" +#include "bh_memory.h" +#include +#include +#include + +static bool is_thread_sys_inited = false; + +static korp_mutex thread_list_lock; +static pthread_key_t thread_local_storage_key[BH_MAX_TLS_NUM]; + +int _vm_thread_sys_init() +{ + unsigned i, j; + int ret; + + if (is_thread_sys_inited) + return 0; + + for (i = 0; i < BH_MAX_TLS_NUM; i++) { + ret = pthread_key_create(&thread_local_storage_key[i], NULL); + if (ret) + goto fail; + } + + ret = vm_mutex_init(&thread_list_lock); + if (ret) + goto fail; + + is_thread_sys_inited = true; + return 0; + + fail: for (j = 0; j < i; j++) + pthread_key_delete(thread_local_storage_key[j]); + return -1; +} + +void vm_thread_sys_destroy(void) +{ + if (is_thread_sys_inited) { + unsigned i; + for (i = 0; i < BH_MAX_TLS_NUM; i++) + pthread_key_delete(thread_local_storage_key[i]); + vm_mutex_destroy(&thread_list_lock); + is_thread_sys_inited = false; + } +} + +typedef struct { + thread_start_routine_t start; + void* stack; + int stack_size; + void* arg; +} thread_wrapper_arg; + +static void *vm_thread_wrapper(void *arg) +{ + thread_wrapper_arg * targ = arg; + LOG_VERBOSE("THREAD CREATE 0x%08x\n", &targ); + targ->stack = (void *)((uintptr_t)(&arg) & ~0xfff); + _vm_tls_put(1, targ); + targ->start(targ->arg); + bh_free(targ); + _vm_tls_put(1, NULL); + return NULL; +} + +int _vm_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start, + void *arg, unsigned int stack_size, int prio) +{ + pthread_attr_t tattr; + thread_wrapper_arg *targ; + + bh_assert(stack_size > 0); + bh_assert(tid); + bh_assert(start); + + *tid = INVALID_THREAD_ID; + + pthread_attr_init(&tattr); + pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE); + if (pthread_attr_setstacksize(&tattr, stack_size) != 0) { + bh_debug("Invalid thread stack size %u. Min stack size on Linux = %u", + stack_size, PTHREAD_STACK_MIN); + pthread_attr_destroy(&tattr); + return BHT_ERROR; + } + + targ = (thread_wrapper_arg*) bh_malloc(sizeof(*targ)); + if (!targ) { + pthread_attr_destroy(&tattr); + return BHT_ERROR; + } + + targ->start = start; + targ->arg = arg; + targ->stack_size = stack_size; + + if (pthread_create(tid, &tattr, vm_thread_wrapper, targ) != 0) { + pthread_attr_destroy(&tattr); + bh_free(targ); + return BHT_ERROR; + } + + pthread_attr_destroy(&tattr); + return BHT_OK; +} + +int _vm_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg, + unsigned int stack_size) +{ + return _vm_thread_create_with_prio(tid, start, arg, stack_size, + BH_THREAD_DEFAULT_PRIORITY); +} + +korp_tid _vm_self_thread() +{ + return (korp_tid) pthread_self(); +} + +void vm_thread_exit(void * code) +{ + bh_free(_vm_tls_get(1)); + _vm_tls_put(1, NULL); + pthread_exit(code); +} + +void *_vm_tls_get(unsigned idx) +{ + bh_assert(idx < BH_MAX_TLS_NUM); + return pthread_getspecific(thread_local_storage_key[idx]); +} + +int _vm_tls_put(unsigned idx, void * tls) +{ + bh_assert(idx < BH_MAX_TLS_NUM); + pthread_setspecific(thread_local_storage_key[idx], tls); + return BHT_OK; +} + +int _vm_mutex_init(korp_mutex *mutex) +{ + return pthread_mutex_init(mutex, NULL) == 0 ? BHT_OK : BHT_ERROR; +} + +int _vm_recursive_mutex_init(korp_mutex *mutex) +{ + int ret; + + pthread_mutexattr_t mattr; + + bh_assert(mutex); + ret = pthread_mutexattr_init(&mattr); + if (ret) + return BHT_ERROR; + + pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE); + ret = pthread_mutex_init(mutex, &mattr); + pthread_mutexattr_destroy(&mattr); + + return ret == 0 ? BHT_OK : BHT_ERROR; +} + +int _vm_mutex_destroy(korp_mutex *mutex) +{ + int ret; + + bh_assert(mutex); + ret = pthread_mutex_destroy(mutex); + + return ret == 0 ? BHT_OK : BHT_ERROR; +} + +/* Returned error (EINVAL, EAGAIN and EDEADLK) from + locking the mutex indicates some logic error present in + the program somewhere. + Don't try to recover error for an existing unknown error.*/ +void vm_mutex_lock(korp_mutex *mutex) +{ + int ret; + + bh_assert(mutex); + ret = pthread_mutex_lock(mutex); + if (0 != ret) { + printf("vm mutex lock failed (ret=%d)!\n", ret); + exit(-1); + } +} + +int vm_mutex_trylock(korp_mutex *mutex) +{ + int ret; + + bh_assert(mutex); + ret = pthread_mutex_trylock(mutex); + + return ret == 0 ? BHT_OK : BHT_ERROR; +} + +/* Returned error (EINVAL, EAGAIN and EPERM) from + unlocking the mutex indicates some logic error present + in the program somewhere. + Don't try to recover error for an existing unknown error.*/ +void vm_mutex_unlock(korp_mutex *mutex) +{ + int ret; + + bh_assert(mutex); + ret = pthread_mutex_unlock(mutex); + if (0 != ret) { + printf("vm mutex unlock failed (ret=%d)!\n", ret); + exit(-1); + } +} + +int _vm_sem_init(korp_sem* sem, unsigned int c) +{ + int ret; + + bh_assert(sem); + ret = sem_init(sem, 0, c); + + return ret == 0 ? BHT_OK : BHT_ERROR; +} + +int _vm_sem_destroy(korp_sem *sem) +{ + int ret; + + bh_assert(sem); + ret = sem_destroy(sem); + + return ret == 0 ? BHT_OK : BHT_ERROR; +} + +int _vm_sem_wait(korp_sem *sem) +{ + int ret; + + bh_assert(sem); + + ret = sem_wait(sem); + + return ret == 0 ? BHT_OK : BHT_ERROR; +} + +/*int _vm_sem_reltimedwait(korp_sem *sem, int mills) +{ + int ret = BHT_OK; + + struct timespec timeout; + const int mills_per_sec = 1000; + const int mills_to_nsec = 1E6; + + bh_assert(sem); + + if (mills == BHT_WAIT_FOREVER) { + ret = sem_wait(sem); + } else { + + timeout.tv_sec = mills / mills_per_sec; + timeout.tv_nsec = (mills % mills_per_sec) * mills_to_nsec; + timeout.tv_sec += time(NULL); + + ret = sem_timedwait(sem, &timeout); + } + + if (ret != BHT_OK) { + if (errno == BHT_TIMEDOUT) { + ret = BHT_TIMEDOUT; + errno = 0; + } else { + bh_debug("Faliure happens when timed wait is called"); + bh_assert(0); + } + } + + return ret; +} +*/ + +int _vm_sem_post(korp_sem *sem) +{ + bh_assert(sem); + + return sem_post(sem) == 0 ? BHT_OK : BHT_ERROR; +} + +int _vm_cond_init(korp_cond *cond) +{ + bh_assert(cond); + + if (pthread_cond_init(cond, NULL) != BHT_OK) + return BHT_ERROR; + + return BHT_OK; +} + +int _vm_cond_destroy(korp_cond *cond) +{ + bh_assert(cond); + + if (pthread_cond_destroy(cond) != BHT_OK) + return BHT_ERROR; + + return BHT_OK; +} + +int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex) +{ + bh_assert(cond); + bh_assert(mutex); + + if (pthread_cond_wait(cond, mutex) != BHT_OK) + return BHT_ERROR; + + return BHT_OK; +} + +static void msec_nsec_to_abstime(struct timespec *ts, int64 msec, int32 nsec) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + ts->tv_sec = tv.tv_sec + msec / 1000; + ts->tv_nsec = tv.tv_usec * 1000 + (msec % 1000) * 1000000 + nsec; + + if (ts->tv_nsec >= 1000000000L) { + ts->tv_sec++; + ts->tv_nsec -= 1000000000L; + } +} + +int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills) +{ + int ret; + struct timespec abstime; + + if (mills == BHT_WAIT_FOREVER) + ret = pthread_cond_wait(cond, mutex); + else { + msec_nsec_to_abstime(&abstime, mills, 0); + ret = pthread_cond_timedwait(cond, mutex, &abstime); + } + + if (ret != BHT_OK && ret != BHT_TIMEDOUT) + return BHT_ERROR; + + return BHT_OK; +} + +int _vm_cond_signal(korp_cond *cond) +{ + bh_assert(cond); + + if (pthread_cond_signal(cond) != BHT_OK) + return BHT_ERROR; + + return BHT_OK; +} + +int _vm_cond_broadcast(korp_cond *cond) +{ + bh_assert(cond); + + if (pthread_cond_broadcast(cond) != BHT_OK) + return BHT_ERROR; + + return BHT_OK; +} + +int _vm_thread_cancel(korp_tid thread) +{ + return pthread_cancel(thread); +} + +int _vm_thread_join(korp_tid thread, void **value_ptr, int mills) +{ + return pthread_join(thread, value_ptr); +} + +int _vm_thread_detach(korp_tid thread) +{ + return pthread_detach(thread); +} + diff --git a/core/shared-lib/platform/darwin/bh_time.c b/core/shared-lib/platform/darwin/bh_time.c new file mode 100755 index 00000000..0627b08d --- /dev/null +++ b/core/shared-lib/platform/darwin/bh_time.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_time.h" + +#include +#include +#include +#include + +/* + * This function returns milliseconds per tick. + * @return milliseconds per tick. + */ +uint64 _bh_time_get_tick_millisecond() +{ + return sysconf(_SC_CLK_TCK); +} + +/* + * This function returns milliseconds after boot. + * @return milliseconds after boot. + */ +uint64 _bh_time_get_boot_millisecond() +{ + struct timespec ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { + return 0; + } + + return ((uint64) ts.tv_sec) * 1000 + ts.tv_nsec / (1000 * 1000); +} + +uint32 bh_get_tick_sec() +{ + return _bh_time_get_boot_millisecond() / 1000; +} + +/* + * This function returns GMT time milliseconds since from 1970.1.1, AKA UNIX time. + * @return milliseconds since from 1970.1.1. + */ +uint64 _bh_time_get_millisecond_from_1970() +{ + struct timeb tp; + ftime(&tp); + + return ((uint64) tp.time) * 1000 + tp.millitm + - (tp.dstflag == 0 ? 0 : 60 * 60 * 1000) + tp.timezone * 60 * 1000; +} + +size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time) +{ + time_t time_sec = time / 1000; + struct timeb tp; + struct tm *ltp; + + ftime(&tp); + time_sec -= tp.timezone * 60; + + ltp = localtime(&time_sec); + if (ltp == NULL) { + return 0; + } + return strftime(s, max, format, ltp); +} + diff --git a/core/shared-lib/platform/darwin/shared_platform.cmake b/core/shared-lib/platform/darwin/shared_platform.cmake new file mode 100644 index 00000000..5b403a09 --- /dev/null +++ b/core/shared-lib/platform/darwin/shared_platform.cmake @@ -0,0 +1,24 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR}) + +include_directories(${PLATFORM_SHARED_DIR}) +include_directories(${PLATFORM_SHARED_DIR}/../include) + + +file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c) + +set (PLATFORM_SHARED_SOURCE ${source_all}) + diff --git a/core/shared-lib/platform/include/bh_types.h b/core/shared-lib/platform/include/bh_types.h index ff561b24..da26c7dc 100644 --- a/core/shared-lib/platform/include/bh_types.h +++ b/core/shared-lib/platform/include/bh_types.h @@ -25,6 +25,8 @@ typedef unsigned short uint16; typedef short int16; typedef unsigned int uint32; typedef int int32; +typedef float float32; +typedef double float64; #define BYTES_OF_UINT8 1 #define BYTES_OF_UINT16 2 diff --git a/core/shared-lib/platform/linux-sgx/bh_assert.c b/core/shared-lib/platform/linux-sgx/bh_assert.c new file mode 100644 index 00000000..b52a9aa5 --- /dev/null +++ b/core/shared-lib/platform/linux-sgx/bh_assert.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_platform.h" +#include "bh_assert.h" +#include +#include +#include + +#ifdef BH_TEST +#include +#endif + +#ifdef BH_TEST +/* for exception throwing */ +jmp_buf bh_test_jb; +#endif + +void bh_assert_internal(int v, const char *file_name, int line_number, + const char *expr_string) +{ + if (v) + return; + + if (!file_name) + file_name = "NULL FILENAME"; + if (!expr_string) + expr_string = "NULL EXPR_STRING"; + + printf("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string, + file_name, line_number); + +#ifdef BH_TEST + longjmp(bh_test_jb, 1); +#endif + + abort(); +} + +void bh_debug_internal(const char *file_name, int line_number, const char *fmt, + ...) +{ +#ifndef JEFF_TEST_VERIFIER + va_list args; + + va_start(args, fmt); + bh_assert(file_name); + + printf("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number); + vprintf(fmt, args); + + va_end(args); + printf("\n"); +#endif +} + diff --git a/core/shared-lib/platform/linux-sgx/bh_definition.c b/core/shared-lib/platform/linux-sgx/bh_definition.c new file mode 100644 index 00000000..5105d0ff --- /dev/null +++ b/core/shared-lib/platform/linux-sgx/bh_definition.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_definition.h" +#include "bh_platform.h" + +int bh_return(int ret) +{ + return ret; +} + +#define RSIZE_MAX 0x7FFFFFFF +int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, unsigned int n) +{ + char *dest = (char*) s1; + char *src = (char*) s2; + if (n == 0) { + return 0; + } + + if (s1 == NULL || s1max > RSIZE_MAX) { + return -1; + } + if (s2 == NULL || n > s1max) { + memset(dest, 0, s1max); + return -1; + } + memcpy(dest, src, n); + return 0; +} + +int b_strcat_s(char * s1, size_t s1max, const char * s2) +{ + if (NULL + == s1|| NULL == s2 || s1max < (strlen(s1) + strlen(s2) + 1) || s1max > RSIZE_MAX) { + return -1; + } + + strcat(s1, s2); + + return 0; +} + +int b_strcpy_s(char * s1, size_t s1max, const char * s2) +{ + if (NULL + == s1|| NULL == s2 || s1max < (strlen(s2) + 1) || s1max > RSIZE_MAX) { + return -1; + } + + strncpy(s1, s2, s1max); + + return 0; +} + +int fopen_s(FILE ** pFile, const char *filename, const char *mode) +{ + if (NULL == pFile || NULL == filename || NULL == mode) { + return -1; + } + + *pFile = fopen(filename, mode); + + if (NULL == *pFile) + return -1; + + return 0; +} diff --git a/core/shared-lib/platform/linux-sgx/bh_platform.c b/core/shared-lib/platform/linux-sgx/bh_platform.c new file mode 100644 index 00000000..d6f4c29c --- /dev/null +++ b/core/shared-lib/platform/linux-sgx/bh_platform.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_common.h" +#include "bh_platform.h" + +#include +#include +#include + +#define FIXED_BUFFER_SIZE (1<<14) +static bh_print_function_t print_function = NULL; + +char *bh_strdup(const char *s) +{ + char *s1 = NULL; + if (s && (s1 = bh_malloc(strlen(s) + 1))) + memcpy(s1, s, strlen(s) + 1); + return s1; +} + +int bh_platform_init() +{ + return 0; +} + +int putchar(int c) +{ + return 0; +} + +int puts(const char *s) +{ + return 0; +} + +void bh_set_print_function(bh_print_function_t pf) +{ + print_function = pf; +} + +int bh_printf_sgx(const char *message, ...) +{ + if (print_function != NULL) { + char msg[FIXED_BUFFER_SIZE] = { '\0' }; + va_list ap; + va_start(ap, message); + vsnprintf(msg, FIXED_BUFFER_SIZE, message, ap); + va_end(ap); + print_function(msg); + } + + return 0; +} diff --git a/core/iwasm/runtime/platform/linux/wasm_platform.h b/core/shared-lib/platform/linux-sgx/bh_platform.h similarity index 51% rename from core/iwasm/runtime/platform/linux/wasm_platform.h rename to core/shared-lib/platform/linux-sgx/bh_platform.h index 7a632095..7a835ef8 100644 --- a/core/iwasm/runtime/platform/linux/wasm_platform.h +++ b/core/shared-lib/platform/linux-sgx/bh_platform.h @@ -14,34 +14,76 @@ * limitations under the License. */ -#ifndef _WASM_PLATFORM_H -#define _WASM_PLATFORM_H - -#include "wasm_config.h" -#include "wasm_types.h" +#ifndef _BH_PLATFORM_H +#define _BH_PLATFORM_H +#include "bh_config.h" +#include "bh_types.h" +#include "bh_memory.h" #include #include -typedef uint64_t uint64; -typedef int64_t int64; -typedef float float32; -typedef double float64; - -#ifndef NULL -# define NULL ((void*) 0) -#endif - -#define WASM_PLATFORM "Linux" - +#include +#include +#include +#include +#include +#include #include #include #include #include -#include #include -#include -#include -#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern int bh_printf_sgx(const char *message, ...); + +typedef uint64_t uint64; +typedef int64_t int64; + +#define DIE do{bh_debug("Die here\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); DEBUGME(void); while(1);}while(0) + +#define BH_PLATFORM "Linux-SGX" + +/* NEED qsort */ + +#define _STACK_SIZE_ADJUSTMENT (32 * 1024) + +/* Stack size of applet threads's native part. */ +#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT) + +/* Default thread priority */ +#define BH_THREAD_DEFAULT_PRIORITY 0 + +#define BH_ROUTINE_MODIFIER + +#define BHT_TIMEDOUT ETIMEDOUT + +#define INVALID_THREAD_ID 0xFFffFFff + +typedef int korp_tid; +typedef int korp_mutex; +typedef int korp_sem; +typedef int korp_cond; +typedef int korp_thread; +typedef void* (*thread_start_routine_t)(void*); + +#define wa_malloc bh_malloc +#define wa_free bh_free +#define wa_strdup bh_strdup + +int snprintf(char *buffer, size_t count, const char *format, ...); +double fmod(double x, double y); +float fmodf(float x, float y); +double sqrt(double x); + +#define BH_WAIT_FOREVER 0xFFFFFFFF + +#ifndef NULL +# define NULL ((void*) 0) +#endif /** * Return the offset of the given field in the given type. @@ -55,47 +97,16 @@ typedef double float64; #define offsetof(Type, field) ((size_t)(&((Type *)0)->field)) #endif -typedef pthread_t korp_tid; -typedef pthread_mutex_t korp_mutex; +#define bh_assert assert -int wasm_platform_init(); +int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, + unsigned int n); +int b_strcat_s(char * s1, size_t s1max, const char * s2); +int b_strcpy_s(char * s1, size_t s1max, const char * s2); -extern bool is_little_endian; +char *bh_strdup(const char *s); -#include - -/* The following operations declared in string.h may be defined as - macros on Linux, so don't declare them as functions here. */ -/* memset */ -/* memcpy */ -/* memmove */ - -/* #include */ - -/* Unit test framework is based on C++, where the declaration of - snprintf is different. */ -#ifndef __cplusplus -int snprintf(char *buffer, size_t count, const char *format, ...); -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* #include */ - -#ifndef __cplusplus -double sqrt(double x); -#endif - -#include -extern int fopen_s(FILE ** pFile, const char *filename, const char *mode); - -char* -wasm_read_file_to_buffer(const char *filename, int *ret_size); - -void* -wasm_dlsym(void *handle, const char *symbol); +int bh_platform_init(); #ifdef __cplusplus } diff --git a/core/shared-lib/platform/linux-sgx/bh_platform_log.c b/core/shared-lib/platform/linux-sgx/bh_platform_log.c new file mode 100644 index 00000000..4ff03192 --- /dev/null +++ b/core/shared-lib/platform/linux-sgx/bh_platform_log.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_platform.h" +#include + +void bh_log_emit(const char *fmt, va_list ap) +{ + vprintf(fmt, ap); + fflush(stdout); +} + +int bh_fprintf(FILE *stream, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = vfprintf(stream ? stream : stdout, fmt, ap); + va_end(ap); + + return ret; +} + +int bh_fflush(void *stream) +{ + return fflush(stream ? stream : stdout); +} diff --git a/core/shared-lib/platform/linux-sgx/bh_thread.c b/core/shared-lib/platform/linux-sgx/bh_thread.c new file mode 100644 index 00000000..8730e13c --- /dev/null +++ b/core/shared-lib/platform/linux-sgx/bh_thread.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_thread.h" +#include "bh_assert.h" +#include "bh_memory.h" +#include +#include +#include + +int _vm_thread_sys_init() +{ + return 0; +} + +void vm_thread_sys_destroy(void) +{ +} + +int _vm_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start, + void *arg, unsigned int stack_size, int prio) +{ + return BHT_ERROR; + // return BHT_OK; +} + +int _vm_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg, + unsigned int stack_size) +{ + return _vm_thread_create_with_prio(tid, start, arg, stack_size, + BH_THREAD_DEFAULT_PRIORITY); +} + +korp_tid _vm_self_thread() +{ + return 0; +} + +void vm_thread_exit(void * code) +{ +} + +// storage for one thread +static void *_tls_store = NULL; + +void *_vm_tls_get(unsigned idx) +{ + return _tls_store; +} + +int _vm_tls_put(unsigned idx, void * tls) +{ + _tls_store = tls; + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_mutex_init(korp_mutex *mutex) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_recursive_mutex_init(korp_mutex *mutex) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_mutex_destroy(korp_mutex *mutex) +{ + return BHT_OK; + //return BHT_ERROR; +} + +/* Returned error (EINVAL, EAGAIN and EDEADLK) from + locking the mutex indicates some logic error present in + the program somewhere. + Don't try to recover error for an existing unknown error.*/ +void vm_mutex_lock(korp_mutex *mutex) +{ +} + +int vm_mutex_trylock(korp_mutex *mutex) +{ + return BHT_OK; + //return BHT_ERROR; +} + +/* Returned error (EINVAL, EAGAIN and EPERM) from + unlocking the mutex indicates some logic error present + in the program somewhere. + Don't try to recover error for an existing unknown error.*/ +void vm_mutex_unlock(korp_mutex *mutex) +{ +} + +int _vm_sem_init(korp_sem* sem, unsigned int c) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_sem_destroy(korp_sem *sem) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_sem_wait(korp_sem *sem) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_sem_reltimedwait(korp_sem *sem, int mills) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_sem_post(korp_sem *sem) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_cond_init(korp_cond *cond) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_cond_destroy(korp_cond *cond) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_cond_signal(korp_cond *cond) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_cond_broadcast(korp_cond *cond) +{ + return BHT_OK; + //return BHT_ERROR; +} + +int _vm_thread_cancel(korp_tid thread) +{ + return 0; +} + +int _vm_thread_join(korp_tid thread, void **value_ptr, int mills) +{ + return 0; +} + +int _vm_thread_detach(korp_tid thread) +{ + return 0; +} diff --git a/core/shared-lib/platform/linux-sgx/bh_time.c b/core/shared-lib/platform/linux-sgx/bh_time.c new file mode 100644 index 00000000..0627b08d --- /dev/null +++ b/core/shared-lib/platform/linux-sgx/bh_time.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_time.h" + +#include +#include +#include +#include + +/* + * This function returns milliseconds per tick. + * @return milliseconds per tick. + */ +uint64 _bh_time_get_tick_millisecond() +{ + return sysconf(_SC_CLK_TCK); +} + +/* + * This function returns milliseconds after boot. + * @return milliseconds after boot. + */ +uint64 _bh_time_get_boot_millisecond() +{ + struct timespec ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { + return 0; + } + + return ((uint64) ts.tv_sec) * 1000 + ts.tv_nsec / (1000 * 1000); +} + +uint32 bh_get_tick_sec() +{ + return _bh_time_get_boot_millisecond() / 1000; +} + +/* + * This function returns GMT time milliseconds since from 1970.1.1, AKA UNIX time. + * @return milliseconds since from 1970.1.1. + */ +uint64 _bh_time_get_millisecond_from_1970() +{ + struct timeb tp; + ftime(&tp); + + return ((uint64) tp.time) * 1000 + tp.millitm + - (tp.dstflag == 0 ? 0 : 60 * 60 * 1000) + tp.timezone * 60 * 1000; +} + +size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time) +{ + time_t time_sec = time / 1000; + struct timeb tp; + struct tm *ltp; + + ftime(&tp); + time_sec -= tp.timezone * 60; + + ltp = localtime(&time_sec); + if (ltp == NULL) { + return 0; + } + return strftime(s, max, format, ltp); +} + diff --git a/core/shared-lib/platform/linux-sgx/shared_platform.cmake b/core/shared-lib/platform/linux-sgx/shared_platform.cmake new file mode 100644 index 00000000..5b403a09 --- /dev/null +++ b/core/shared-lib/platform/linux-sgx/shared_platform.cmake @@ -0,0 +1,24 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR}) + +include_directories(${PLATFORM_SHARED_DIR}) +include_directories(${PLATFORM_SHARED_DIR}/../include) + + +file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c) + +set (PLATFORM_SHARED_SOURCE ${source_all}) + diff --git a/core/shared-lib/platform/linux/bh_platform.c b/core/shared-lib/platform/linux/bh_platform.c index fe05e8bd..3ff600cf 100755 --- a/core/shared-lib/platform/linux/bh_platform.c +++ b/core/shared-lib/platform/linux/bh_platform.c @@ -15,8 +15,10 @@ */ #include "bh_platform.h" -#include -#include + +#include +#include +#include char *bh_strdup(const char *s) { @@ -25,3 +27,56 @@ char *bh_strdup(const char *s) memcpy(s1, s, strlen(s) + 1); return s1; } + +int bh_platform_init() +{ + return 0; +} + +char* +bh_read_file_to_buffer(const char *filename, int *ret_size) +{ + char *buffer; + int file; + int file_size, read_size; + struct stat stat_buf; + + if (!filename || !ret_size) { + printf("Read file to buffer failed: invalid filename or ret size.\n"); + return NULL; + } + + if ((file = open(filename, O_RDONLY, 0)) == -1) { + printf("Read file to buffer failed: open file %s failed.\n", + filename); + return NULL; + } + + if (fstat(file, &stat_buf) != 0) { + printf("Read file to buffer failed: fstat file %s failed.\n", + filename); + close(file); + return NULL; + } + + file_size = stat_buf.st_size; + + if (!(buffer = bh_malloc(file_size))) { + printf("Read file to buffer failed: alloc memory failed.\n"); + close(file); + return NULL; + } + + read_size = read(file, buffer, file_size); + close(file); + + if (read_size < file_size) { + printf("Read file to buffer failed: read file content failed.\n"); + bh_free(buffer); + return NULL; + } + + *ret_size = file_size; + return buffer; +} + diff --git a/core/shared-lib/platform/linux/bh_platform.h b/core/shared-lib/platform/linux/bh_platform.h index 00c25b49..47172c1f 100644 --- a/core/shared-lib/platform/linux/bh_platform.h +++ b/core/shared-lib/platform/linux/bh_platform.h @@ -26,11 +26,16 @@ #include #include #include -#include - -#ifndef __cplusplus -int snprintf(char *buffer, size_t count, const char *format, ...); -#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -47,46 +52,19 @@ extern void DEBUGME(void); /* NEED qsort */ -#include -#include -#include -#include -#include -#include -#include -#include - #define _STACK_SIZE_ADJUSTMENT (32 * 1024) -/* Stack size of applet manager thread. */ -#define BH_APPLET_MANAGER_THREAD_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT) - -/* Stack size of HMC thread. */ -#define BH_HMC_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) - -/* Stack size of watchdog thread. */ -#define BH_WATCHDOG_THREAD_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) - /* Stack size of applet threads's native part. */ #define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT) -/* Stack size of remote invoke listen thread. */ -#define BH_REMOTE_INVOKE_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) - -/* Stack size of remote post listen thread. */ -#define BH_REMOTE_POST_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) - -/* Maximal recursion depth of interpreter. */ -#define BH_MAX_INTERP_RECURSION_DEPTH 8 - /* Default thread priority */ #define BH_THREAD_DEFAULT_PRIORITY 0 #define BH_ROUTINE_MODIFIER + #define BHT_TIMEDOUT ETIMEDOUT #define INVALID_THREAD_ID 0xFFffFFff -#define INVALID_SEM_ID SEM_FAILED typedef pthread_t korp_tid; typedef pthread_mutex_t korp_mutex; @@ -99,28 +77,43 @@ typedef void* (*thread_start_routine_t)(void*); #define wa_free bh_free #define wa_strdup bh_strdup +int snprintf(char *buffer, size_t count, const char *format, ...); double fmod(double x, double y); float fmodf(float x, float y); +double sqrt(double x); -/* Definitions for applet debugging */ -#define APPLET_DEBUG_LISTEN_PORT 8000 -#define BH_SOCKET_INVALID_SOCK -1 #define BH_WAIT_FOREVER 0xFFFFFFFF -typedef int bh_socket_t; #ifndef NULL # define NULL ((void*) 0) #endif +/** + * Return the offset of the given field in the given type. + * + * @param Type the type containing the filed + * @param field the field in the type + * + * @return the offset of field in Type + */ +#ifndef offsetof +#define offsetof(Type, field) ((size_t)(&((Type *)0)->field)) +#endif + #define bh_assert assert -extern int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, - unsigned int n); -extern int b_strcat_s(char * s1, size_t s1max, const char * s2); -extern int b_strcpy_s(char * s1, size_t s1max, const char * s2); -extern int fopen_s(FILE ** pFile, const char *filename, const char *mode); +int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, + unsigned int n); +int b_strcat_s(char * s1, size_t s1max, const char * s2); +int b_strcpy_s(char * s1, size_t s1max, const char * s2); -extern char *bh_strdup(const char *s); +int fopen_s(FILE ** pFile, const char *filename, const char *mode); + +char *bh_read_file_to_buffer(const char *filename, int *ret_size); + +char *bh_strdup(const char *s); + +int bh_platform_init(); #ifdef __cplusplus } diff --git a/core/shared-lib/platform/vxworks/bh_assert.c b/core/shared-lib/platform/vxworks/bh_assert.c new file mode 100644 index 00000000..b52a9aa5 --- /dev/null +++ b/core/shared-lib/platform/vxworks/bh_assert.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_platform.h" +#include "bh_assert.h" +#include +#include +#include + +#ifdef BH_TEST +#include +#endif + +#ifdef BH_TEST +/* for exception throwing */ +jmp_buf bh_test_jb; +#endif + +void bh_assert_internal(int v, const char *file_name, int line_number, + const char *expr_string) +{ + if (v) + return; + + if (!file_name) + file_name = "NULL FILENAME"; + if (!expr_string) + expr_string = "NULL EXPR_STRING"; + + printf("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string, + file_name, line_number); + +#ifdef BH_TEST + longjmp(bh_test_jb, 1); +#endif + + abort(); +} + +void bh_debug_internal(const char *file_name, int line_number, const char *fmt, + ...) +{ +#ifndef JEFF_TEST_VERIFIER + va_list args; + + va_start(args, fmt); + bh_assert(file_name); + + printf("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number); + vprintf(fmt, args); + + va_end(args); + printf("\n"); +#endif +} + diff --git a/core/shared-lib/platform/vxworks/bh_definition.c b/core/shared-lib/platform/vxworks/bh_definition.c new file mode 100644 index 00000000..19e10d55 --- /dev/null +++ b/core/shared-lib/platform/vxworks/bh_definition.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_definition.h" +#include "bh_platform.h" + +int bh_return(int ret) +{ + return ret; +} + +int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, unsigned int n) +{ + char *dest = (char*) s1; + char *src = (char*) s2; + if (n == 0) { + return 0; + } + + if (s1 == NULL || s1max > RSIZE_MAX) { + return -1; + } + if (s2 == NULL || n > s1max) { + memset(dest, 0, s1max); + return -1; + } + memcpy(dest, src, n); + return 0; +} + +int b_strcat_s(char * s1, size_t s1max, const char * s2) +{ + if (NULL + == s1|| NULL == s2 || s1max < (strlen(s1) + strlen(s2) + 1) || s1max > RSIZE_MAX) { + return -1; + } + + strcat(s1, s2); + + return 0; +} + +int b_strcpy_s(char * s1, size_t s1max, const char * s2) +{ + if (NULL + == s1|| NULL == s2 || s1max < (strlen(s2) + 1) || s1max > RSIZE_MAX) { + return -1; + } + + strcpy(s1, s2); + + return 0; +} diff --git a/core/iwasm/runtime/platform/linux/wasm_platform.c b/core/shared-lib/platform/vxworks/bh_platform.c similarity index 63% rename from core/iwasm/runtime/platform/linux/wasm_platform.c rename to core/shared-lib/platform/vxworks/bh_platform.c index 53600a25..98112422 100644 --- a/core/iwasm/runtime/platform/linux/wasm_platform.c +++ b/core/shared-lib/platform/vxworks/bh_platform.c @@ -14,41 +14,31 @@ * limitations under the License. */ -#include "wasm_log.h" -#include "wasm_platform.h" -#include "wasm_memory.h" - +#include "bh_platform.h" +#include +#include #include #include #include #include #include -bool is_little_endian = false; -bool __is_little_endian() +char *bh_strdup(const char *s) { - union w - { - int a; - char b; - }c; - - c.a = 1; - return (c.b == 1); + char *s1 = NULL; + if (s && (s1 = bh_malloc(strlen(s) + 1))) + memcpy(s1, s, strlen(s) + 1); + return s1; } -int -wasm_platform_init() +int bh_platform_init() { - if (__is_little_endian()) - is_little_endian = true; - return 0; } char* -wasm_read_file_to_buffer(const char *filename, int *ret_size) +bh_read_file_to_buffer(const char *filename, int *ret_size) { char *buffer; int file; @@ -56,19 +46,19 @@ wasm_read_file_to_buffer(const char *filename, int *ret_size) struct stat stat_buf; if (!filename || !ret_size) { - LOG_ERROR("Read file to buffer failed: invalid filename or ret size.\n"); + printf("Read file to buffer failed: invalid filename or ret size.\n"); return NULL; } if ((file = open(filename, O_RDONLY, 0)) == -1) { - LOG_ERROR("Read file to buffer failed: open file %s failed.\n", - filename); + printf("Read file to buffer failed: open file %s failed.\n", + filename); return NULL; } if (fstat(file, &stat_buf) != 0) { - LOG_ERROR("Read file to buffer failed: fstat file %s failed.\n", - filename); + printf("Read file to buffer failed: fstat file %s failed.\n", + filename); close(file); return NULL; } @@ -76,7 +66,7 @@ wasm_read_file_to_buffer(const char *filename, int *ret_size) file_size = stat_buf.st_size; if (!(buffer = wasm_malloc(file_size))) { - LOG_ERROR("Read file to buffer failed: alloc memory failed.\n"); + printf("Read file to buffer failed: alloc memory failed.\n"); close(file); return NULL; } @@ -85,7 +75,7 @@ wasm_read_file_to_buffer(const char *filename, int *ret_size) close(file); if (read_size < file_size) { - LOG_ERROR("Read file to buffer failed: read file content failed.\n"); + printf("Read file to buffer failed: read file content failed.\n"); wasm_free(buffer); return NULL; } diff --git a/core/shared-lib/platform/vxworks/bh_platform.h b/core/shared-lib/platform/vxworks/bh_platform.h new file mode 100644 index 00000000..142583e5 --- /dev/null +++ b/core/shared-lib/platform/vxworks/bh_platform.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _BH_PLATFORM_H +#define _BH_PLATFORM_H + +#include "bh_config.h" +#include "bh_types.h" +#include "bh_memory.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint64_t uint64; +typedef int64_t int64; + +extern void DEBUGME(void); + +#define DIE do{bh_debug("Die here\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); DEBUGME(void); while(1);}while(0) + +#define BH_PLATFORM "VxWorks" + +/* NEED qsort */ + +#define _STACK_SIZE_ADJUSTMENT (32 * 1024) + +/* Stack size of applet threads's native part. */ +#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT) + +/* Default thread priority */ +#define BH_THREAD_DEFAULT_PRIORITY 0 + +#define BH_ROUTINE_MODIFIER + +#define BHT_TIMEDOUT ETIMEDOUT + +#define INVALID_THREAD_ID 0xFFffFFff + +typedef pthread_t korp_tid; +typedef pthread_mutex_t korp_mutex; +typedef sem_t korp_sem; +typedef pthread_cond_t korp_cond; +typedef pthread_t korp_thread; +typedef void* (*thread_start_routine_t)(void*); + +#define wa_malloc bh_malloc +#define wa_free bh_free +#define wa_strdup bh_strdup + +int snprintf(char *buffer, size_t count, const char *format, ...); +double fmod(double x, double y); +float fmodf(float x, float y); +double sqrt(double x); + +#define BH_WAIT_FOREVER 0xFFFFFFFF + +#ifndef NULL +# define NULL ((void*) 0) +#endif + +/** + * Return the offset of the given field in the given type. + * + * @param Type the type containing the filed + * @param field the field in the type + * + * @return the offset of field in Type + */ +#ifndef offsetof +#define offsetof(Type, field) ((size_t)(&((Type *)0)->field)) +#endif + +#define bh_assert assert + +int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, + unsigned int n); +int b_strcat_s(char * s1, size_t s1max, const char * s2); +int b_strcpy_s(char * s1, size_t s1max, const char * s2); + +char *bh_read_file_to_buffer(const char *filename, int *ret_size); + +char *bh_strdup(const char *s); + +int bh_platform_init(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/shared-lib/platform/vxworks/bh_platform_log.c b/core/shared-lib/platform/vxworks/bh_platform_log.c new file mode 100644 index 00000000..4ff03192 --- /dev/null +++ b/core/shared-lib/platform/vxworks/bh_platform_log.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_platform.h" +#include + +void bh_log_emit(const char *fmt, va_list ap) +{ + vprintf(fmt, ap); + fflush(stdout); +} + +int bh_fprintf(FILE *stream, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = vfprintf(stream ? stream : stdout, fmt, ap); + va_end(ap); + + return ret; +} + +int bh_fflush(void *stream) +{ + return fflush(stream ? stream : stdout); +} diff --git a/core/shared-lib/platform/vxworks/bh_thread.c b/core/shared-lib/platform/vxworks/bh_thread.c new file mode 100644 index 00000000..8883c37b --- /dev/null +++ b/core/shared-lib/platform/vxworks/bh_thread.c @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_thread.h" +#include "bh_assert.h" +#include "bh_log.h" +#include "bh_memory.h" +#include +#include +#include + +static bool is_thread_sys_inited = false; + +static korp_mutex thread_list_lock; +static pthread_key_t thread_local_storage_key[BH_MAX_TLS_NUM]; + +int _vm_thread_sys_init() +{ + unsigned i, j; + int ret; + + if (is_thread_sys_inited) + return 0; + + for (i = 0; i < BH_MAX_TLS_NUM; i++) { + ret = pthread_key_create(&thread_local_storage_key[i], NULL); + if (ret) + goto fail; + } + + ret = vm_mutex_init(&thread_list_lock); + if (ret) + goto fail; + + is_thread_sys_inited = true; + return 0; + + fail: for (j = 0; j < i; j++) + pthread_key_delete(thread_local_storage_key[j]); + return -1; +} + +void vm_thread_sys_destroy(void) +{ + if (is_thread_sys_inited) { + unsigned i; + for (i = 0; i < BH_MAX_TLS_NUM; i++) + pthread_key_delete(thread_local_storage_key[i]); + vm_mutex_destroy(&thread_list_lock); + is_thread_sys_inited = false; + } +} + +typedef struct { + thread_start_routine_t start; + void* stack; + int stack_size; + void* arg; +} thread_wrapper_arg; + +static void *vm_thread_wrapper(void *arg) +{ + thread_wrapper_arg * targ = arg; + LOG_VERBOSE("THREAD CREATE 0x%08x\n", &targ); + targ->stack = (void *)((uintptr_t)(&arg) & ~0xfff); + _vm_tls_put(1, targ); + targ->start(targ->arg); + bh_free(targ); + _vm_tls_put(1, NULL); + return NULL; +} + +int _vm_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start, + void *arg, unsigned int stack_size, int prio) +{ + pthread_attr_t tattr; + thread_wrapper_arg *targ; + + bh_assert(stack_size > 0); + bh_assert(tid); + bh_assert(start); + + *tid = INVALID_THREAD_ID; + + pthread_attr_init(&tattr); + pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE); + if (pthread_attr_setstacksize(&tattr, stack_size) != 0) { + bh_debug("Invalid thread stack size %u. Min stack size on Linux = %u", + stack_size, PTHREAD_STACK_MIN); + pthread_attr_destroy(&tattr); + return BHT_ERROR; + } + + targ = (thread_wrapper_arg*) bh_malloc(sizeof(*targ)); + if (!targ) { + pthread_attr_destroy(&tattr); + return BHT_ERROR; + } + + targ->start = start; + targ->arg = arg; + targ->stack_size = stack_size; + + if (pthread_create(tid, &tattr, vm_thread_wrapper, targ) != 0) { + pthread_attr_destroy(&tattr); + bh_free(targ); + return BHT_ERROR; + } + + pthread_attr_destroy(&tattr); + return BHT_OK; +} + +int _vm_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg, + unsigned int stack_size) +{ + return _vm_thread_create_with_prio(tid, start, arg, stack_size, + BH_THREAD_DEFAULT_PRIORITY); +} + +korp_tid _vm_self_thread() +{ + return (korp_tid) pthread_self(); +} + +void vm_thread_exit(void * code) +{ + bh_free(_vm_tls_get(1)); + _vm_tls_put(1, NULL); + pthread_exit(code); +} + +void *_vm_tls_get(unsigned idx) +{ + bh_assert(idx < BH_MAX_TLS_NUM); + return pthread_getspecific(thread_local_storage_key[idx]); +} + +int _vm_tls_put(unsigned idx, void * tls) +{ + bh_assert(idx < BH_MAX_TLS_NUM); + pthread_setspecific(thread_local_storage_key[idx], tls); + return BHT_OK; +} + +int _vm_mutex_init(korp_mutex *mutex) +{ + return pthread_mutex_init(mutex, NULL) == 0 ? BHT_OK : BHT_ERROR; +} + +int _vm_recursive_mutex_init(korp_mutex *mutex) +{ + int ret; + + pthread_mutexattr_t mattr; + + bh_assert(mutex); + ret = pthread_mutexattr_init(&mattr); + if (ret) + return BHT_ERROR; + + pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE); + ret = pthread_mutex_init(mutex, &mattr); + pthread_mutexattr_destroy(&mattr); + + return ret == 0 ? BHT_OK : BHT_ERROR; +} + +int _vm_mutex_destroy(korp_mutex *mutex) +{ + int ret; + + bh_assert(mutex); + ret = pthread_mutex_destroy(mutex); + + return ret == 0 ? BHT_OK : BHT_ERROR; +} + +/* Returned error (EINVAL, EAGAIN and EDEADLK) from + locking the mutex indicates some logic error present in + the program somewhere. + Don't try to recover error for an existing unknown error.*/ +void vm_mutex_lock(korp_mutex *mutex) +{ + int ret; + + bh_assert(mutex); + ret = pthread_mutex_lock(mutex); + if (0 != ret) { + printf("vm mutex lock failed (ret=%d)!\n", ret); + exit(-1); + } +} + +int vm_mutex_trylock(korp_mutex *mutex) +{ + int ret; + + bh_assert(mutex); + ret = pthread_mutex_trylock(mutex); + + return ret == 0 ? BHT_OK : BHT_ERROR; +} + +/* Returned error (EINVAL, EAGAIN and EPERM) from + unlocking the mutex indicates some logic error present + in the program somewhere. + Don't try to recover error for an existing unknown error.*/ +void vm_mutex_unlock(korp_mutex *mutex) +{ + int ret; + + bh_assert(mutex); + ret = pthread_mutex_unlock(mutex); + if (0 != ret) { + printf("vm mutex unlock failed (ret=%d)!\n", ret); + exit(-1); + } +} + +int _vm_sem_init(korp_sem* sem, unsigned int c) +{ + int ret; + + bh_assert(sem); + ret = sem_init(sem, 0, c); + + return ret == 0 ? BHT_OK : BHT_ERROR; +} + +int _vm_sem_destroy(korp_sem *sem) +{ + int ret; + + bh_assert(sem); + ret = sem_destroy(sem); + + return ret == 0 ? BHT_OK : BHT_ERROR; +} + +int _vm_sem_wait(korp_sem *sem) +{ + int ret; + + bh_assert(sem); + + ret = sem_wait(sem); + + return ret == 0 ? BHT_OK : BHT_ERROR; +} + +int _vm_sem_reltimedwait(korp_sem *sem, int mills) +{ + int ret = BHT_OK; + + struct timespec timeout; + const int mills_per_sec = 1000; + const int mills_to_nsec = 1E6; + + bh_assert(sem); + + if (mills == BHT_WAIT_FOREVER) { + ret = sem_wait(sem); + } else { + + timeout.tv_sec = mills / mills_per_sec; + timeout.tv_nsec = (mills % mills_per_sec) * mills_to_nsec; + timeout.tv_sec += time(NULL); + + ret = sem_timedwait(sem, &timeout); + } + + if (ret != BHT_OK) { + if (errno == BHT_TIMEDOUT) { + ret = BHT_TIMEDOUT; + errno = 0; + } else { + bh_debug("Faliure happens when timed wait is called"); + bh_assert(0); + } + } + + return ret; +} + +int _vm_sem_post(korp_sem *sem) +{ + bh_assert(sem); + + return sem_post(sem) == 0 ? BHT_OK : BHT_ERROR; +} + +int _vm_cond_init(korp_cond *cond) +{ + bh_assert(cond); + + if (pthread_cond_init(cond, NULL) != BHT_OK) + return BHT_ERROR; + + return BHT_OK; +} + +int _vm_cond_destroy(korp_cond *cond) +{ + bh_assert(cond); + + if (pthread_cond_destroy(cond) != BHT_OK) + return BHT_ERROR; + + return BHT_OK; +} + +int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex) +{ + bh_assert(cond); + bh_assert(mutex); + + if (pthread_cond_wait(cond, mutex) != BHT_OK) + return BHT_ERROR; + + return BHT_OK; +} + +static void msec_nsec_to_abstime(struct timespec *ts, int64 msec, int32 nsec) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + ts->tv_sec = tv.tv_sec + msec / 1000; + ts->tv_nsec = tv.tv_usec * 1000 + (msec % 1000) * 1000000 + nsec; + + if (ts->tv_nsec >= 1000000000L) { + ts->tv_sec++; + ts->tv_nsec -= 1000000000L; + } +} + +int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills) +{ + int ret; + struct timespec abstime; + + if (mills == BHT_WAIT_FOREVER) + ret = pthread_cond_wait(cond, mutex); + else { + msec_nsec_to_abstime(&abstime, mills, 0); + ret = pthread_cond_timedwait(cond, mutex, &abstime); + } + + if (ret != BHT_OK && ret != BHT_TIMEDOUT) + return BHT_ERROR; + + return BHT_OK; +} + +int _vm_cond_signal(korp_cond *cond) +{ + bh_assert(cond); + + if (pthread_cond_signal(cond) != BHT_OK) + return BHT_ERROR; + + return BHT_OK; +} + +int _vm_cond_broadcast(korp_cond *cond) +{ + bh_assert(cond); + + if (pthread_cond_broadcast(cond) != BHT_OK) + return BHT_ERROR; + + return BHT_OK; +} + +int _vm_thread_cancel(korp_tid thread) +{ + return pthread_cancel(thread); +} + +int _vm_thread_join(korp_tid thread, void **value_ptr, int mills) +{ + return pthread_join(thread, value_ptr); +} + +int _vm_thread_detach(korp_tid thread) +{ + return pthread_detach(thread); +} + diff --git a/core/shared-lib/platform/vxworks/bh_time.c b/core/shared-lib/platform/vxworks/bh_time.c new file mode 100644 index 00000000..4cae3588 --- /dev/null +++ b/core/shared-lib/platform/vxworks/bh_time.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "bh_time.h" + +#include +#include +#include + +/* + * This function returns milliseconds per tick. + * @return milliseconds per tick. + */ +uint64 _bh_time_get_tick_millisecond() +{ + return sysconf(_SC_CLK_TCK); +} + +/* + * This function returns milliseconds after boot. + * @return milliseconds after boot. + */ +uint64 _bh_time_get_boot_millisecond() +{ + struct timespec ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { + return 0; + } + + return ((uint64) ts.tv_sec) * 1000 + ts.tv_nsec / (1000 * 1000); +} + +uint32 bh_get_tick_sec() +{ + return _bh_time_get_boot_millisecond() / 1000; +} + +/* + * This function returns GMT time milliseconds since from 1970.1.1, AKA UNIX time. + * @return milliseconds since from 1970.1.1. + */ +uint64 _bh_time_get_millisecond_from_1970() +{ + struct timespec ts; + + if (clock_gettime(CLOCK_REALTIME, &ts) != 0) { + return 0; + } + + return ((uint64) ts.tv_sec) * 1000 + ts.tv_nsec / (1000 * 1000); +} + +size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time) +{ + time_t time_sec = time / 1000; + struct tm *ltp; + + ltp = localtime(&time_sec); + if (ltp == NULL) { + return 0; + } + return strftime(s, max, format, ltp); +} + diff --git a/core/shared-lib/platform/vxworks/shared_platform.cmake b/core/shared-lib/platform/vxworks/shared_platform.cmake new file mode 100644 index 00000000..5b403a09 --- /dev/null +++ b/core/shared-lib/platform/vxworks/shared_platform.cmake @@ -0,0 +1,24 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR}) + +include_directories(${PLATFORM_SHARED_DIR}) +include_directories(${PLATFORM_SHARED_DIR}/../include) + + +file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c) + +set (PLATFORM_SHARED_SOURCE ${source_all}) + diff --git a/core/iwasm/runtime/platform/zephyr/COPYRIGHT b/core/shared-lib/platform/zephyr/COPYRIGHT similarity index 100% rename from core/iwasm/runtime/platform/zephyr/COPYRIGHT rename to core/shared-lib/platform/zephyr/COPYRIGHT diff --git a/core/iwasm/runtime/platform/zephyr/wasm_math.c b/core/shared-lib/platform/zephyr/bh_math.c similarity index 91% rename from core/iwasm/runtime/platform/zephyr/wasm_math.c rename to core/shared-lib/platform/zephyr/bh_math.c index ebea5c49..a2794704 100644 --- a/core/iwasm/runtime/platform/zephyr/wasm_math.c +++ b/core/shared-lib/platform/zephyr/bh_math.c @@ -28,10 +28,7 @@ * $FreeBSD$ */ -#include "wasm_log.h" -#include "wasm_platform.h" -#include "wasm_platform_log.h" -#include "wasm_memory.h" +#include "bh_platform.h" #define __FDLIBM_STDC__ @@ -99,6 +96,13 @@ typedef union { } bits; } IEEEd2bits_B; +static union { + int a; + char b; +} __ue = { .a = 1 }; + +#define is_little_endian() (__ue.b == 1) + #define __HIL(x) *(1+pdouble2pint(&x)) #define __LOL(x) *(pdouble2pint(&x)) #define __HIB(x) *(int*)&x @@ -179,39 +183,39 @@ typedef union { } while (0) /* Macro wrappers. */ -#define EXTRACT_WORDS(ix0,ix1,d) do { \ - if (is_little_endian) \ - EXTRACT_WORDS_L(ix0,ix1,d); \ - else \ - EXTRACT_WORDS_B(ix0,ix1,d); \ +#define EXTRACT_WORDS(ix0,ix1,d) do { \ + if (is_little_endian()) \ + EXTRACT_WORDS_L(ix0,ix1,d); \ + else \ + EXTRACT_WORDS_B(ix0,ix1,d); \ } while (0) -#define INSERT_WORDS(d,ix0,ix1) do { \ - if (is_little_endian) \ - INSERT_WORDS_L(d,ix0,ix1); \ - else \ - INSERT_WORDS_B(d,ix0,ix1); \ +#define INSERT_WORDS(d,ix0,ix1) do { \ + if (is_little_endian()) \ + INSERT_WORDS_L(d,ix0,ix1); \ + else \ + INSERT_WORDS_B(d,ix0,ix1); \ } while (0) -#define GET_HIGH_WORD(i,d) \ - do { \ - if (is_little_endian) \ - GET_HIGH_WORD_L(i,d); \ - else \ - GET_HIGH_WORD_B(i,d); \ - } while (0) +#define GET_HIGH_WORD(i,d) \ + do { \ + if (is_little_endian()) \ + GET_HIGH_WORD_L(i,d); \ + else \ + GET_HIGH_WORD_B(i,d); \ + } while (0) -#define SET_HIGH_WORD(d,v) \ - do { \ - if (is_little_endian) \ - SET_HIGH_WORD_L(d,v); \ - else \ - SET_HIGH_WORD_B(d,v); \ - } while (0) +#define SET_HIGH_WORD(d,v) \ + do { \ + if (is_little_endian()) \ + SET_HIGH_WORD_L(d,v); \ + else \ + SET_HIGH_WORD_B(d,v); \ + } while (0) -#define __HI(x) (is_little_endian ? __HIL(x) : __HIB(x)) +#define __HI(x) (is_little_endian() ? __HIL(x) : __HIB(x)) -#define __LO(x) (is_little_endian ? __LOL(x) : __LOB(x)) +#define __LO(x) (is_little_endian() ? __LOL(x) : __LOB(x)) /* * Attempt to get strict C99 semantics for assignment with non-C99 compilers. @@ -509,7 +513,7 @@ static double freebsd_rint(double x) static int freebsd_isnan(double d) { - if (is_little_endian) { + if (is_little_endian()) { IEEEd2bits_L u; u.d = d; return (u.bits.exp == 2047 && (u.bits.manl != 0 || u.bits.manh != 0)); diff --git a/core/shared-lib/platform/zephyr/bh_platform.c b/core/shared-lib/platform/zephyr/bh_platform.c index fe05e8bd..7c4263b3 100755 --- a/core/shared-lib/platform/zephyr/bh_platform.c +++ b/core/shared-lib/platform/zephyr/bh_platform.c @@ -25,3 +25,25 @@ char *bh_strdup(const char *s) memcpy(s1, s, strlen(s) + 1); return s1; } + +#ifndef CONFIG_AEE_ENABLE +static int +_stdout_hook_iwasm(int c) +{ + printk("%c", (char)c); + return 1; +} + +int bh_platform_init() +{ + extern void __stdout_hook_install(int (*hook)(int)); + /* Enable printf() in Zephyr */ + __stdout_hook_install(_stdout_hook_iwasm); + return 0; +} +#else +int bh_platform_init() +{ + return 0; +} +#endif diff --git a/core/shared-lib/platform/zephyr/bh_platform.h b/core/shared-lib/platform/zephyr/bh_platform.h index 4e22d904..2602bee3 100644 --- a/core/shared-lib/platform/zephyr/bh_platform.h +++ b/core/shared-lib/platform/zephyr/bh_platform.h @@ -52,7 +52,6 @@ /* Invalid thread tid */ #define INVALID_THREAD_ID NULL -#define INVALID_SEM_ID SEM_FAILED #define BH_WAIT_FOREVER K_FOREVER typedef uint64_t uint64; @@ -89,6 +88,18 @@ int snprintf(char *buffer, size_t count, const char *format, ...); #define NULL ((void*)0) #endif +/** + * Return the offset of the given field in the given type. + * + * @param Type the type containing the filed + * @param field the field in the type + * + * @return the offset of field in Type + */ +#ifndef offsetof +#define offsetof(Type, field) ((size_t)(&((Type *)0)->field)) +#endif + #define bh_assert(x) \ do { \ if (!(x)) { \ @@ -96,9 +107,23 @@ int snprintf(char *buffer, size_t count, const char *format, ...); } \ } while (0) -extern int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, - unsigned int n); -extern int b_strcat_s(char * s1, size_t s1max, const char * s2); -extern int b_strcpy_s(char * s1, size_t s1max, const char * s2); +int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, + unsigned int n); +int b_strcat_s(char * s1, size_t s1max, const char * s2); +int b_strcpy_s(char * s1, size_t s1max, const char * s2); + +/* math functions */ +double sqrt(double x); +double floor(double x); +double ceil(double x); +double fmin(double x, double y); +double fmax(double x, double y); +double rint(double x); +double fabs(double x); +double trunc(double x); +int signbit(double x); +int isnan(double x); + +int bh_platform_init(); #endif diff --git a/samples/gui/README.md b/samples/gui/README.md new file mode 100644 index 00000000..3bfd18dd --- /dev/null +++ b/samples/gui/README.md @@ -0,0 +1,119 @@ +Introduction +============== +This sample demonstrates that a graphic user interface application in WebAssembly programming with WAMR graphic library(WGL) extension. WGL is implemented based on LittlevGL, an open-source embedded 2d graphic library. LittlevGL source code is built into the WAMR runtime and exported to Webassembly application with WGL extension. These extension API's are listed in: `/core/iwasm/lib/app-libs/extension/gui/wgl.h`. Currently only a small set of API's are provided and that would be extended in future. + +The runtime component supports building target for Linux and Zephyr/STM Nucleo board. The beauty of this sample is the WebAssembly application can have identical display and behavior when running from both runtime environments. That implies we can do majority of application validation from desktop environment as long as two runtime distributions support the same set of application interface. + +The sample also provides the native Linux version of application without the runtime under folder "lvgl-native-ui-app". It can help to check differences between the implementations in native and WebAssembly. + + + + +The number on top will plus one each second, and the number on the bottom will plus one when clicked. + +Configure 32 bit or 64 bit build +============== +On 64 bit operating system, there is an option to build 32 bit or 64 bit binaries. In file `./lvgl-native-ui-app/CMakeLists.txt` and/or `./wasm-runtime-wgl/linux-build/CMakeLists.txt` , modify the line: +`set (BUILD_AS_64BIT_SUPPORT "YES")` + where `YES` means 64 bit build while `NO` means 32 bit build. + +Install required SDK and libraries +============== +- 32 bit SDL(simple directmedia layer) (Note: only necessary when `BUILD_AS_64BIT_SUPPORT` is set to `NO`) +Use apt-get: + `sudo apt-get install libsdl2-dev:i386` +Or download source from www.libsdl.org: +``` +./configure C_FLAGS=-m32 CXX_FLAGS=-m32 LD_FLAGS=-m32 +make +sudo make install +``` +- 64 bit SDL(simple directmedia layer) (Note: only necessary when `BUILD_AS_64BIT_SUPPORT` is set to `YES`) +Use apt-get: + `sudo apt-get install libsdl2-dev` +Or download source from www.libsdl.org: +``` +./configure +make +sudo make install +``` + +- Install EMSDK +``` + https://emscripten.org/docs/tools_reference/emsdk.html +``` + +Build and Run +============== + +Linux +-------------------------------- +- Build
+`./build.sh`
+ All binaries are in "out", which contains "host_tool", "lvgl_native_ui_app", "ui_app.wasm", "ui_app_lvgl_compatible" and "wasm_runtime_wgl". +- Run native Linux application
+`./lvgl_native_ui_app`
+ +- Run WASM VM Linux applicaton & install WASM APP
+ First start wasm_runtime_wgl in server mode.
+`./wasm_runtime_wgl -s`
+ Then install wasm APP use host tool.
+`./host_tool -i ui_app -f ui_app.wasm`
+`./host_tool -i ui_app -f ui_app_compatible.wasm`
+ +Zephyr +-------------------------------- +WASM VM and native extension method can be built into Zephyr, Then we can install wasm app into STM32.
+- Build WASM VM into Zephyr system
+ a. clone zephyr source code
+Refer to Zephyr getting started.
+https://docs.zephyrproject.org/latest/getting_started/index.html
+`west init zephyrproject`
+`cd zephyrproject`
+`west update`
+ b. copy samples
+ `cd zephyr/samples/`
+ `cp -a samples/gui/wasm-runtime-wgl wasm-runtime-wgl`
+ `cd wasm-runtime-wgl/zephyr_build`
+ c. create a link to wamr core
+ ` ln -s /core core`
+ d. build source code
+ `mkdir build && cd build`
+ `source ../../../../zephyr-env.sh`
+ `cmake -GNinja -DBOARD=nucleo_f746zg ..`
+ ` ninja flash`
+ +- Test on STM32 NUCLEO_F767ZI with ILI9341 Display with XPT2046 touch
+Hardware Connections + +``` ++-------------------+-+------------------+ +|NUCLEO-F767ZI | ILI9341 Display | ++-------------------+-+------------------+ +| CN7.10 | CLK | ++-------------------+-+------------------+ +| CN7.12 | MISO | ++-------------------+-+------------------+ +| CN7.14 | MOSI | ++-------------------+-+------------------+ +| CN11.1 | CS1 for ILI9341 | ++-------------------+-+------------------+ +| CN11.2 | D/C | ++-------------------+-+------------------+ +| CN11.3 | RESET | ++-------------------+-+------------------+ +| CN9.25 | PEN interrupt | ++-------------------+-+------------------+ +| CN9.27 | CS2 for XPT2046 | ++-------------------+-+------------------+ +| CN10.14 | PC UART RX | ++-------------------+-+------------------+ +| CN11.16 | PC UART RX | ++-------------------+-+------------------+ +``` + + +- Install WASM application to Zephyr using host_tool
+First, connect PC and STM32 with UART. Then install to use host_tool.
+`./host_tool -D /dev/ttyUSBXXX -i ui_app -f ui_app.wasm` + diff --git a/samples/gui/build.sh b/samples/gui/build.sh new file mode 100755 index 00000000..a88987ad --- /dev/null +++ b/samples/gui/build.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +PROJECT_DIR=$PWD +WAMR_DIR=${PWD}/../.. +OUT_DIR=${PWD}/out +BUILD_DIR=${PWD}/build + +if [ ! -d $BUILD_DIR ]; then + mkdir ${BUILD_DIR} +fi + +rm -rf ${OUT_DIR} +mkdir ${OUT_DIR} + + +cd ${WAMR_DIR}/core/shared-lib/mem-alloc +if [ ! -d "tlsf" ]; then + git clone https://github.com/mattconte/tlsf +fi + +cd ${WAMR_DIR}/core/iwasm/lib/3rdparty +if [ ! -d "lvgl" ]; then + git clone https://github.com/littlevgl/lvgl.git --branch v6.0.1 +fi +if [ ! -d "lv_drivers" ]; then + git clone https://github.com/littlevgl/lv_drivers.git +fi + +echo "##################### 1. build native-ui-app start#####################" +cd $BUILD_DIR +mkdir -p lvgl-native-ui-app +cd lvgl-native-ui-app +cmake ${PROJECT_DIR}/lvgl-native-ui-app +make +if [ $? != 0 ];then + echo "BUILD_FAIL native-ui-app $?\n" + exit 2 +fi +echo $PWD +cp lvgl_native_ui_app ${OUT_DIR} +echo "#####################build native-ui-app success" + + +echo "##################### 2. build littlevgl wasm runtime start#####################" +cd $BUILD_DIR +mkdir -p wasm-runtime-wgl +cd wasm-runtime-wgl +cmake ${PROJECT_DIR}/wasm-runtime-wgl/linux-build +make +cp wasm_runtime_wgl ${OUT_DIR}/ + +echo "##################### build littlevgl wasm runtime end#####################" + +echo "#####################build host-tool" +cd $BUILD_DIR +mkdir -p host-tool +cd host-tool +cmake ${WAMR_DIR}/test-tools/host-tool +make +if [ $? != 0 ];then + echo "BUILD_FAIL host tool exit as $?\n" + exit 2 +fi +cp host_tool ${OUT_DIR} +echo "#####################build host-tool success" + + +echo "##################### 3. build wasm ui app start#####################" +cd ${PROJECT_DIR}/wasm-apps/wgl +make +cp ui_app.wasm ${OUT_DIR}/ +cd ${PROJECT_DIR}/wasm-apps/lvgl-compatible +make +cp ui_app_lvgl_compatible.wasm ${OUT_DIR}/ +echo "##################### build wasm ui app end#####################" diff --git a/samples/gui/lvgl-native-ui-app/CMakeLists.txt b/samples/gui/lvgl-native-ui-app/CMakeLists.txt new file mode 100644 index 00000000..95550afc --- /dev/null +++ b/samples/gui/lvgl-native-ui-app/CMakeLists.txt @@ -0,0 +1,52 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required (VERSION 2.8.2) +message ("lvgl_native_ui_app...") +project (lvgl_native_ui_app) + +################################################################# + +# Currently build as 64-bit by default. Set to "NO" to build 32-bit binaries. +set (BUILD_AS_64BIT_SUPPORT "YES") + +if (CMAKE_SIZEOF_VOID_P EQUAL 8) + if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES") + # Add -fPIC flag if build as 64-bit + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC") + else () + add_definitions (-m32) + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") + set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32") + endif () +endif () + +set(THIRDPARTY_DIR ../../../core/iwasm/lib/3rdparty) +set(LVGL_SOURCE_DIR ${THIRDPARTY_DIR}/lvgl) +set(LVGL_DRIVER_DIR ${THIRDPARTY_DIR}/lv_drivers) + +################################# + +INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}) +INCLUDE_DIRECTORIES(${THIRDPARTY_DIR}) + +add_definitions (-DLV_CONF_INCLUDE_SIMPLE) + +file(GLOB_RECURSE INCLUDES "${LVGL_DRIVER_DIR}/*.h" "${LVGL_SOURCE_DIR}/*.h" "./*.h" ) +file(GLOB_RECURSE SOURCES "${LVGL_DRIVER_DIR}/*.c" "${LVGL_SOURCE_DIR}/*.c" ) + +add_executable(lvgl_native_ui_app main.c get_time.c ${SOURCES} ${INCLUDES}) +target_link_libraries(lvgl_native_ui_app PRIVATE SDL2 ) + diff --git a/samples/gui/lvgl-native-ui-app/LICENCE.txt b/samples/gui/lvgl-native-ui-app/LICENCE.txt new file mode 100644 index 00000000..beaef1d2 --- /dev/null +++ b/samples/gui/lvgl-native-ui-app/LICENCE.txt @@ -0,0 +1,8 @@ +MIT licence +Copyright (c) 2016 Gábor Kiss-Vámosi + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/samples/gui/lvgl-native-ui-app/get_time.c b/samples/gui/lvgl-native-ui-app/get_time.c new file mode 100644 index 00000000..756191a6 --- /dev/null +++ b/samples/gui/lvgl-native-ui-app/get_time.c @@ -0,0 +1,11 @@ +#include +#include "system_header.h" + +int time_get_ms() +{ + static struct timeval tv; + gettimeofday(&tv, NULL); + long long time_in_mill = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000; + + return (int) time_in_mill; +} diff --git a/samples/gui/lvgl-native-ui-app/lv_conf.h b/samples/gui/lvgl-native-ui-app/lv_conf.h new file mode 100644 index 00000000..e2996121 --- /dev/null +++ b/samples/gui/lvgl-native-ui-app/lv_conf.h @@ -0,0 +1,495 @@ +/** + * @file lv_conf.h + * + */ + +/* + * COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER + */ + +#if 1 /*Set it to "1" to enable content*/ + +#ifndef LV_CONF_H +#define LV_CONF_H +/* clang-format off */ + +#include + +/*==================== + Graphical settings + *====================*/ + +/* Maximal horizontal and vertical resolution to support by the library.*/ +#define LV_HOR_RES_MAX (320) +#define LV_VER_RES_MAX (240) + +/* Color depth: + * - 1: 1 byte per pixel + * - 8: RGB233 + * - 16: RGB565 + * - 32: ARGB8888 + */ +#define LV_COLOR_DEPTH 32 + +/* Swap the 2 bytes of RGB565 color. + * Useful if the display has a 8 bit interface (e.g. SPI)*/ +#define LV_COLOR_16_SWAP 0 + +/* 1: Enable screen transparency. + * Useful for OSD or other overlapping GUIs. + * Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/ +#define LV_COLOR_SCREEN_TRANSP 0 + +/*Images pixels with this color will not be drawn (with chroma keying)*/ +#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/ + +/* Enable anti-aliasing (lines, and radiuses will be smoothed) */ +#define LV_ANTIALIAS 1 + +/* Default display refresh period. + * Can be changed in the display driver (`lv_disp_drv_t`).*/ +#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/ + +/* Dot Per Inch: used to initialize default sizes. + * E.g. a button with width = LV_DPI / 2 -> half inch wide + * (Not so important, you can adjust it to modify default sizes and spaces)*/ +#define LV_DPI 100 /*[px]*/ + +/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */ +typedef int16_t lv_coord_t; + +/*========================= + Memory manager settings + *=========================*/ + +/* LittelvGL's internal memory manager's settings. + * The graphical objects and other related data are stored here. */ + +/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */ +#define LV_MEM_CUSTOM 0 +#if LV_MEM_CUSTOM == 0 +/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/ +# define LV_MEM_SIZE (128U * 1024U) + +/* Complier prefix for a big array declaration */ +# define LV_MEM_ATTR + +/* Set an address for the memory pool instead of allocating it as an array. + * Can be in external SRAM too. */ +# define LV_MEM_ADR 0 + +/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */ +# define LV_MEM_AUTO_DEFRAG 1 +#else /*LV_MEM_CUSTOM*/ +# define LV_MEM_CUSTOM_INCLUDE /*Header for the dynamic memory function*/ +# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/ +# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/ +#endif /*LV_MEM_CUSTOM*/ + +/* Garbage Collector settings + * Used if lvgl is binded to higher level language and the memory is managed by that language */ +#define LV_ENABLE_GC 0 +#if LV_ENABLE_GC != 0 +# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/ +# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/ +# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/ +#endif /* LV_ENABLE_GC */ + +/*======================= + Input device settings + *=======================*/ + +/* Input device default settings. + * Can be changed in the Input device driver (`lv_indev_drv_t`)*/ + +/* Input device read period in milliseconds */ +#define LV_INDEV_DEF_READ_PERIOD 30 + +/* Drag threshold in pixels */ +#define LV_INDEV_DEF_DRAG_LIMIT 10 + +/* Drag throw slow-down in [%]. Greater value -> faster slow-down */ +#define LV_INDEV_DEF_DRAG_THROW 20 + +/* Long press time in milliseconds. + * Time to send `LV_EVENT_LONG_PRESSSED`) */ +#define LV_INDEV_DEF_LONG_PRESS_TIME 400 + +/* Repeated trigger period in long press [ms] + * Time between `LV_EVENT_LONG_PRESSED_REPEAT */ +#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100 + +/*================== + * Feature usage + *==================*/ + +/*1: Enable the Animations */ +#define LV_USE_ANIMATION 1 +#if LV_USE_ANIMATION + +/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_anim_user_data_t; + +#endif + +/* 1: Enable shadow drawing*/ +#define LV_USE_SHADOW 1 + +/* 1: Enable object groups (for keyboard/encoder navigation) */ +#define LV_USE_GROUP 1 +#if LV_USE_GROUP +typedef void * lv_group_user_data_t; +#endif /*LV_USE_GROUP*/ + +/* 1: Enable GPU interface*/ +#define LV_USE_GPU 1 + +/* 1: Enable file system (might be required for images */ +#define LV_USE_FILESYSTEM 1 +#if LV_USE_FILESYSTEM +/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_fs_drv_user_data_t; +#endif + +/*1: Add a `user_data` to drivers and objects*/ +#define LV_USE_USER_DATA 1 + +/*======================== + * Image decoder and cache + *========================*/ + +/* 1: Enable indexed (palette) images */ +#define LV_IMG_CF_INDEXED 1 + +/* 1: Enable alpha indexed images */ +#define LV_IMG_CF_ALPHA 1 + +/* Default image cache size. Image caching keeps the images opened. + * If only the built-in image formats are used there is no real advantage of caching. + * (I.e. no new image decoder is added) + * With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images. + * However the opened images might consume additional RAM. + * LV_IMG_CACHE_DEF_SIZE must be >= 1 */ +#define LV_IMG_CACHE_DEF_SIZE 1 + +/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_img_decoder_user_data_t; + +/*===================== + * Compiler settings + *====================*/ +/* Define a custom attribute to `lv_tick_inc` function */ +#define LV_ATTRIBUTE_TICK_INC + +/* Define a custom attribute to `lv_task_handler` function */ +#define LV_ATTRIBUTE_TASK_HANDLER + +/* With size optimization (-Os) the compiler might not align data to + * 4 or 8 byte boundary. This alignment will be explicitly applied where needed. + * E.g. __attribute__((aligned(4))) */ +#define LV_ATTRIBUTE_MEM_ALIGN + +/* Attribute to mark large constant arrays for example + * font's bitmaps */ +#define LV_ATTRIBUTE_LARGE_CONST + +/*=================== + * HAL settings + *==================*/ + +/* 1: use a custom tick source. + * It removes the need to manually update the tick with `lv_tick_inc`) */ +#define LV_TICK_CUSTOM 1 +#if LV_TICK_CUSTOM == 1 +#define LV_TICK_CUSTOM_INCLUDE "system_header.h" /*Header for the sys time function*/ +#define LV_TICK_CUSTOM_SYS_TIME_EXPR (time_get_ms()) /*Expression evaluating to current systime in ms*/ +#endif /*LV_TICK_CUSTOM*/ + +typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/ +typedef void * lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/ + +/*================ + * Log settings + *===============*/ + +/*1: Enable the log module*/ +#define LV_USE_LOG 1 +#if LV_USE_LOG +/* How important log should be added: + * LV_LOG_LEVEL_TRACE A lot of logs to give detailed information + * LV_LOG_LEVEL_INFO Log important events + * LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem + * LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail + * LV_LOG_LEVEL_NONE Do not log anything + */ +# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN + +/* 1: Print the log with 'printf'; + * 0: user need to register a callback with `lv_log_register_print`*/ +# define LV_LOG_PRINTF 1 +#endif /*LV_USE_LOG*/ + +/*================ + * THEME USAGE + *================*/ +#define LV_THEME_LIVE_UPDATE 1 /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/ + +#define LV_USE_THEME_TEMPL 1 /*Just for test*/ +#define LV_USE_THEME_DEFAULT 1 /*Built mainly from the built-in styles. Consumes very few RAM*/ +#define LV_USE_THEME_ALIEN 1 /*Dark futuristic theme*/ +#define LV_USE_THEME_NIGHT 1 /*Dark elegant theme*/ +#define LV_USE_THEME_MONO 1 /*Mono color theme for monochrome displays*/ +#define LV_USE_THEME_MATERIAL 1 /*Flat theme with bold colors and light shadows*/ +#define LV_USE_THEME_ZEN 1 /*Peaceful, mainly light theme */ +#define LV_USE_THEME_NEMO 1 /*Water-like theme based on the movie "Finding Nemo"*/ + +/*================== + * FONT USAGE + *===================*/ + +/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel. + * The symbols are available via `LV_SYMBOL_...` defines + * More info about fonts: https://docs.littlevgl.com/#Fonts + * To create a new font go to: https://littlevgl.com/ttf-font-to-c-array + */ + +/* Robot fonts with bpp = 4 + * https://fonts.google.com/specimen/Roboto */ +#define LV_FONT_ROBOTO_12 1 +#define LV_FONT_ROBOTO_16 1 +#define LV_FONT_ROBOTO_22 1 +#define LV_FONT_ROBOTO_28 1 + +/*Pixel perfect monospace font + * http://pelulamu.net/unscii/ */ +#define LV_FONT_UNSCII_8 1 + +/* Optionally declare your custom fonts here. + * You can use these fonts as default font too + * and they will be available globally. E.g. + * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ + * LV_FONT_DECLARE(my_font_2) + */ +#define LV_FONT_CUSTOM_DECLARE + +/*Always set a default font from the built-in fonts*/ +#define LV_FONT_DEFAULT &lv_font_roboto_16 + +/* Enable it if you have fonts with a lot of characters. + * The limit depends on the font size, font face and bpp + * but with > 10,000 characters if you see issues probably you need to enable it.*/ +#define LV_FONT_FMT_TXT_LARGE 1 + +/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_font_user_data_t; + +/*================= + * Text settings + *=================*/ + +/* Select a character encoding for strings. + * Your IDE or editor should have the same character encoding + * - LV_TXT_ENC_UTF8 + * - LV_TXT_ENC_ASCII + * */ +#define LV_TXT_ENC LV_TXT_ENC_UTF8 + + /*Can break (wrap) texts on these chars*/ +#define LV_TXT_BREAK_CHARS " ,.;:-_" + +/*=================== + * LV_OBJ SETTINGS + *==================*/ + +/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/ +typedef void * lv_obj_user_data_t; + +/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/ +#define LV_USE_OBJ_REALIGN 1 + +/* Enable to make the object clickable on a larger area. + * LV_EXT_CLICK_AREA_OFF or 0: Disable this feature + * LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px) + * LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px) + */ +#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_FULL + +/*================== + * LV OBJ X USAGE + *================*/ +/* + * Documentation of the object types: https://docs.littlevgl.com/#Object-types + */ + +/*Arc (dependencies: -)*/ +#define LV_USE_ARC 1 + +/*Bar (dependencies: -)*/ +#define LV_USE_BAR 1 + +/*Button (dependencies: lv_cont*/ +#define LV_USE_BTN 1 +#if LV_USE_BTN != 0 +/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/ +# define LV_BTN_INK_EFFECT 1 +#endif + +/*Button matrix (dependencies: -)*/ +#define LV_USE_BTNM 1 + +/*Calendar (dependencies: -)*/ +#define LV_USE_CALENDAR 1 + +/*Canvas (dependencies: lv_img)*/ +#define LV_USE_CANVAS 1 + +/*Check box (dependencies: lv_btn, lv_label)*/ +#define LV_USE_CB 1 + +/*Chart (dependencies: -)*/ +#define LV_USE_CHART 1 +#if LV_USE_CHART +# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 20 +#endif + +/*Container (dependencies: -*/ +#define LV_USE_CONT 1 + +/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/ +#define LV_USE_DDLIST 1 +#if LV_USE_DDLIST != 0 +/*Open and close default animation time [ms] (0: no animation)*/ +# define LV_DDLIST_DEF_ANIM_TIME 200 +#endif + +/*Gauge (dependencies:lv_bar, lv_lmeter)*/ +#define LV_USE_GAUGE 1 + +/*Image (dependencies: lv_label*/ +#define LV_USE_IMG 1 + +/*Image Button (dependencies: lv_btn*/ +#define LV_USE_IMGBTN 1 +#if LV_USE_IMGBTN +/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/ +# define LV_IMGBTN_TILED 0 +#endif + +/*Keyboard (dependencies: lv_btnm)*/ +#define LV_USE_KB 1 + +/*Label (dependencies: -*/ +#define LV_USE_LABEL 1 +#if LV_USE_LABEL != 0 +/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/ +# define LV_LABEL_DEF_SCROLL_SPEED 25 + +/* Waiting period at beginning/end of animation cycle */ +# define LV_LABEL_WAIT_CHAR_COUNT 3 + +/*Enable selecting text of the label */ +# define LV_LABEL_TEXT_SEL 1 + +/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/ +# define LV_LABEL_LONG_TXT_HINT 0 +#endif + +/*LED (dependencies: -)*/ +#define LV_USE_LED 1 + +/*Line (dependencies: -*/ +#define LV_USE_LINE 1 + +/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/ +#define LV_USE_LIST 1 +#if LV_USE_LIST != 0 +/*Default animation time of focusing to a list element [ms] (0: no animation) */ +# define LV_LIST_DEF_ANIM_TIME 100 +#endif + +/*Line meter (dependencies: *;)*/ +#define LV_USE_LMETER 1 + +/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ +#define LV_USE_MBOX 1 + +/*Page (dependencies: lv_cont)*/ +#define LV_USE_PAGE 1 +#if LV_USE_PAGE != 0 +/*Focus default animation time [ms] (0: no animation)*/ +# define LV_PAGE_DEF_ANIM_TIME 400 +#endif + +/*Preload (dependencies: lv_arc, lv_anim)*/ +#define LV_USE_PRELOAD 1 +#if LV_USE_PRELOAD != 0 +# define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/ +# define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/ +# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC +#endif + +/*Roller (dependencies: lv_ddlist)*/ +#define LV_USE_ROLLER 1 +#if LV_USE_ROLLER != 0 +/*Focus animation time [ms] (0: no animation)*/ +# define LV_ROLLER_DEF_ANIM_TIME 200 + +/*Number of extra "pages" when the roller is infinite*/ +# define LV_ROLLER_INF_PAGES 7 +#endif + +/*Slider (dependencies: lv_bar)*/ +#define LV_USE_SLIDER 1 + +/*Spinbox (dependencies: lv_ta)*/ +#define LV_USE_SPINBOX 1 + +/*Switch (dependencies: lv_slider)*/ +#define LV_USE_SW 1 + +/*Text area (dependencies: lv_label, lv_page)*/ +#define LV_USE_TA 1 +#if LV_USE_TA != 0 +# define LV_TA_DEF_CURSOR_BLINK_TIME 400 /*ms*/ +# define LV_TA_DEF_PWD_SHOW_TIME 1500 /*ms*/ +#endif + +/*Table (dependencies: lv_label)*/ +#define LV_USE_TABLE 1 +#if LV_USE_TABLE +# define LV_TABLE_COL_MAX 12 +#endif + +/*Tab (dependencies: lv_page, lv_btnm)*/ +#define LV_USE_TABVIEW 1 +# if LV_USE_TABVIEW != 0 +/*Time of slide animation [ms] (0: no animation)*/ +# define LV_TABVIEW_DEF_ANIM_TIME 300 +#endif + +/*Tileview (dependencies: lv_page) */ +#define LV_USE_TILEVIEW 1 +#if LV_USE_TILEVIEW +/*Time of slide animation [ms] (0: no animation)*/ +# define LV_TILEVIEW_DEF_ANIM_TIME 300 +#endif + +/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ +#define LV_USE_WIN 1 + +/*================== + * Non-user section + *==================*/ + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/ +# define _CRT_SECURE_NO_WARNINGS +#endif + +/*--END OF LV_CONF_H--*/ + +/*Be sure every define has a default value*/ +#include "lvgl/src/lv_conf_checker.h" + +#endif /*LV_CONF_H*/ + +#endif /*End of "Content enable"*/ diff --git a/samples/gui/lvgl-native-ui-app/lv_drv_conf.h b/samples/gui/lvgl-native-ui-app/lv_drv_conf.h new file mode 100644 index 00000000..d216a3e9 --- /dev/null +++ b/samples/gui/lvgl-native-ui-app/lv_drv_conf.h @@ -0,0 +1,310 @@ +/** + * @file lv_drv_conf.h + * + */ + +/* + * COPY THIS FILE AS lv_drv_conf.h + */ + +#if 1 /*Set it to "1" to enable the content*/ + +#ifndef LV_DRV_CONF_H +#define LV_DRV_CONF_H + +#include "lv_conf.h" + +/********************* + * DELAY INTERFACE + *********************/ +#define LV_DRV_DELAY_INCLUDE /*Dummy include by default*/ +#define LV_DRV_DELAY_US(us) /*delay_us(us)*/ /*Delay the given number of microseconds*/ +#define LV_DRV_DELAY_MS(ms) /*delay_ms(ms)*/ /*Delay the given number of milliseconds*/ + +/********************* + * DISPLAY INTERFACE + *********************/ + +/*------------ + * Common + *------------*/ +#define LV_DRV_DISP_INCLUDE /*Dummy include by default*/ +#define LV_DRV_DISP_CMD_DATA(val) /*pin_x_set(val)*/ /*Set the command/data pin to 'val'*/ +#define LV_DRV_DISP_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ + +/*--------- + * SPI + *---------*/ +#define LV_DRV_DISP_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/ +#define LV_DRV_DISP_SPI_WR_BYTE(data) /*spi_wr(data)*/ /*Write a byte the SPI bus*/ +#define LV_DRV_DISP_SPI_WR_ARRAY(adr, n) /*spi_wr_mem(adr, n)*/ /*Write 'n' bytes to SPI bus from 'adr'*/ + +/*------------------ + * Parallel port + *-----------------*/ +#define LV_DRV_DISP_PAR_CS(val) /*par_cs_set(val)*/ /*Set the Parallel port's Chip select to 'val'*/ +#define LV_DRV_DISP_PAR_SLOW /*par_slow()*/ /*Set low speed on the parallel port*/ +#define LV_DRV_DISP_PAR_FAST /*par_fast()*/ /*Set high speed on the parallel port*/ +#define LV_DRV_DISP_PAR_WR_WORD(data) /*par_wr(data)*/ /*Write a word to the parallel port*/ +#define LV_DRV_DISP_PAR_WR_ARRAY(adr, n) /*par_wr_mem(adr,n)*/ /*Write 'n' bytes to Parallel ports from 'adr'*/ + +/*************************** + * INPUT DEVICE INTERFACE + ***************************/ + +/*---------- + * Common + *----------*/ +#define LV_DRV_INDEV_INCLUDE /*Dummy include by default*/ +#define LV_DRV_INDEV_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ +#define LV_DRV_INDEV_IRQ_READ 0 /*pn_x_read()*/ /*Read the IRQ pin*/ + +/*--------- + * SPI + *---------*/ +#define LV_DRV_INDEV_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/ +#define LV_DRV_INDEV_SPI_XCHG_BYTE(data) 0 /*spi_xchg(val)*/ /*Write 'val' to SPI and give the read value*/ + +/*--------- + * I2C + *---------*/ +#define LV_DRV_INDEV_I2C_START /*i2c_start()*/ /*Make an I2C start*/ +#define LV_DRV_INDEV_I2C_STOP /*i2c_stop()*/ /*Make an I2C stop*/ +#define LV_DRV_INDEV_I2C_RESTART /*i2c_restart()*/ /*Make an I2C restart*/ +#define LV_DRV_INDEV_I2C_WR(data) /*i2c_wr(data)*/ /*Write a byte to the I1C bus*/ +#define LV_DRV_INDEV_I2C_READ(last_read) 0 /*i2c_rd()*/ /*Read a byte from the I2C bud*/ + + +/********************* + * DISPLAY DRIVERS + *********************/ + +/*------------------- + * Monitor of PC + *-------------------*/ +#ifndef USE_MONITOR +# define USE_MONITOR 1 +#endif + +#if USE_MONITOR +# define MONITOR_HOR_RES LV_HOR_RES_MAX +# define MONITOR_VER_RES LV_VER_RES_MAX + +/* Scale window by this factor (useful when simulating small screens) */ +# define MONITOR_ZOOM 1 + +/* Used to test true double buffering with only address changing. + * Set LV_VDB_SIZE = (LV_HOR_RES * LV_VER_RES) and LV_VDB_DOUBLE = 1 and LV_COLOR_DEPTH = 32" */ +# define MONITOR_DOUBLE_BUFFERED 0 + +/*Eclipse: Visual Studio: */ +# define MONITOR_SDL_INCLUDE_PATH + +/*Different rendering might be used if running in a Virtual machine*/ +# define MONITOR_VIRTUAL_MACHINE 0 + +/*Open two windows to test multi display support*/ +# define MONITOR_DUAL 0 +#endif + +/*----------------------------------- + * Native Windows (including mouse) + *----------------------------------*/ +#ifndef USE_WINDOWS +# define USE_WINDOWS 0 +#endif + +#define USE_WINDOWS 0 +#if USE_WINDOWS +# define WINDOW_HOR_RES 480 +# define WINDOW_VER_RES 320 +#endif + +/*---------------- + * SSD1963 + *--------------*/ +#ifndef USE_SSD1963 +# define USE_SSD1963 0 +#endif + +#if USE_SSD1963 +# define SSD1963_HOR_RES LV_HOR_RES +# define SSD1963_VER_RES LV_VER_RES +# define SSD1963_HT 531 +# define SSD1963_HPS 43 +# define SSD1963_LPS 8 +# define SSD1963_HPW 10 +# define SSD1963_VT 288 +# define SSD1963_VPS 12 +# define SSD1963_FPS 4 +# define SSD1963_VPW 10 +# define SSD1963_HS_NEG 0 /*Negative hsync*/ +# define SSD1963_VS_NEG 0 /*Negative vsync*/ +# define SSD1963_ORI 0 /*0, 90, 180, 270*/ +# define SSD1963_COLOR_DEPTH 16 +#endif + +/*---------------- + * R61581 + *--------------*/ +#ifndef USE_R61581 +# define USE_R61581 0 +#endif + +#if USE_R61581 +# define R61581_HOR_RES LV_HOR_RES +# define R61581_VER_RES LV_VER_RES +# define R61581_HSPL 0 /*HSYNC signal polarity*/ +# define R61581_HSL 10 /*HSYNC length (Not Implemented)*/ +# define R61581_HFP 10 /*Horitontal Front poarch (Not Implemented)*/ +# define R61581_HBP 10 /*Horitontal Back poarch (Not Implemented */ +# define R61581_VSPL 0 /*VSYNC signal polarity*/ +# define R61581_VSL 10 /*VSYNC length (Not Implemented)*/ +# define R61581_VFP 8 /*Vertical Front poarch*/ +# define R61581_VBP 8 /*Vertical Back poarch */ +# define R61581_DPL 0 /*DCLK signal polarity*/ +# define R61581_EPL 1 /*ENABLE signal polarity*/ +# define R61581_ORI 0 /*0, 180*/ +# define R61581_LV_COLOR_DEPTH 16 /*Fix 16 bit*/ +#endif + +/*------------------------------ + * ST7565 (Monochrome, low res.) + *-----------------------------*/ +#ifndef USE_ST7565 +# define USE_ST7565 0 +#endif + +#if USE_ST7565 +/*No settings*/ +#endif /*USE_ST7565*/ + +/*----------------------------------------- + * Linux frame buffer device (/dev/fbx) + *-----------------------------------------*/ +#ifndef USE_FBDEV +# define USE_FBDEV 1 +#endif + +#if USE_FBDEV +# define FBDEV_PATH "/dev/fb0" +#endif + +/********************* + * INPUT DEVICES + *********************/ + +/*-------------- + * XPT2046 + *--------------*/ +#ifndef USE_XPT2046 +# define USE_XPT2046 0 +#endif + +#if USE_XPT2046 +# define XPT2046_HOR_RES 480 +# define XPT2046_VER_RES 320 +# define XPT2046_X_MIN 200 +# define XPT2046_Y_MIN 200 +# define XPT2046_X_MAX 3800 +# define XPT2046_Y_MAX 3800 +# define XPT2046_AVG 4 +# define XPT2046_INV 0 +#endif + +/*----------------- + * FT5406EE8 + *-----------------*/ +#ifndef USE_FT5406EE8 +# define USE_FT5406EE8 0 +#endif + +#if USE_FT5406EE8 +# define FT5406EE8_I2C_ADR 0x38 /*7 bit address*/ +#endif + +/*--------------- + * AD TOUCH + *--------------*/ +#ifndef USE_AD_TOUCH +# define USE_AD_TOUCH 0 +#endif + +#if USE_AD_TOUCH +/*No settings*/ +#endif + + +/*--------------------------------------- + * Mouse or touchpad on PC (using SDL) + *-------------------------------------*/ +#ifndef USE_MOUSE +# define USE_MOUSE 1 +#endif + +#if USE_MOUSE +/*No settings*/ +#endif + +/*------------------------------------------- + * Mousewheel as encoder on PC (using SDL) + *------------------------------------------*/ +#ifndef USE_MOUSEWHEEL +# define USE_MOUSEWHEEL 1 +#endif + +#if USE_MOUSEWHEEL +/*No settings*/ +#endif + +/*------------------------------------------------- + * Touchscreen as libinput interface (for Linux based systems) + *------------------------------------------------*/ +#ifndef USE_LIBINPUT +# define USE_LIBINPUT 0 +#endif + +#if USE_LIBINPUT +# define LIBINPUT_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/ +#endif /*USE_LIBINPUT*/ + +/*------------------------------------------------- + * Mouse or touchpad as evdev interface (for Linux based systems) + *------------------------------------------------*/ +#ifndef USE_EVDEV +# define USE_EVDEV 0 +#endif + +#if USE_EVDEV +# define EVDEV_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/ +# define EVDEV_SWAP_AXES 0 /*Swap the x and y axes of the touchscreen*/ + +# define EVDEV_SCALE 0 /* Scale input, e.g. if touchscreen resolution does not match display resolution */ +# if EVDEV_SCALE +# define EVDEV_SCALE_HOR_RES (4096) /* Horizontal resolution of touchscreen */ +# define EVDEV_SCALE_VER_RES (4096) /* Vertical resolution of touchscreen */ +# endif /*EVDEV_SCALE*/ + +# define EVDEV_CALIBRATE 0 /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/ +# if EVDEV_CALIBRATE +# define EVDEV_HOR_MIN 3800 /*If EVDEV_XXX_MIN > EVDEV_XXX_MAX the XXX axis is automatically inverted*/ +# define EVDEV_HOR_MAX 200 +# define EVDEV_VER_MIN 200 +# define EVDEV_VER_MAX 3800 +# endif /*EVDEV_SCALE*/ +#endif /*USE_EVDEV*/ + +/*------------------------------- + * Keyboard of a PC (using SDL) + *------------------------------*/ +#ifndef USE_KEYBOARD +# define USE_KEYBOARD 1 +#endif + +#if USE_KEYBOARD +/*No settings*/ +#endif + +#endif /*LV_DRV_CONF_H*/ + +#endif /*End of "Content enable"*/ diff --git a/samples/gui/lvgl-native-ui-app/main.c b/samples/gui/lvgl-native-ui-app/main.c new file mode 100644 index 00000000..1e778385 --- /dev/null +++ b/samples/gui/lvgl-native-ui-app/main.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file main + * + */ + +/********************* + * INCLUDES + *********************/ +#define _DEFAULT_SOURCE /* needed for usleep() */ +#include +#include +#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/ +#include +#include "lvgl/lvgl.h" +#include "lv_drivers/display/monitor.h" +#include "lv_drivers/indev/mouse.h" +#include "lv_drivers/indev/mousewheel.h" +#include "lv_drivers/indev/keyboard.h" + + +/********************* + * DEFINES + *********************/ + +/*On OSX SDL needs different handling*/ +#if defined(__APPLE__) && defined(TARGET_OS_MAC) +# if __APPLE__ && TARGET_OS_MAC +#define SDL_APPLE +# endif +#endif + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void hal_init(void); +static void btn_event_cb(lv_obj_t * btn, lv_event_t event); + +/********************** + * STATIC VARIABLES + **********************/ +uint32_t count = 0; +char count_str[11] = { 0 }; +lv_obj_t *hello_world_label; +lv_obj_t *count_label; +lv_obj_t * btn1; +lv_obj_t * label_count1; +int label_count1_value = 0; +char label_count1_str[11] = { 0 }; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +int main(int argc, char ** argv) +{ + (void) argc; /*Unused*/ + (void) argv; /*Unused*/ + + /*Initialize LittlevGL*/ + lv_init(); + + /*Initialize the HAL (display, input devices, tick) for LittlevGL*/ + hal_init(); + + hello_world_label = lv_label_create(lv_disp_get_scr_act(NULL), NULL); + lv_label_set_text(hello_world_label, "Hello world!"); + lv_obj_align(hello_world_label, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); + + count_label = lv_label_create(lv_disp_get_scr_act(NULL), NULL); + lv_obj_align(count_label, NULL, LV_ALIGN_IN_TOP_MID, 0, 0); + btn1 = lv_btn_create(lv_disp_get_scr_act(NULL), NULL); /*Create a button on the currently loaded screen*/ + lv_obj_set_event_cb(btn1, btn_event_cb); /*Set function to be called when the button is released*/ + lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 20); /*Align below the label*/ + + /*Create a label on the button*/ + lv_obj_t * btn_label = lv_label_create(btn1, NULL); + lv_label_set_text(btn_label, "Click ++"); + + label_count1 = lv_label_create(lv_disp_get_scr_act(NULL), NULL); + lv_label_set_text(label_count1, "0"); + lv_obj_align(label_count1, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + while(1) { + /* Periodically call the lv_task handler. + * It could be done in a timer interrupt or an OS task too.*/ + if ((count % 100) == 0) { + sprintf(count_str, "%d", count/ 100); + lv_label_set_text(count_label, count_str); + } + lv_task_handler(); + ++count; + usleep(10 * 1000); /*Just to let the system breath*/ + } + return 0; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * Initialize the Hardware Abstraction Layer (HAL) for the Littlev graphics library + */ +static void hal_init(void) +{ + /* Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/ + monitor_init(); + + /*Create a display buffer*/ + static lv_disp_buf_t disp_buf1; + static lv_color_t buf1_1[320*10]; + lv_disp_buf_init(&disp_buf1, buf1_1, NULL, 320*10); + + /*Create a display*/ + lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); /*Basic initialization*/ + disp_drv.buffer = &disp_buf1; + disp_drv.flush_cb = monitor_flush; /*Used when `LV_VDB_SIZE != 0` in lv_conf.h (buffered drawing)*/ + // disp_drv.hor_res = 200; + // disp_drv.ver_res = 100; + lv_disp_drv_register(&disp_drv); + + /* Add the mouse as input device + * Use the 'mouse' driver which reads the PC's mouse*/ + mouse_init(); + lv_indev_drv_t indev_drv; + lv_indev_drv_init(&indev_drv); /*Basic initialization*/ + indev_drv.type = LV_INDEV_TYPE_POINTER; + indev_drv.read_cb = mouse_read; /*This function will be called periodically (by the library) to get the mouse position and state*/ + lv_indev_drv_register(&indev_drv); +} + +static void btn_event_cb(lv_obj_t * btn, lv_event_t event) +{ + if(event == LV_EVENT_RELEASED) { + label_count1_value++; + sprintf(label_count1_str, "%d", label_count1_value); + lv_label_set_text(label_count1, label_count1_str); + } +} diff --git a/samples/gui/lvgl-native-ui-app/system_header.h b/samples/gui/lvgl-native-ui-app/system_header.h new file mode 100644 index 00000000..9c8b1d23 --- /dev/null +++ b/samples/gui/lvgl-native-ui-app/system_header.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +int time_get_ms(); diff --git a/samples/gui/wasm-apps/lvgl-compatible/Makefile b/samples/gui/wasm-apps/lvgl-compatible/Makefile new file mode 100644 index 00000000..17946491 --- /dev/null +++ b/samples/gui/wasm-apps/lvgl-compatible/Makefile @@ -0,0 +1,39 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CC = emcc +APP_DIR = ${shell pwd} +IWASM_DIR=../../../../core/iwasm +CFLAGS += -O3 \ + -Wno-int-conversion \ + -DLV_CONF_INCLUDE_SIMPLE \ + -I$(APP_DIR)/src/ \ + -I$(IWASM_DIR)/lib/app-libs/base/ \ + -I$(IWASM_DIR)/lib/native-interface/ \ + -I$(IWASM_DIR)/lib/app-libs/extension/sensor \ + -I$(IWASM_DIR)/lib/app-libs/extension/gui \ + -I$(IWASM_DIR)/lib/app-libs/extension/connection + +SRCS += $(APP_DIR)/src/main.c + +# For app size consideration, not all but necessary app libs are included +SRCS += $(IWASM_DIR)/lib/app-libs/base/timer.c +SRCS += $(IWASM_DIR)/lib/app-libs/extension/gui/src/*.c + +all: + @$(CC) $(CFLAGS) $(SRCS) \ + -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ + -s TOTAL_MEMORY=65536 -s TOTAL_STACK=2048\ + -s "EXPORTED_FUNCTIONS=['_on_init', '_on_timer_callback', '_on_widget_event']" \ + -o ui_app_lvgl_compatible.wasm diff --git a/samples/gui/wasm-apps/lvgl-compatible/src/main.c b/samples/gui/wasm-apps/lvgl-compatible/src/main.c new file mode 100644 index 00000000..8f2c37a5 --- /dev/null +++ b/samples/gui/wasm-apps/lvgl-compatible/src/main.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "wasm_app.h" +#include "lvgl.h" + +extern char g_widget_text[]; + +static void btn_event_cb(lv_obj_t *btn, lv_event_t event); + +uint32_t count = 0; +char count_str[11] = { 0 }; +lv_obj_t *hello_world_label; +lv_obj_t *count_label; +lv_obj_t *btn1; +lv_obj_t *label_count1; +int label_count1_value = 100; +char label_count1_str[11] = { 0 }; + +void timer1_update(user_timer_t timer1) +{ + if ((count % 100) == 0) { + sprintf(count_str, "%d", count / 100); + lv_label_set_text(count_label, count_str); + } + ++count; +} + +void on_init() +{ + char *text; + + hello_world_label = lv_label_create(NULL, NULL); + lv_label_set_text(hello_world_label, "Hello world!"); + text = lv_label_get_text(hello_world_label); + printf("Label text %lu %s \n", strlen(text), text); + lv_obj_align(hello_world_label, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); + + count_label = lv_label_create(NULL, NULL); + lv_obj_align(count_label, NULL, LV_ALIGN_IN_TOP_MID, 0, 0); + + btn1 = lv_btn_create(NULL, NULL); /*Create a button on the currently loaded screen*/ + lv_obj_set_event_cb(btn1, btn_event_cb); /*Set function to be called when the button is released*/ + lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0); /*Align below the label*/ + + /*Create a label on the button*/ + lv_obj_t *btn_label = lv_label_create(btn1, NULL); + lv_label_set_text(btn_label, "Click --"); + + label_count1 = lv_label_create(NULL, NULL); + lv_label_set_text(label_count1, "100"); + lv_obj_align(label_count1, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + + /* set up a timer */ + user_timer_t timer; + timer = api_timer_create(10, true, false, timer1_update); + api_timer_restart(timer, 10); +} + +static void btn_event_cb(lv_obj_t *btn, lv_event_t event) +{ + if(event == LV_EVENT_RELEASED) { + label_count1_value--; + sprintf(label_count1_str, "%d", label_count1_value); + lv_label_set_text(label_count1, label_count1_str); + if (label_count1_value == 0) + label_count1_value = 100; + } +} diff --git a/samples/gui/wasm-apps/wgl/Makefile b/samples/gui/wasm-apps/wgl/Makefile new file mode 100644 index 00000000..88df1f25 --- /dev/null +++ b/samples/gui/wasm-apps/wgl/Makefile @@ -0,0 +1,39 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CC = emcc +APP_DIR = ${shell pwd} +IWASM_DIR=../../../../core/iwasm +CFLAGS += -O3 \ + -Wno-int-conversion \ + -DLV_CONF_INCLUDE_SIMPLE \ + -I$(APP_DIR)/src/ \ + -I$(IWASM_DIR)/lib/app-libs/base/ \ + -I$(IWASM_DIR)/lib/native-interface/ \ + -I$(IWASM_DIR)/lib/app-libs/extension/sensor \ + -I$(IWASM_DIR)/lib/app-libs/extension/gui \ + -I$(IWASM_DIR)/lib/app-libs/extension/connection + +SRCS += $(APP_DIR)/src/main.c + +# For app size consideration, not all but necessary app libs are included +SRCS += $(IWASM_DIR)/lib/app-libs/base/timer.c +SRCS += $(IWASM_DIR)/lib/app-libs/extension/gui/src/*.c + +all: + @$(CC) $(CFLAGS) $(SRCS) \ + -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ + -s TOTAL_MEMORY=65536 -s TOTAL_STACK=2048\ + -s "EXPORTED_FUNCTIONS=['_on_init', '_on_timer_callback', '_on_widget_event']" \ + -o ui_app.wasm diff --git a/samples/gui/wasm-apps/wgl/src/main.c b/samples/gui/wasm-apps/wgl/src/main.c new file mode 100644 index 00000000..bcd9f8ce --- /dev/null +++ b/samples/gui/wasm-apps/wgl/src/main.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "wasm_app.h" + +static void btn_event_cb(wgl_obj_t btn, wgl_event_t event); + +uint32_t count = 0; +char count_str[11] = { 0 }; +wgl_obj_t hello_world_label; +wgl_obj_t count_label; +wgl_obj_t btn1; +wgl_obj_t label_count1; +int label_count1_value = 0; +char label_count1_str[11] = { 0 }; + +void timer1_update(user_timer_t timer1) +{ + if ((count % 100) == 0) { + sprintf(count_str, "%d", count / 100); + wgl_label_set_text(count_label, count_str); + } + ++count; +} + +void on_init() +{ + hello_world_label = wgl_label_create((wgl_obj_t)NULL, (wgl_obj_t)NULL); + wgl_label_set_text(hello_world_label, "Hello world!"); + wgl_obj_align(hello_world_label, (wgl_obj_t)NULL, WGL_ALIGN_IN_TOP_LEFT, 0, 0); + + count_label = wgl_label_create((wgl_obj_t)NULL, (wgl_obj_t)NULL); + wgl_obj_align(count_label, (wgl_obj_t)NULL, WGL_ALIGN_IN_TOP_MID, 0, 0); + + btn1 = wgl_btn_create((wgl_obj_t)NULL, (wgl_obj_t)NULL); /*Create a button on the currently loaded screen*/ + wgl_obj_set_event_cb(btn1, btn_event_cb); /*Set function to be called when the button is released*/ + wgl_obj_align(btn1, (wgl_obj_t)NULL, WGL_ALIGN_CENTER, 0, 0); /*Align below the label*/ + + /*Create a label on the button*/ + wgl_obj_t btn_label = wgl_label_create(btn1, (wgl_obj_t)NULL); + wgl_label_set_text(btn_label, "Click ++"); + + label_count1 = wgl_label_create((wgl_obj_t)NULL, (wgl_obj_t)NULL); + wgl_label_set_text(label_count1, "0"); + wgl_obj_align(label_count1, (wgl_obj_t)NULL, WGL_ALIGN_IN_BOTTOM_MID, 0, 0); + + /* set up a timer */ + user_timer_t timer; + timer = api_timer_create(10, true, false, timer1_update); + api_timer_restart(timer, 10); +} + +static void btn_event_cb(wgl_obj_t btn, wgl_event_t event) +{ + if(event == WGL_EVENT_RELEASED) { + label_count1_value++; + sprintf(label_count1_str, "%d", label_count1_value); + wgl_label_set_text(label_count1, label_count1_str); + + //wgl_cont_set_fit4(btn, WGL_FIT_FLOOD, WGL_FIT_FLOOD, WGL_FIT_FLOOD, WGL_FIT_FLOOD); + //wgl_obj_clean(btn); + } +} diff --git a/samples/gui/wasm-runtime-wgl/linux-build/CMakeLists.txt b/samples/gui/wasm-runtime-wgl/linux-build/CMakeLists.txt new file mode 100644 index 00000000..5869052d --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/linux-build/CMakeLists.txt @@ -0,0 +1,115 @@ +cmake_minimum_required (VERSION 2.8) + +project (wasm_runtime_wgl) + +set(REPO_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..) +set(WASM_DIR ${REPO_ROOT_DIR}/core/iwasm) +set(APP_MGR_DIR ${REPO_ROOT_DIR}/core/app-mgr) +set(SHARED_DIR ${REPO_ROOT_DIR}/core/shared-lib) + +set (LV_DRIVERS_DIR ${WASM_DIR}/lib/3rdparty/lv_drivers) +set (LVGL_DIR ${WASM_DIR}/lib/3rdparty/lvgl) + +file(GLOB_RECURSE LV_DRIVERS_SOURCES "${LV_DRIVERS_DIR}/*.c" ) + +set (TARGET_PLATFORM "linux") + +# Reset default linker flags +set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") + +# Enable repl mode if want to test spec cases +# add_definitions(-DWASM_ENABLE_REPL) + +if (NOT ("$ENV{VALGRIND}" STREQUAL "YES")) + add_definitions(-DNVALGRIND) +endif () + +# Currently build as 64-bit by default. +set (BUILD_AS_64BIT_SUPPORT "YES") + +if (CMAKE_SIZEOF_VOID_P EQUAL 8) +if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES") + # Add -fPIC flag if build as 64-bit + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC") +else () + add_definitions (-m32) + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") + set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32") +endif () +endif () + +if (NOT CMAKE_BUILD_TYPE) +SET(CMAKE_BUILD_TYPE Debug) +endif (NOT CMAKE_BUILD_TYPE) +message ("CMAKE_BUILD_TYPE = " ${CMAKE_BUILD_TYPE}) + +if (NOT PLATFORM) +SET(PLATFORM linux) +endif (NOT PLATFORM) +message ("PLATFORM = " ${PLATFORM}) + +set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -Wno-pedantic") + + +enable_language (ASM) + +include (${WASM_DIR}/runtime/platform/${TARGET_PLATFORM}/platform.cmake) +include (${WASM_DIR}/runtime/utils/utils.cmake) +include (${WASM_DIR}/runtime/vmcore-wasm/vmcore.cmake) +include (${WASM_DIR}/lib/native/base/wasm_lib_base.cmake) +include (${WASM_DIR}/lib/native/libc/wasm_libc.cmake) +include (${WASM_DIR}/lib/native/extension/sensor/wasm_lib_sensor.cmake) +include (${WASM_DIR}/lib/native/extension/gui/wasm_lib_gui.cmake) +include (${WASM_DIR}/lib/native/extension/connection/wasm_lib_conn.cmake) +include (${WASM_DIR}/lib/native/extension/connection/${TARGET_PLATFORM}/connection_mgr.cmake) +include (${WASM_DIR}/lib/native-interface/native_interface.cmake) +include (${APP_MGR_DIR}/app-manager/app_mgr.cmake) +include (${APP_MGR_DIR}/app-mgr-shared/app_mgr_shared.cmake) +include (${SHARED_DIR}/platform/${TARGET_PLATFORM}/shared_platform.cmake) +include (${SHARED_DIR}/utils/shared_utils.cmake) +include (${SHARED_DIR}/mem-alloc/mem_alloc.cmake) +include (${SHARED_DIR}/coap/lib_coap.cmake) + +set (PROJECT_SRC_DIR ${CMAKE_CURRENT_LIST_DIR}/../src/platform/${TARGET_PLATFORM}) + +include_directories(${SHARED_DIR}/include) +include_directories(${PROJECT_SRC_DIR}) + +add_definitions (-DWASM_ENABLE_BASE_LIB) +add_definitions (-Dattr_container_malloc=bh_malloc) +add_definitions (-Dattr_container_free=bh_free) +add_definitions (-DLV_CONF_INCLUDE_SIMPLE) + +add_library (vmlib + ${WASM_PLATFORM_LIB_SOURCE} + ${WASM_UTILS_LIB_SOURCE} + ${VMCORE_LIB_SOURCE} + ${WASM_LIBC_SOURCE} + ${APP_MGR_SOURCE} + ${WASM_LIB_BASE_SOURCE} + ${WASM_LIB_EXT_SOURCE} + ${WASM_LIB_SENSOR_SOURCE} + ${WASM_LIB_GUI_SOURCE} + ${WASM_LIB_CONN_SOURCE} + ${WASM_LIB_CONN_MGR_SOURCE} + ${PLATFORM_SHARED_SOURCE} + ${UTILS_SHARED_SOURCE} + ${MEM_ALLOC_SHARED_SOURCE} + ${NATIVE_INTERFACE_SOURCE} + ) + +set (SOURCES + ${PROJECT_SRC_DIR}/main.c + ${PROJECT_SRC_DIR}/iwasm_main.c + ${PROJECT_SRC_DIR}/../../ext_lib_export.c + ${LV_DRIVERS_SOURCES} + ) + +add_executable (wasm_runtime_wgl ${SOURCES}) + +target_link_libraries (wasm_runtime_wgl vmlib -lm -ldl -lpthread -lSDL2) +#target_link_libraries(wasm_runtime_wgl PRIVATE SDL2 ) + diff --git a/samples/gui/wasm-runtime-wgl/src/ext_lib_export.c b/samples/gui/wasm-runtime-wgl/src/ext_lib_export.c new file mode 100644 index 00000000..e478b7e4 --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/ext_lib_export.c @@ -0,0 +1,12 @@ +#include "lib_export.h" +#include "native_interface.h" +#include "connection_api.h" +#include "gui_api.h" + +static NativeSymbol extended_native_symbol_defs[] = { +#include "runtime_sensor.inl" +#include "connection.inl" +#include "wamr_gui.inl" +}; + +#include "ext_lib_export.h" diff --git a/samples/gui/wasm-runtime-wgl/src/platform/linux/iwasm_main.c b/samples/gui/wasm-runtime-wgl/src/platform/linux/iwasm_main.c new file mode 100644 index 00000000..856e864c --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/linux/iwasm_main.c @@ -0,0 +1,512 @@ + +#ifndef CONNECTION_UART +#include +#include +#include +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "runtime_lib.h" +#include "runtime_timer.h" +#include "native_interface.h" +#include "app_manager_export.h" +#include "bh_common.h" +#include "bh_queue.h" +#include "bh_thread.h" +#include "bh_memory.h" +#include "runtime_sensor.h" +#include "attr_container.h" +#include "module_wasm_app.h" +#include "wasm_export.h" + +#include "lv_drivers/display/monitor.h" +#include "lv_drivers/indev/mouse.h" + +#define MAX 2048 + +#ifndef CONNECTION_UART +#define SA struct sockaddr +static char *host_address = "127.0.0.1"; +static int port = 8888; +#else +static char *uart_device = "/dev/ttyS2"; +static int baudrate = B115200; +#endif + +extern void * thread_timer_check(void *); +extern void init_sensor_framework(); +extern int aee_host_msg_callback(void *msg, uint16_t msg_len); +extern bool init_connection_framework(); +extern void wgl_init(); + +#ifndef CONNECTION_UART +int listenfd = -1; +int sockfd = -1; +static pthread_mutex_t sock_lock = PTHREAD_MUTEX_INITIALIZER; +#else +int uartfd = -1; +#endif + +#ifndef CONNECTION_UART +static bool server_mode = false; + +// Function designed for chat between client and server. +void* func(void* arg) +{ + char buff[MAX]; + int n; + struct sockaddr_in servaddr; + + while (1) { + if (sockfd != -1) + close(sockfd); + // socket create and verification + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) { + printf("socket creation failed...\n"); + return NULL; + } else + printf("Socket successfully created..\n"); + bzero(&servaddr, sizeof(servaddr)); + // assign IP, PORT + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr(host_address); + servaddr.sin_port = htons(port); + + // connect the client socket to server socket + if (connect(sockfd, (SA*) &servaddr, sizeof(servaddr)) != 0) { + printf("connection with the server failed...\n"); + sleep(10); + continue; + } else { + printf("connected to the server..\n"); + } + + // infinite loop for chat + for (;;) { + bzero(buff, MAX); + + // read the message from client and copy it in buffer + n = read(sockfd, buff, sizeof(buff)); + // print buffer which contains the client contents + //fprintf(stderr, "recieved %d bytes from host: %s", n, buff); + + // socket disconnected + if (n <= 0) + break; + + aee_host_msg_callback(buff, n); + } + } + + // After chatting close the socket + close(sockfd); +} + +static bool host_init() +{ + return true; +} + +int host_send(void * ctx, const char *buf, int size) +{ + int ret; + + if (pthread_mutex_trylock(&sock_lock) == 0) { + if (sockfd == -1) { + pthread_mutex_unlock(&sock_lock); + return 0; + } + + ret = write(sockfd, buf, size); + + pthread_mutex_unlock(&sock_lock); + return ret; + } + + return -1; +} + +void host_destroy() +{ + if (server_mode) + close(listenfd); + + pthread_mutex_lock(&sock_lock); + close(sockfd); + pthread_mutex_unlock(&sock_lock); +} + +host_interface interface = { + .init = host_init, + .send = host_send, + .destroy = host_destroy + }; + +void* func_server_mode(void* arg) +{ + int clilent; + struct sockaddr_in serv_addr, cli_addr; + int n; + char buff[MAX]; + + struct sigaction sa; + sa.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &sa, 0); + + /* First call to socket() function */ + listenfd = socket(AF_INET, SOCK_STREAM, 0); + + if (listenfd < 0) { + perror("ERROR opening socket"); + exit(1); + } + + /* Initialize socket structure */ + bzero((char *) &serv_addr, sizeof(serv_addr)); + + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(port); + + /* Now bind the host address using bind() call.*/ + if (bind(listenfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { + perror("ERROR on binding"); + exit(1); + } + + listen(listenfd, 5); + clilent = sizeof(cli_addr); + + while (1) { + pthread_mutex_lock(&sock_lock); + + sockfd = accept(listenfd, (struct sockaddr *) &cli_addr, &clilent); + + pthread_mutex_unlock(&sock_lock); + + if (sockfd < 0) { + perror("ERROR on accept"); + exit(1); + } + + printf("connection established!\n"); + + for (;;) { + bzero(buff, MAX); + + // read the message from client and copy it in buffer + n = read(sockfd, buff, sizeof(buff)); + + // socket disconnected + if (n <= 0) { + pthread_mutex_lock(&sock_lock); + close(sockfd); + sockfd = -1; + pthread_mutex_unlock(&sock_lock); + + sleep(2); + break; + } + + aee_host_msg_callback(buff, n); + } + } +} + +#else +static int parse_baudrate(int baud) +{ + switch (baud) { + case 9600: + return B9600; + case 19200: + return B19200; + case 38400: + return B38400; + case 57600: + return B57600; + case 115200: + return B115200; + case 230400: + return B230400; + case 460800: + return B460800; + case 500000: + return B500000; + case 576000: + return B576000; + case 921600: + return B921600; + case 1000000: + return B1000000; + case 1152000: + return B1152000; + case 1500000: + return B1500000; + case 2000000: + return B2000000; + case 2500000: + return B2500000; + case 3000000: + return B3000000; + case 3500000: + return B3500000; + case 4000000: + return B4000000; + default: + return -1; + } +} +static bool uart_init(const char *device, int baudrate, int *fd) +{ + int uart_fd; + struct termios uart_term; + + uart_fd = open(device, O_RDWR | O_NOCTTY); + + if (uart_fd <= 0) + return false; + + memset(&uart_term, 0, sizeof(uart_term)); + uart_term.c_cflag = baudrate | CS8 | CLOCAL | CREAD; + uart_term.c_iflag = IGNPAR; + uart_term.c_oflag = 0; + + /* set noncanonical mode */ + uart_term.c_lflag = 0; + uart_term.c_cc[VTIME] = 30; + uart_term.c_cc[VMIN] = 1; + tcflush(uart_fd, TCIFLUSH); + + if (tcsetattr(uart_fd, TCSANOW, &uart_term) != 0) { + close(uart_fd); + return false; + } + + *fd = uart_fd; + + return true; +} + +static void *func_uart_mode(void *arg) +{ + int n; + char buff[MAX]; + + if (!uart_init(uart_device, baudrate, &uartfd)) { + printf("open uart fail! %s\n", uart_device); + return NULL; + } + + for (;;) { + bzero(buff, MAX); + + n = read(uartfd, buff, sizeof(buff)); + + if (n <= 0) { + close(uartfd); + uartfd = -1; + break; + } + + aee_host_msg_callback(buff, n); + } + + return NULL; +} + +static int uart_send(void * ctx, const char *buf, int size) +{ + int ret; + + ret = write(uartfd, buf, size); + + return ret; +} + +static void uart_destroy() +{ + close(uartfd); +} + +static host_interface interface = { .send = uart_send, .destroy = uart_destroy }; + +#endif + +static char global_heap_buf[270 * 1024] = { 0 }; + +static void showUsage() +{ +#ifndef CONNECTION_UART + printf("Usage:\n"); + printf("\nWork as TCP server mode:\n"); + printf("\tvgl_wasm_runtime -s|--server_mode -p|--port \n"); + printf("where\n"); + printf("\t represents the port that would be listened on and the default is 8888\n"); + printf("\nWork as TCP client mode:\n"); + printf("\tvgl_wasm_runtime -a|--host_address -p|--port \n"); + printf("where\n"); + printf("\t represents the network address of host and the default is 127.0.0.1\n"); + printf("\t represents the listen port of host and the default is 8888\n"); +#else + printf("Usage:\n"); + printf("\tvgl_wasm_runtime -u -b \n\n"); + printf("where\n"); + printf("\t represents the UART device name and the default is /dev/ttyS2\n"); + printf("\t represents the UART device baudrate and the default is 115200\n"); +#endif +} + +static bool parse_args(int argc, char *argv[]) +{ + int c; + + while (1) { + int optIndex = 0; + static struct option longOpts[] = { +#ifndef CONNECTION_UART + { "server_mode", no_argument, NULL, 's' }, + { "host_address", required_argument, NULL, 'a' }, + { "port", required_argument, NULL, 'p' }, +#else + { "uart", required_argument, NULL, 'u' }, + { "baudrate", required_argument, NULL, 'b' }, +#endif + { "help", required_argument, NULL, 'h' }, + { 0, 0, 0, 0 } + }; + + c = getopt_long(argc, argv, "sa:p:u:b:h", longOpts, &optIndex); + if (c == -1) + break; + + switch (c) { +#ifndef CONNECTION_UART + case 's': + server_mode = true; + break; + case 'a': + host_address = optarg; + printf("host address: %s\n", host_address); + break; + case 'p': + port = atoi(optarg); + printf("port: %d\n", port); + break; +#else + case 'u': + uart_device = optarg; + printf("uart device: %s\n", uart_device); + break; + case 'b': + baudrate = parse_baudrate(atoi(optarg)); + printf("uart baudrate: %s\n", optarg); + break; +#endif + case 'h': + showUsage(); + return false; + default: + showUsage(); + return false; + } + } + + return true; +} + +/** + * Initialize the Hardware Abstraction Layer (HAL) for the Littlev graphics library + */ +static void hal_init(void) +{ + /* Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/ + monitor_init(); + + /*Create a display buffer*/ + static lv_disp_buf_t disp_buf1; + static lv_color_t buf1_1[480*10]; + lv_disp_buf_init(&disp_buf1, buf1_1, NULL, 480*10); + + /*Create a display*/ + lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); /*Basic initialization*/ + disp_drv.buffer = &disp_buf1; + disp_drv.flush_cb = monitor_flush; + // disp_drv.hor_res = 200; + // disp_drv.ver_res = 100; + lv_disp_drv_register(&disp_drv); + + /* Add the mouse as input device + * Use the 'mouse' driver which reads the PC's mouse*/ + mouse_init(); + lv_indev_drv_t indev_drv; + lv_indev_drv_init(&indev_drv); /*Basic initialization*/ + indev_drv.type = LV_INDEV_TYPE_POINTER; + indev_drv.read_cb = mouse_read; /*This function will be called periodically (by the library) to get the mouse position and state*/ + lv_indev_drv_register(&indev_drv); +} + +// Driver function +int iwasm_main(int argc, char *argv[]) +{ + korp_thread tid; + + if (!parse_args(argc, argv)) + return -1; + + if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf)) + != 0) { + printf("Init global heap failed.\n"); + return -1; + } + + if (vm_thread_sys_init() != 0) { + goto fail1; + } + + if (!init_connection_framework()) { + vm_thread_sys_destroy(); + goto fail1; + } + + wgl_init(); + + hal_init(); + + init_sensor_framework(); + + // timer manager + init_wasm_timer(); + +#ifndef CONNECTION_UART + if (server_mode) + vm_thread_create(&tid, func_server_mode, NULL, + BH_APPLET_PRESERVED_STACK_SIZE); + else + vm_thread_create(&tid, func, NULL, BH_APPLET_PRESERVED_STACK_SIZE); +#else + vm_thread_create(&tid, func_uart_mode, NULL, BH_APPLET_PRESERVED_STACK_SIZE); +#endif + + // TODO: + app_manager_startup(&interface); + + fail1: bh_memory_destroy(); + return -1; +} diff --git a/samples/gui/wasm-runtime-wgl/src/platform/linux/lv_drv_conf.h b/samples/gui/wasm-runtime-wgl/src/platform/linux/lv_drv_conf.h new file mode 100644 index 00000000..d216a3e9 --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/linux/lv_drv_conf.h @@ -0,0 +1,310 @@ +/** + * @file lv_drv_conf.h + * + */ + +/* + * COPY THIS FILE AS lv_drv_conf.h + */ + +#if 1 /*Set it to "1" to enable the content*/ + +#ifndef LV_DRV_CONF_H +#define LV_DRV_CONF_H + +#include "lv_conf.h" + +/********************* + * DELAY INTERFACE + *********************/ +#define LV_DRV_DELAY_INCLUDE /*Dummy include by default*/ +#define LV_DRV_DELAY_US(us) /*delay_us(us)*/ /*Delay the given number of microseconds*/ +#define LV_DRV_DELAY_MS(ms) /*delay_ms(ms)*/ /*Delay the given number of milliseconds*/ + +/********************* + * DISPLAY INTERFACE + *********************/ + +/*------------ + * Common + *------------*/ +#define LV_DRV_DISP_INCLUDE /*Dummy include by default*/ +#define LV_DRV_DISP_CMD_DATA(val) /*pin_x_set(val)*/ /*Set the command/data pin to 'val'*/ +#define LV_DRV_DISP_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ + +/*--------- + * SPI + *---------*/ +#define LV_DRV_DISP_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/ +#define LV_DRV_DISP_SPI_WR_BYTE(data) /*spi_wr(data)*/ /*Write a byte the SPI bus*/ +#define LV_DRV_DISP_SPI_WR_ARRAY(adr, n) /*spi_wr_mem(adr, n)*/ /*Write 'n' bytes to SPI bus from 'adr'*/ + +/*------------------ + * Parallel port + *-----------------*/ +#define LV_DRV_DISP_PAR_CS(val) /*par_cs_set(val)*/ /*Set the Parallel port's Chip select to 'val'*/ +#define LV_DRV_DISP_PAR_SLOW /*par_slow()*/ /*Set low speed on the parallel port*/ +#define LV_DRV_DISP_PAR_FAST /*par_fast()*/ /*Set high speed on the parallel port*/ +#define LV_DRV_DISP_PAR_WR_WORD(data) /*par_wr(data)*/ /*Write a word to the parallel port*/ +#define LV_DRV_DISP_PAR_WR_ARRAY(adr, n) /*par_wr_mem(adr,n)*/ /*Write 'n' bytes to Parallel ports from 'adr'*/ + +/*************************** + * INPUT DEVICE INTERFACE + ***************************/ + +/*---------- + * Common + *----------*/ +#define LV_DRV_INDEV_INCLUDE /*Dummy include by default*/ +#define LV_DRV_INDEV_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ +#define LV_DRV_INDEV_IRQ_READ 0 /*pn_x_read()*/ /*Read the IRQ pin*/ + +/*--------- + * SPI + *---------*/ +#define LV_DRV_INDEV_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/ +#define LV_DRV_INDEV_SPI_XCHG_BYTE(data) 0 /*spi_xchg(val)*/ /*Write 'val' to SPI and give the read value*/ + +/*--------- + * I2C + *---------*/ +#define LV_DRV_INDEV_I2C_START /*i2c_start()*/ /*Make an I2C start*/ +#define LV_DRV_INDEV_I2C_STOP /*i2c_stop()*/ /*Make an I2C stop*/ +#define LV_DRV_INDEV_I2C_RESTART /*i2c_restart()*/ /*Make an I2C restart*/ +#define LV_DRV_INDEV_I2C_WR(data) /*i2c_wr(data)*/ /*Write a byte to the I1C bus*/ +#define LV_DRV_INDEV_I2C_READ(last_read) 0 /*i2c_rd()*/ /*Read a byte from the I2C bud*/ + + +/********************* + * DISPLAY DRIVERS + *********************/ + +/*------------------- + * Monitor of PC + *-------------------*/ +#ifndef USE_MONITOR +# define USE_MONITOR 1 +#endif + +#if USE_MONITOR +# define MONITOR_HOR_RES LV_HOR_RES_MAX +# define MONITOR_VER_RES LV_VER_RES_MAX + +/* Scale window by this factor (useful when simulating small screens) */ +# define MONITOR_ZOOM 1 + +/* Used to test true double buffering with only address changing. + * Set LV_VDB_SIZE = (LV_HOR_RES * LV_VER_RES) and LV_VDB_DOUBLE = 1 and LV_COLOR_DEPTH = 32" */ +# define MONITOR_DOUBLE_BUFFERED 0 + +/*Eclipse: Visual Studio: */ +# define MONITOR_SDL_INCLUDE_PATH + +/*Different rendering might be used if running in a Virtual machine*/ +# define MONITOR_VIRTUAL_MACHINE 0 + +/*Open two windows to test multi display support*/ +# define MONITOR_DUAL 0 +#endif + +/*----------------------------------- + * Native Windows (including mouse) + *----------------------------------*/ +#ifndef USE_WINDOWS +# define USE_WINDOWS 0 +#endif + +#define USE_WINDOWS 0 +#if USE_WINDOWS +# define WINDOW_HOR_RES 480 +# define WINDOW_VER_RES 320 +#endif + +/*---------------- + * SSD1963 + *--------------*/ +#ifndef USE_SSD1963 +# define USE_SSD1963 0 +#endif + +#if USE_SSD1963 +# define SSD1963_HOR_RES LV_HOR_RES +# define SSD1963_VER_RES LV_VER_RES +# define SSD1963_HT 531 +# define SSD1963_HPS 43 +# define SSD1963_LPS 8 +# define SSD1963_HPW 10 +# define SSD1963_VT 288 +# define SSD1963_VPS 12 +# define SSD1963_FPS 4 +# define SSD1963_VPW 10 +# define SSD1963_HS_NEG 0 /*Negative hsync*/ +# define SSD1963_VS_NEG 0 /*Negative vsync*/ +# define SSD1963_ORI 0 /*0, 90, 180, 270*/ +# define SSD1963_COLOR_DEPTH 16 +#endif + +/*---------------- + * R61581 + *--------------*/ +#ifndef USE_R61581 +# define USE_R61581 0 +#endif + +#if USE_R61581 +# define R61581_HOR_RES LV_HOR_RES +# define R61581_VER_RES LV_VER_RES +# define R61581_HSPL 0 /*HSYNC signal polarity*/ +# define R61581_HSL 10 /*HSYNC length (Not Implemented)*/ +# define R61581_HFP 10 /*Horitontal Front poarch (Not Implemented)*/ +# define R61581_HBP 10 /*Horitontal Back poarch (Not Implemented */ +# define R61581_VSPL 0 /*VSYNC signal polarity*/ +# define R61581_VSL 10 /*VSYNC length (Not Implemented)*/ +# define R61581_VFP 8 /*Vertical Front poarch*/ +# define R61581_VBP 8 /*Vertical Back poarch */ +# define R61581_DPL 0 /*DCLK signal polarity*/ +# define R61581_EPL 1 /*ENABLE signal polarity*/ +# define R61581_ORI 0 /*0, 180*/ +# define R61581_LV_COLOR_DEPTH 16 /*Fix 16 bit*/ +#endif + +/*------------------------------ + * ST7565 (Monochrome, low res.) + *-----------------------------*/ +#ifndef USE_ST7565 +# define USE_ST7565 0 +#endif + +#if USE_ST7565 +/*No settings*/ +#endif /*USE_ST7565*/ + +/*----------------------------------------- + * Linux frame buffer device (/dev/fbx) + *-----------------------------------------*/ +#ifndef USE_FBDEV +# define USE_FBDEV 1 +#endif + +#if USE_FBDEV +# define FBDEV_PATH "/dev/fb0" +#endif + +/********************* + * INPUT DEVICES + *********************/ + +/*-------------- + * XPT2046 + *--------------*/ +#ifndef USE_XPT2046 +# define USE_XPT2046 0 +#endif + +#if USE_XPT2046 +# define XPT2046_HOR_RES 480 +# define XPT2046_VER_RES 320 +# define XPT2046_X_MIN 200 +# define XPT2046_Y_MIN 200 +# define XPT2046_X_MAX 3800 +# define XPT2046_Y_MAX 3800 +# define XPT2046_AVG 4 +# define XPT2046_INV 0 +#endif + +/*----------------- + * FT5406EE8 + *-----------------*/ +#ifndef USE_FT5406EE8 +# define USE_FT5406EE8 0 +#endif + +#if USE_FT5406EE8 +# define FT5406EE8_I2C_ADR 0x38 /*7 bit address*/ +#endif + +/*--------------- + * AD TOUCH + *--------------*/ +#ifndef USE_AD_TOUCH +# define USE_AD_TOUCH 0 +#endif + +#if USE_AD_TOUCH +/*No settings*/ +#endif + + +/*--------------------------------------- + * Mouse or touchpad on PC (using SDL) + *-------------------------------------*/ +#ifndef USE_MOUSE +# define USE_MOUSE 1 +#endif + +#if USE_MOUSE +/*No settings*/ +#endif + +/*------------------------------------------- + * Mousewheel as encoder on PC (using SDL) + *------------------------------------------*/ +#ifndef USE_MOUSEWHEEL +# define USE_MOUSEWHEEL 1 +#endif + +#if USE_MOUSEWHEEL +/*No settings*/ +#endif + +/*------------------------------------------------- + * Touchscreen as libinput interface (for Linux based systems) + *------------------------------------------------*/ +#ifndef USE_LIBINPUT +# define USE_LIBINPUT 0 +#endif + +#if USE_LIBINPUT +# define LIBINPUT_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/ +#endif /*USE_LIBINPUT*/ + +/*------------------------------------------------- + * Mouse or touchpad as evdev interface (for Linux based systems) + *------------------------------------------------*/ +#ifndef USE_EVDEV +# define USE_EVDEV 0 +#endif + +#if USE_EVDEV +# define EVDEV_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/ +# define EVDEV_SWAP_AXES 0 /*Swap the x and y axes of the touchscreen*/ + +# define EVDEV_SCALE 0 /* Scale input, e.g. if touchscreen resolution does not match display resolution */ +# if EVDEV_SCALE +# define EVDEV_SCALE_HOR_RES (4096) /* Horizontal resolution of touchscreen */ +# define EVDEV_SCALE_VER_RES (4096) /* Vertical resolution of touchscreen */ +# endif /*EVDEV_SCALE*/ + +# define EVDEV_CALIBRATE 0 /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/ +# if EVDEV_CALIBRATE +# define EVDEV_HOR_MIN 3800 /*If EVDEV_XXX_MIN > EVDEV_XXX_MAX the XXX axis is automatically inverted*/ +# define EVDEV_HOR_MAX 200 +# define EVDEV_VER_MIN 200 +# define EVDEV_VER_MAX 3800 +# endif /*EVDEV_SCALE*/ +#endif /*USE_EVDEV*/ + +/*------------------------------- + * Keyboard of a PC (using SDL) + *------------------------------*/ +#ifndef USE_KEYBOARD +# define USE_KEYBOARD 1 +#endif + +#if USE_KEYBOARD +/*No settings*/ +#endif + +#endif /*LV_DRV_CONF_H*/ + +#endif /*End of "Content enable"*/ diff --git a/samples/gui/wasm-runtime-wgl/src/platform/linux/main.c b/samples/gui/wasm-runtime-wgl/src/platform/linux/main.c new file mode 100644 index 00000000..24cae03d --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/linux/main.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +extern void iwasm_main(int argc, char *argv[]); +int main(int argc, char *argv[]) +{ + iwasm_main(argc,argv); +} diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/LICENSE b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/LICENSE new file mode 100644 index 00000000..8f71f43f --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.c b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.c new file mode 100644 index 00000000..6d9048d4 --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.c @@ -0,0 +1,337 @@ +/** + * @file XPT2046.c +*/ +/********************* + * INCLUDES + *********************/ +#include "XPT2046.h" +#include "board_config.h" +#include "stdio.h" +#include +#include "spi.h" + +#include "zephyr.h" +#include "kernel.h" + +#if USE_XPT2046 + +#include + +#define abs(x) ((x) < 0 ? -(x) : (x)) + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static void xpt2046_corr(int16_t * x, int16_t * y); +static void xpt2046_avg(int16_t * x, int16_t * y); + +/********************** + * STATIC VARIABLES + **********************/ +int16_t avg_buf_x[XPT2046_AVG]; +int16_t avg_buf_y[XPT2046_AVG]; +uint8_t avg_last; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Initialize the XPT2046 + */ +struct device *input_dev; + +struct spi_config spi_conf_xpt2046; +struct spi_cs_control xpt2046_cs_ctrl; +struct device *xpt2046_pen_gpio_dev; +static struct gpio_callback gpio_cb; +lv_indev_data_t touch_point; +lv_indev_data_t last_touch_point; + +#define TOUCH_READ_THREAD_STACK_SIZE 4096 +static K_THREAD_STACK_DEFINE(touch_read_thread_stack, TOUCH_READ_THREAD_STACK_SIZE); +static struct k_thread touch_thread_data; +static struct k_sem sem_touch_read; + +K_MUTEX_DEFINE( spi_display_touch_mutex); + +int cnt = 0; +int touch_read_times = 0; +int last_pen_interrupt_time = 0; +void xpt2046_pen_gpio_callback(struct device *port, struct gpio_callback *cb, + u32_t pins) +{ + int i; + cnt++; + if ((k_uptime_get_32() - last_pen_interrupt_time) > 500) { + k_sem_give(&sem_touch_read); + touch_read_times++; + last_pen_interrupt_time = k_uptime_get_32(); + } + +} + +void disable_pen_interrupt() +{ + int ret = 0; + ret = gpio_pin_disable_callback(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN); + if (ret != 0) { + printf("gpio_pin_configure GPIO_DIR_IN failed\n"); + } +} +void enable_pen_interrupt() +{ + int ret = 0; + ret = gpio_pin_enable_callback(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN); + if (ret != 0) { + printf("gpio_pin_configure failed\n"); + } +} + +void touch_screen_read_thread() +{ + int i; + bool ret = false; + + for (;;) { + k_sem_take(&sem_touch_read, K_FOREVER); + memset(&last_touch_point, 0, sizeof(lv_indev_data_t)); + memset(&touch_point, 0, sizeof(lv_indev_data_t)); + memset(avg_buf_x, 0, sizeof(avg_buf_x)); + memset(avg_buf_y, 0, sizeof(avg_buf_y)); + k_mutex_lock(&spi_display_touch_mutex, K_FOREVER); + disable_pen_interrupt(); + for (i = 0; i < 100; i++) { + ret = xpt2046_read(&touch_point); + if (ret) { + if ((abs(last_touch_point.point.x - touch_point.point.x) < 4) + && (abs(last_touch_point.point.y - touch_point.point.y) + < 4)) { + break; + } + last_touch_point = touch_point; + + } + } + enable_pen_interrupt(); + k_mutex_unlock(&spi_display_touch_mutex); + } +} + +void xpt2046_init(void) +{ + int ret; + input_dev = device_get_binding(XPT2046_SPI_DEVICE_NAME); + + if (input_dev == NULL) { + printf("device not found. Aborting test."); + return; + } + memset((void *) &touch_point, 0, sizeof(lv_indev_data_t)); + + spi_conf_xpt2046.frequency = XPT2046_SPI_MAX_FREQUENCY; + spi_conf_xpt2046.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8); + spi_conf_xpt2046.slave = 0; + spi_conf_xpt2046.cs = NULL; +#ifdef XPT2046_CS_GPIO_CONTROLLER + xpt2046_cs_ctrl.gpio_dev = device_get_binding(XPT2046_CS_GPIO_CONTROLLER); + if (xpt2046_cs_ctrl.gpio_dev == NULL) { + printk("Cannot find %s!\n", XPT2046_CS_GPIO_CONTROLLER); + return; + } + gpio_pin_configure(xpt2046_cs_ctrl.gpio_dev, XPT2046_CS_GPIO_PIN, + GPIO_DIR_OUT); + gpio_pin_write(xpt2046_cs_ctrl.gpio_dev, XPT2046_CS_GPIO_PIN, 1); + xpt2046_cs_ctrl.gpio_pin = XPT2046_CS_GPIO_PIN; + xpt2046_cs_ctrl.delay = 0; + spi_conf_xpt2046.cs = &xpt2046_cs_ctrl; + +#endif + +#ifdef XPT2046_PEN_GPIO_CONTROLLER + + xpt2046_pen_gpio_dev = device_get_binding(XPT2046_PEN_GPIO_CONTROLLER); + if (!xpt2046_pen_gpio_dev) { + printk("Cannot find %s!\n", XPT2046_PEN_GPIO_CONTROLLER); + return; + } + /* Setup GPIO input */ + ret = gpio_pin_configure(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN, + (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE + | GPIO_INT_ACTIVE_LOW | GPIO_INT_DEBOUNCE) + ); + if (ret) { + printk("Error configuring pin %d!\n", XPT2046_PEN_GPIO_PIN); + } + + gpio_init_callback(&gpio_cb, xpt2046_pen_gpio_callback, + BIT(XPT2046_PEN_GPIO_PIN)); + + ret = gpio_add_callback(xpt2046_pen_gpio_dev, &gpio_cb); + if (ret) { + printk("gpio_add_callback error\n"); + } + ret = gpio_pin_enable_callback(xpt2046_pen_gpio_dev, XPT2046_PEN_GPIO_PIN); + if (ret) { + printk("gpio_pin_enable_callback error\n"); + } +#endif + + k_sem_init(&sem_touch_read, 0, 1); + + k_thread_create(&touch_thread_data, touch_read_thread_stack, + TOUCH_READ_THREAD_STACK_SIZE, touch_screen_read_thread, + NULL, NULL, NULL, 5, + 0, K_NO_WAIT); + printf("xpt2046_init ok \n"); +} + +/** + * Get the current position and state of the touchpad + * @param data store the read data here + * @return false: because no ore data to be read + */ +bool xpt2046_read(lv_indev_data_t * data) +{ + static int16_t last_x = 0; + static int16_t last_y = 0; + bool valid = true; + int s32_ret = 0; + uint8_t buf; + + int16_t x = 0; + int16_t y = 0; + + char tx1[16] = { 0 }; + char rx1[16] = { 0 }; + + struct spi_buf tx_buf = { .buf = &tx1, .len = 3 }; + struct spi_buf_set tx_bufs = { .buffers = &tx_buf, .count = 1 }; + struct spi_buf rx_buf = { .buf = &rx1, .len = 3 }; + struct spi_buf_set rx_bufs = { .buffers = &rx_buf, .count = 1 }; + + tx1[0] = CMD_X_READ; + s32_ret = spi_transceive(input_dev, &spi_conf_xpt2046, &tx_bufs, &rx_bufs); + if (s32_ret != 0) { + printf("spi_transceive return failed:%d\n", s32_ret); + } + x = rx1[1] << 8; + x += rx1[2]; + + tx1[0] = CMD_Y_READ; + s32_ret = spi_transceive(input_dev, &spi_conf_xpt2046, &tx_bufs, &rx_bufs); + if (s32_ret != 0) { + printf("spi_transceive return failed:%d\n", s32_ret); + } + y = rx1[1] << 8; + y += rx1[2]; + x = x >> 3; + y = y >> 3; + + xpt2046_corr(&x, &y); + if (y <= 0 || (x > 320)) { + valid = false; + } + + last_x = x; + last_y = y; + + data->point.x = x; + data->point.y = y; + data->state = valid == false ? LV_INDEV_STATE_REL : LV_INDEV_STATE_PR; + + return valid; +} + +/********************** + * STATIC FUNCTIONS + **********************/ +static void xpt2046_corr(int16_t * x, int16_t * y) +{ +#if XPT2046_XY_SWAP != 0 + int16_t swap_tmp; + swap_tmp = *x; + *x = *y; + *y = swap_tmp; +#endif + + if ((*x) > XPT2046_X_MIN) + (*x) -= XPT2046_X_MIN; + else + (*x) = 0; + + if ((*y) > XPT2046_Y_MIN) + (*y) -= XPT2046_Y_MIN; + else + (*y) = 0; + + (*x) = (uint32_t)((uint32_t)(*x) * XPT2046_HOR_RES) + / (XPT2046_X_MAX - XPT2046_X_MIN); + + (*y) = (uint32_t)((uint32_t)(*y) * XPT2046_VER_RES) + / (XPT2046_Y_MAX - XPT2046_Y_MIN); + +#if XPT2046_X_INV != 0 + (*x) = XPT2046_HOR_RES - (*x); +#endif + +#if XPT2046_Y_INV != 0 + (*y) = XPT2046_VER_RES - (*y); +#endif + +} + +static void xpt2046_avg(int16_t * x, int16_t * y) +{ + /*Shift out the oldest data*/ + uint8_t i; + for (i = XPT2046_AVG - 1; i > 0; i--) { + avg_buf_x[i] = avg_buf_x[i - 1]; + avg_buf_y[i] = avg_buf_y[i - 1]; + } + + /*Insert the new point*/ + avg_buf_x[0] = *x; + avg_buf_y[0] = *y; + if (avg_last < XPT2046_AVG) + avg_last++; + + /*Sum the x and y coordinates*/ + int32_t x_sum = 0; + int32_t y_sum = 0; + for (i = 0; i < avg_last; i++) { + x_sum += avg_buf_x[i]; + y_sum += avg_buf_y[i]; + } + + /*Normalize the sums*/ + (*x) = (int32_t) x_sum / avg_last; + (*y) = (int32_t) y_sum / avg_last; +} + +bool touchscreen_read(lv_indev_data_t * data) +{ + /*Store the collected data*/ + data->point.x = last_touch_point.point.x; + data->point.y = last_touch_point.point.y; + data->state = last_touch_point.state; + + if (last_touch_point.state == LV_INDEV_STATE_PR) { + last_touch_point.state = LV_INDEV_STATE_REL; + } + return false; +} + +#endif diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.h b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.h new file mode 100644 index 00000000..6f96c600 --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/XPT2046.h @@ -0,0 +1,71 @@ +/** + * @file XPT2046.h + * + */ + +#ifndef XPT2046_H +#define XPT2046_H + +#define USE_XPT2046 1 +#ifndef LV_CONF_INCLUDE_SIMPLE +#define LV_CONF_INCLUDE_SIMPLE +#endif + +# define XPT2046_HOR_RES 320 +# define XPT2046_VER_RES 240 +# define XPT2046_X_MIN 200 +# define XPT2046_Y_MIN 200 +# define XPT2046_X_MAX 3800 +# define XPT2046_Y_MAX 3800 +# define XPT2046_AVG 4 +# define XPT2046_INV 0 + +#define CMD_X_READ 0b10010000 +#define CMD_Y_READ 0b11010000 + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#ifdef LV_CONF_INCLUDE_SIMPLE +//#include "lv_drv_conf.h" +#else +//#include "../../lv_drv_conf.h" +#endif + +#if USE_XPT2046 +#include +#include +#include +#include "lv_hal/lv_hal_indev.h" +#include "device.h" +#include "gpio.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +void xpt2046_init(void); +bool xpt2046_read(lv_indev_data_t * data); + +/********************** + * MACROS + **********************/ + +#endif /* USE_XPT2046 */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* XPT2046_H */ diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/board_config.h b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/board_config.h new file mode 100644 index 00000000..1233c300 --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/board_config.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __BOARD_CONFIG_H__ +#define __BOARD_CONFIG_H__ +#include "pin_config_stm32.h" + +#endif /* __BOARD_CONFIG_H__ */ diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display.h b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display.h new file mode 100644 index 00000000..b820b9ce --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display.h @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2017 Jan Van Winkel + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Public API for display drivers and applications + */ + +#ifndef ZEPHYR_INCLUDE_DISPLAY_H_ +#define ZEPHYR_INCLUDE_DISPLAY_H_ + +/** + * @brief Display Interface + * @defgroup display_interface Display Interface + * @ingroup display_interfaces + * @{ + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum display_pixel_format { + PIXEL_FORMAT_RGB_888 = BIT(0), PIXEL_FORMAT_MONO01 = BIT(1), /* 0=Black 1=White */ + PIXEL_FORMAT_MONO10 = BIT(2), /* 1=Black 0=White */ + PIXEL_FORMAT_ARGB_8888 = BIT(3), PIXEL_FORMAT_RGB_565 = BIT(4), +}; + +enum display_screen_info { + /** + * If selected, one octet represents 8 pixels ordered vertically, + * otherwise ordered horizontally. + */ + SCREEN_INFO_MONO_VTILED = BIT(0), + /** + * If selected, the MSB represents the first pixel, + * otherwise MSB represents the last pixel. + */ + SCREEN_INFO_MONO_MSB_FIRST = BIT(1), + /** + * Electrophoretic Display. + */ + SCREEN_INFO_EPD = BIT(2), + /** + * Screen has two alternating ram buffers + */ + SCREEN_INFO_DOUBLE_BUFFER = BIT(3), +}; + +/** + * @enum display_orientation + * @brief Enumeration with possible display orientation + * + */ +enum display_orientation { + DISPLAY_ORIENTATION_NORMAL, + DISPLAY_ORIENTATION_ROTATED_90, + DISPLAY_ORIENTATION_ROTATED_180, + DISPLAY_ORIENTATION_ROTATED_270, +}; + +/** + * @struct display_capabilities + * @brief Structure holding display capabilities + * + * @var u16_t display_capabilities::x_resolution + * Display resolution in the X direction + * + * @var u16_t display_capabilities::y_resolution + * Display resolution in the Y direction + * + * @var u32_t display_capabilities::supported_pixel_formats + * Bitwise or of pixel formats supported by the display + * + * @var u32_t display_capabilities::screen_info + * Information about display panel + * + * @var enum display_pixel_format display_capabilities::current_pixel_format + * Currently active pixel format for the display + * + * @var enum display_orientation display_capabilities::current_orientation + * Current display orientation + * + */ +struct display_capabilities { + u16_t x_resolution; + u16_t y_resolution; + u32_t supported_pixel_formats; + u32_t screen_info; + enum display_pixel_format current_pixel_format; + enum display_orientation current_orientation; +}; + +/** + * @struct display_buffer_descriptor + * @brief Structure to describe display data buffer layout + * + * @var u32_t display_buffer_descriptor::buf_size + * Data buffer size in bytes + * + * @var u16_t display_buffer_descriptor::width + * Data buffer row width in pixels + * + * @var u16_t display_buffer_descriptor::height + * Data buffer column height in pixels + * + * @var u16_t display_buffer_descriptor::pitch + * Number of pixels between consecutive rows in the data buffer + * + */ +struct display_buffer_descriptor { + u32_t buf_size; + u16_t width; + u16_t height; + u16_t pitch; +}; + +/** + * @typedef display_blanking_on_api + * @brief Callback API to turn on display blanking + * See display_blanking_on() for argument description + */ +typedef int (*display_blanking_on_api)(const struct device *dev); + +/** + * @typedef display_blanking_off_api + * @brief Callback API to turn off display blanking + * See display_blanking_off() for argument description + */ +typedef int (*display_blanking_off_api)(const struct device *dev); + +/** + * @typedef display_write_api + * @brief Callback API for writing data to the display + * See display_write() for argument description + */ +typedef int (*display_write_api)(const struct device *dev, const u16_t x, + const u16_t y, const struct display_buffer_descriptor *desc, + const void *buf); + +/** + * @typedef display_read_api + * @brief Callback API for reading data from the display + * See display_read() for argument description + */ +typedef int (*display_read_api)(const struct device *dev, const u16_t x, + const u16_t y, const struct display_buffer_descriptor *desc, void *buf); + +/** + * @typedef display_get_framebuffer_api + * @brief Callback API to get framebuffer pointer + * See display_get_framebuffer() for argument description + */ +typedef void *(*display_get_framebuffer_api)(const struct device *dev); + +/** + * @typedef display_set_brightness_api + * @brief Callback API to set display brightness + * See display_set_brightness() for argument description + */ +typedef int (*display_set_brightness_api)(const struct device *dev, + const u8_t brightness); + +/** + * @typedef display_set_contrast_api + * @brief Callback API to set display contrast + * See display_set_contrast() for argument description + */ +typedef int (*display_set_contrast_api)(const struct device *dev, + const u8_t contrast); + +/** + * @typedef display_get_capabilities_api + * @brief Callback API to get display capabilities + * See display_get_capabilities() for argument description + */ +typedef void (*display_get_capabilities_api)(const struct device *dev, + struct display_capabilities * capabilities); + +/** + * @typedef display_set_pixel_format_api + * @brief Callback API to set pixel format used by the display + * See display_set_pixel_format() for argument description + */ +typedef int (*display_set_pixel_format_api)(const struct device *dev, + const enum display_pixel_format pixel_format); + +/** + * @typedef display_set_orientation_api + * @brief Callback API to set orientation used by the display + * See display_set_orientation() for argument description + */ +typedef int (*display_set_orientation_api)(const struct device *dev, + const enum display_orientation orientation); + +/** + * @brief Display driver API + * API which a display driver should expose + */ +struct display_driver_api { + display_blanking_on_api blanking_on; + display_blanking_off_api blanking_off; + display_write_api write; + display_read_api read; + display_get_framebuffer_api get_framebuffer; + display_set_brightness_api set_brightness; + display_set_contrast_api set_contrast; + display_get_capabilities_api get_capabilities; + display_set_pixel_format_api set_pixel_format; + display_set_orientation_api set_orientation; +}; +extern struct ili9340_data ili9340_data1; +extern struct display_driver_api ili9340_api1; +/** + * @brief Write data to display + * + * @param dev Pointer to device structure + * @param x x Coordinate of the upper left corner where to write the buffer + * @param y y Coordinate of the upper left corner where to write the buffer + * @param desc Pointer to a structure describing the buffer layout + * @param buf Pointer to buffer array + * + * @retval 0 on success else negative errno code. + */ +static inline int display_write(const struct device *dev, const u16_t x, + const u16_t y, const struct display_buffer_descriptor *desc, + const void *buf) +{ + struct display_driver_api *api = &ili9340_api1; + //(struct display_driver_api *)dev->driver_api; + + return api->write(dev, x, y, desc, buf); +} + +/** + * @brief Read data from display + * + * @param dev Pointer to device structure + * @param x x Coordinate of the upper left corner where to read from + * @param y y Coordinate of the upper left corner where to read from + * @param desc Pointer to a structure describing the buffer layout + * @param buf Pointer to buffer array + * + * @retval 0 on success else negative errno code. + */ +static inline int display_read(const struct device *dev, const u16_t x, + const u16_t y, const struct display_buffer_descriptor *desc, void *buf) +{ + struct display_driver_api *api = &ili9340_api1; + //(struct display_driver_api *)dev->driver_api; + + return api->read(dev, x, y, desc, buf); +} + +/** + * @brief Get pointer to framebuffer for direct access + * + * @param dev Pointer to device structure + * + * @retval Pointer to frame buffer or NULL if direct framebuffer access + * is not supported + * + */ +static inline void *display_get_framebuffer(const struct device *dev) +{ + struct display_driver_api *api = &ili9340_api1; + //(struct display_driver_api *)dev->driver_api; + + return api->get_framebuffer(dev); +} + +/** + * @brief Turn display blanking on + * + * @param dev Pointer to device structure + * + * @retval 0 on success else negative errno code. + */ +static inline int display_blanking_on(const struct device *dev) +{ + struct display_driver_api *api = &ili9340_api1; + //(struct display_driver_api *)dev->driver_api; + + return api->blanking_on(dev); +} + +/** + * @brief Turn display blanking off + * + * @param dev Pointer to device structure + * + * @retval 0 on success else negative errno code. + */ +static inline int display_blanking_off(const struct device *dev) +{ + struct display_driver_api *api = &ili9340_api1; + //(struct display_driver_api *)dev->driver_api; + + return api->blanking_off(dev); +} + +/** + * @brief Set the brightness of the display + * + * Set the brightness of the display in steps of 1/256, where 255 is full + * brightness and 0 is minimal. + * + * @param dev Pointer to device structure + * @param brightness Brightness in steps of 1/256 + * + * @retval 0 on success else negative errno code. + */ +static inline int display_set_brightness(const struct device *dev, + u8_t brightness) +{ + struct display_driver_api *api = &ili9340_api1; + //(struct display_driver_api *)dev->driver_api; + + return api->set_brightness(dev, brightness); +} + +/** + * @brief Set the contrast of the display + * + * Set the contrast of the display in steps of 1/256, where 255 is maximum + * difference and 0 is minimal. + * + * @param dev Pointer to device structure + * @param contrast Contrast in steps of 1/256 + * + * @retval 0 on success else negative errno code. + */ +static inline int display_set_contrast(const struct device *dev, u8_t contrast) +{ + struct display_driver_api *api = &ili9340_api1; + //(struct display_driver_api *)dev->driver_api; + + return api->set_contrast(dev, contrast); +} + +/** + * @brief Get display capabilities + * + * @param dev Pointer to device structure + * @param capabilities Pointer to capabilities structure to populate + */ +static inline void display_get_capabilities(const struct device *dev, + struct display_capabilities * capabilities) +{ + struct display_driver_api *api = &ili9340_api1; + //(struct display_driver_api *)dev->driver_api; + + api->get_capabilities(dev, capabilities); +} + +/** + * @brief Set pixel format used by the display + * + * @param dev Pointer to device structure + * @param pixel_format Pixel format to be used by display + * + * @retval 0 on success else negative errno code. + */ +static inline int display_set_pixel_format(const struct device *dev, + const enum display_pixel_format pixel_format) +{ + struct display_driver_api *api = &ili9340_api1; + //(struct display_driver_api *)dev->driver_api; + + return api->set_pixel_format(dev, pixel_format); +} + +/** + * @brief Set display orientation + * + * @param dev Pointer to device structure + * @param orientation Orientation to be used by display + * + * @retval 0 on success else negative errno code. + */ +static inline int display_set_orientation(const struct device *dev, + const enum display_orientation orientation) +{ + struct display_driver_api *api = &ili9340_api1; + //(struct display_driver_api *)dev->driver_api; + + return api->set_orientation(dev, orientation); +} + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DISPLAY_H_*/ diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.c b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.c new file mode 100644 index 00000000..07e77ffc --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.c @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2017 Jan Van Winkel + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "display_ili9340.h" +#include + +//#define LOG_LEVEL CONFIG_DISPLAY_LOG_LEVEL +//#include +//LOG_MODULE_REGISTER(display_ili9340); +#define LOG_ERR printf +#define LOG_DBG printf +#define LOG_WRN printf + +#include +#include +#include +#include + +struct ili9340_data { + struct device *reset_gpio; + struct device *command_data_gpio; + struct device *spi_dev; + struct spi_config spi_config; +#ifdef DT_ILITEK_ILI9340_0_CS_GPIO_CONTROLLER +struct spi_cs_control cs_ctrl; +#endif +}; + +struct ili9340_data ili9340_data1; + +#define ILI9340_CMD_DATA_PIN_COMMAND 0 +#define ILI9340_CMD_DATA_PIN_DATA 1 + +static void ili9340_exit_sleep(struct ili9340_data *data) +{ + ili9340_transmit(data, ILI9340_CMD_EXIT_SLEEP, NULL, 0); + //k_sleep(120); +} + +int ili9340_init() +{ + struct ili9340_data *data = &ili9340_data1; + printf("Initializing display driver\n"); + data->spi_dev = device_get_binding(DT_ILITEK_ILI9340_0_BUS_NAME); + if (data->spi_dev == NULL) { + return -EPERM; + } + data->spi_config.frequency = DT_ILITEK_ILI9340_0_SPI_MAX_FREQUENCY; + data->spi_config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8); //SPI_OP_MODE_MASTER | SPI_WORD_SET(8); + data->spi_config.slave = DT_ILITEK_ILI9340_0_BASE_ADDRESS; + +#ifdef DT_ILITEK_ILI9340_0_CS_GPIO_CONTROLLER + data->cs_ctrl.gpio_dev = + device_get_binding(DT_ILITEK_ILI9340_0_CS_GPIO_CONTROLLER); + data->cs_ctrl.gpio_pin = DT_ILITEK_ILI9340_0_CS_GPIO_PIN; + data->cs_ctrl.delay = 0; + data->spi_config.cs = &(data->cs_ctrl); +#else + data->spi_config.cs = NULL; +#endif + data->reset_gpio = device_get_binding( + DT_ILITEK_ILI9340_0_RESET_GPIOS_CONTROLLER); + if (data->reset_gpio == NULL) { + return -EPERM; + } + + gpio_pin_configure(data->reset_gpio, DT_ILITEK_ILI9340_0_RESET_GPIOS_PIN, + GPIO_DIR_OUT); + + data->command_data_gpio = device_get_binding( + DT_ILITEK_ILI9340_0_CMD_DATA_GPIOS_CONTROLLER); + if (data->command_data_gpio == NULL) { + return -EPERM; + } + + gpio_pin_configure(data->command_data_gpio, + DT_ILITEK_ILI9340_0_CMD_DATA_GPIOS_PIN, GPIO_DIR_OUT); + + LOG_DBG("Resetting display driver"); + gpio_pin_write(data->reset_gpio, DT_ILITEK_ILI9340_0_RESET_GPIOS_PIN, 1); + k_sleep(1); + gpio_pin_write(data->reset_gpio, DT_ILITEK_ILI9340_0_RESET_GPIOS_PIN, 0); + k_sleep(1); + gpio_pin_write(data->reset_gpio, DT_ILITEK_ILI9340_0_RESET_GPIOS_PIN, 1); + k_sleep(5); + + LOG_DBG("Initializing LCD\n"); + ili9340_lcd_init(data); + + LOG_DBG("Exiting sleep mode\n"); + ili9340_exit_sleep(data); + + return 0; +} + +static void ili9340_set_mem_area(struct ili9340_data *data, const u16_t x, + const u16_t y, const u16_t w, const u16_t h) +{ + u16_t spi_data[2]; + + spi_data[0] = sys_cpu_to_be16(x); + spi_data[1] = sys_cpu_to_be16(x + w - 1); + ili9340_transmit(data, ILI9340_CMD_COLUMN_ADDR, &spi_data[0], 4); + + spi_data[0] = sys_cpu_to_be16(y); + spi_data[1] = sys_cpu_to_be16(y + h - 1); + ili9340_transmit(data, ILI9340_CMD_PAGE_ADDR, &spi_data[0], 4); +} + +static int ili9340_write(const struct device *dev, const u16_t x, const u16_t y, + const struct display_buffer_descriptor *desc, const void *buf) +{ + struct ili9340_data *data = (struct ili9340_data *) &ili9340_data1; + const u8_t *write_data_start = (u8_t *) buf; + struct spi_buf tx_buf; + struct spi_buf_set tx_bufs; + u16_t write_cnt; + u16_t nbr_of_writes; + u16_t write_h; + + __ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width"); + __ASSERT((3 * desc->pitch * desc->height) <= desc->buf_size, + "Input buffer to small"); + ili9340_set_mem_area(data, x, y, desc->width, desc->height); + + if (desc->pitch > desc->width) { + write_h = 1U; + nbr_of_writes = desc->height; + } else { + write_h = desc->height; + nbr_of_writes = 1U; + } + ili9340_transmit(data, ILI9340_CMD_MEM_WRITE, (void *) write_data_start, + 3 * desc->width * write_h); + + tx_bufs.buffers = &tx_buf; + tx_bufs.count = 1; + + write_data_start += (3 * desc->pitch); + for (write_cnt = 1U; write_cnt < nbr_of_writes; ++write_cnt) { + tx_buf.buf = (void *) write_data_start; + tx_buf.len = 3 * desc->width * write_h; + spi_transceive(data->spi_dev, &data->spi_config, &tx_bufs, NULL); + write_data_start += (3 * desc->pitch); + } + + return 0; +} + +static int ili9340_read(const struct device *dev, const u16_t x, const u16_t y, + const struct display_buffer_descriptor *desc, void *buf) +{ + LOG_ERR("Reading not supported"); + return -ENOTSUP; +} + +static void *ili9340_get_framebuffer(const struct device *dev) +{ + LOG_ERR("Direct framebuffer access not supported"); + return NULL; +} + +static int ili9340_display_blanking_off(const struct device *dev) +{ + struct ili9340_data *data = (struct ili9340_data *) dev->driver_data; + + LOG_DBG("Turning display blanking off"); + ili9340_transmit(data, ILI9340_CMD_DISPLAY_ON, NULL, 0); + return 0; +} + +static int ili9340_display_blanking_on(const struct device *dev) +{ + struct ili9340_data *data = (struct ili9340_data *) dev->driver_data; + + LOG_DBG("Turning display blanking on"); + ili9340_transmit(data, ILI9340_CMD_DISPLAY_OFF, NULL, 0); + return 0; +} + +static int ili9340_set_brightness(const struct device *dev, + const u8_t brightness) +{ + LOG_WRN("Set brightness not implemented"); + return -ENOTSUP; +} + +static int ili9340_set_contrast(const struct device *dev, const u8_t contrast) +{ + LOG_ERR("Set contrast not supported"); + return -ENOTSUP; +} + +static int ili9340_set_pixel_format(const struct device *dev, + const enum display_pixel_format pixel_format) +{ + if (pixel_format == PIXEL_FORMAT_RGB_888) { + return 0; +} + LOG_ERR("Pixel format change not implemented"); + return -ENOTSUP; +} + +static int ili9340_set_orientation(const struct device *dev, + const enum display_orientation orientation) +{ +if (orientation == DISPLAY_ORIENTATION_NORMAL) { + return 0; +} +LOG_ERR("Changing display orientation not implemented"); + return -ENOTSUP; +} + +static void ili9340_get_capabilities(const struct device *dev, + struct display_capabilities *capabilities) +{ + memset(capabilities, 0, sizeof(struct display_capabilities)); + capabilities->x_resolution = 320; + capabilities->y_resolution = 240; + capabilities->supported_pixel_formats = PIXEL_FORMAT_RGB_888; + capabilities->current_pixel_format = PIXEL_FORMAT_RGB_888; + capabilities->current_orientation = DISPLAY_ORIENTATION_NORMAL; +} + +void ili9340_transmit(struct ili9340_data *data, u8_t cmd, void *tx_data, + size_t tx_len) +{ + int i; + char * buf1 = tx_data; + data = (struct ili9340_data *) &ili9340_data1; + struct spi_buf tx_buf = { .buf = &cmd, .len = 1 }; + struct spi_buf_set tx_bufs = { .buffers = &tx_buf, .count = 1 }; + + gpio_pin_write(data->command_data_gpio, DT_ILITEK_ILI9340_0_CMD_DATA_GPIOS_PIN, + ILI9340_CMD_DATA_PIN_COMMAND); + spi_transceive(data->spi_dev, &data->spi_config, &tx_bufs, NULL); + if (tx_data != NULL) { + tx_buf.buf = tx_data; + tx_buf.len = tx_len; + gpio_pin_write(data->command_data_gpio, + DT_ILITEK_ILI9340_0_CMD_DATA_GPIOS_PIN, + ILI9340_CMD_DATA_PIN_DATA); + spi_transceive(data->spi_dev, &data->spi_config, &tx_bufs, NULL); + } +} + +struct display_driver_api ili9340_api1 = + { .blanking_on = ili9340_display_blanking_on, .blanking_off = + ili9340_display_blanking_off, .write = ili9340_write, .read = + ili9340_read, .get_framebuffer = ili9340_get_framebuffer, + .set_brightness = ili9340_set_brightness, .set_contrast = + ili9340_set_contrast, .get_capabilities = + ili9340_get_capabilities, .set_pixel_format = + ili9340_set_pixel_format, .set_orientation = + ili9340_set_orientation, }; + +/* + DEVICE_AND_API_INIT(ili9340, DT_ILITEK_ILI9340_0_LABEL, &ili9340_init, + &ili9340_data, NULL, APPLICATION, + CONFIG_APPLICATION_INIT_PRIORITY, &ili9340_api); + */ diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.h b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.h new file mode 100644 index 00000000..8aab97a6 --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017 Jan Van Winkel + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9340_H_ +#define ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9340_H_ +#include "board_config.h" +#include +#include + +#define ILI9340_CMD_ENTER_SLEEP 0x10 +#define ILI9340_CMD_EXIT_SLEEP 0x11 +#define ILI9340_CMD_GAMMA_SET 0x26 +#define ILI9340_CMD_DISPLAY_OFF 0x28 +#define ILI9340_CMD_DISPLAY_ON 0x29 +#define ILI9340_CMD_COLUMN_ADDR 0x2a +#define ILI9340_CMD_PAGE_ADDR 0x2b +#define ILI9340_CMD_MEM_WRITE 0x2c +#define ILI9340_CMD_MEM_ACCESS_CTRL 0x36 +#define ILI9340_CMD_PIXEL_FORMAT_SET 0x3A +#define ILI9340_CMD_FRAME_CTRL_NORMAL_MODE 0xB1 +#define ILI9340_CMD_DISPLAY_FUNCTION_CTRL 0xB6 +#define ILI9340_CMD_POWER_CTRL_1 0xC0 +#define ILI9340_CMD_POWER_CTRL_2 0xC1 +#define ILI9340_CMD_VCOM_CTRL_1 0xC5 +#define ILI9340_CMD_VCOM_CTRL_2 0xC7 +#define ILI9340_CMD_POSITVE_GAMMA_CORRECTION 0xE0 +#define ILI9340_CMD_NEGATIVE_GAMMA_CORRECTION 0xE1 + +#define ILI9340_DATA_MEM_ACCESS_CTRL_MY 0x80 +#define ILI9340_DATA_MEM_ACCESS_CTRL_MX 0x40 +#define ILI9340_DATA_MEM_ACCESS_CTRL_MV 0x20 +#define ILI9340_DATA_MEM_ACCESS_CTRL_ML 0x10 +#define ILI9340_DATA_MEM_ACCESS_CTRL_BGR 0x08 +#define ILI9340_DATA_MEM_ACCESS_CTRL_MH 0x04 + +#define ILI9340_DATA_PIXEL_FORMAT_RGB_18_BIT 0x60 +#define ILI9340_DATA_PIXEL_FORMAT_RGB_16_BIT 0x50 +#define ILI9340_DATA_PIXEL_FORMAT_MCU_18_BIT 0x06 +#define ILI9340_DATA_PIXEL_FORMAT_MCU_16_BIT 0x05 + +struct ili9340_data; + +/** + * Send data to ILI9340 display controller + * + * @param data Device data structure + * @param cmd Command to send to display controller + * @param tx_data Data to transmit to the display controller + * In case no data should be transmitted pass a NULL pointer + * @param tx_len Number of bytes in tx_data buffer + * + */ +void ili9340_transmit(struct ili9340_data *data, u8_t cmd, void *tx_data, + size_t tx_len); + +/** + * Perform LCD specific initialization + * + * @param data Device data structure + */ +void ili9340_lcd_init(struct ili9340_data *data); + +#define DT_ILITEK_ILI9340_0_LABEL "DISPLAY" +#define CONFIG_DISPLAY_LOG_LEVEL 0 + +#endif /* ZEPHYR_DRIVERS_DISPLAY_DISPLAY_ILI9340_H_ */ diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340_adafruit_1480.c b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340_adafruit_1480.c new file mode 100644 index 00000000..a8581a72 --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/display_ili9340_adafruit_1480.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017 Jan Van Winkel + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "display_ili9340.h" + +void ili9340_lcd_init(struct ili9340_data *data) +{ + u8_t tx_data[15]; + + tx_data[0] = 0x23; + ili9340_transmit(data, ILI9340_CMD_POWER_CTRL_1, tx_data, 1); + + tx_data[0] = 0x10; + ili9340_transmit(data, ILI9340_CMD_POWER_CTRL_2, tx_data, 1); + + tx_data[0] = 0x3e; + tx_data[1] = 0x28; + ili9340_transmit(data, ILI9340_CMD_VCOM_CTRL_1, tx_data, 2); + + tx_data[0] = 0x86; + ili9340_transmit(data, ILI9340_CMD_VCOM_CTRL_2, tx_data, 1); + + tx_data[0] = + ILI9340_DATA_MEM_ACCESS_CTRL_MV | ILI9340_DATA_MEM_ACCESS_CTRL_BGR; + ili9340_transmit(data, ILI9340_CMD_MEM_ACCESS_CTRL, tx_data, 1); + + tx_data[0] = ILI9340_DATA_PIXEL_FORMAT_MCU_18_BIT | + ILI9340_DATA_PIXEL_FORMAT_RGB_18_BIT; + ili9340_transmit(data, ILI9340_CMD_PIXEL_FORMAT_SET, tx_data, 1); + + tx_data[0] = 0x00; + tx_data[1] = 0x18; + ili9340_transmit(data, ILI9340_CMD_FRAME_CTRL_NORMAL_MODE, tx_data, 2); + + tx_data[0] = 0x08; + tx_data[1] = 0x82; + tx_data[2] = 0x27; + ili9340_transmit(data, ILI9340_CMD_DISPLAY_FUNCTION_CTRL, tx_data, 3); + + tx_data[0] = 0x01; + ili9340_transmit(data, ILI9340_CMD_GAMMA_SET, tx_data, 1); + + tx_data[0] = 0x0F; + tx_data[1] = 0x31; + tx_data[2] = 0x2B; + tx_data[3] = 0x0C; + tx_data[4] = 0x0E; + tx_data[5] = 0x08; + tx_data[6] = 0x4E; + tx_data[7] = 0xF1; + tx_data[8] = 0x37; + tx_data[9] = 0x07; + tx_data[10] = 0x10; + tx_data[11] = 0x03; + tx_data[12] = 0x0E; + tx_data[13] = 0x09; + tx_data[14] = 0x00; + ili9340_transmit(data, ILI9340_CMD_POSITVE_GAMMA_CORRECTION, tx_data, 15); + + tx_data[0] = 0x00; + tx_data[1] = 0x0E; + tx_data[2] = 0x14; + tx_data[3] = 0x03; + tx_data[4] = 0x11; + tx_data[5] = 0x07; + tx_data[6] = 0x31; + tx_data[7] = 0xC1; + tx_data[8] = 0x48; + tx_data[9] = 0x08; + tx_data[10] = 0x0F; + tx_data[11] = 0x0C; + tx_data[12] = 0x31; + tx_data[13] = 0x36; + tx_data[14] = 0x0F; + ili9340_transmit(data, ILI9340_CMD_NEGATIVE_GAMMA_CORRECTION, tx_data, 15); +} diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c new file mode 100644 index 00000000..48681550 --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "bh_platform.h" +#include "runtime_lib.h" +#include "native_interface.h" +#include "app_manager_export.h" +#include "board_config.h" +#include "bh_common.h" +#include "bh_queue.h" +#include "bh_thread.h" +#include "bh_memory.h" +#include "runtime_sensor.h" +#include "attr_container.h" +#include "module_wasm_app.h" +#include "wasm_export.h" +#include "display.h" +#include "lvgl.h" + +extern void * thread_timer_check(void *); +extern void init_sensor_framework(); +extern int aee_host_msg_callback(void *msg, uint16_t msg_len); +extern bool touchscreen_read(lv_indev_data_t * data); +extern int ili9340_init(); +extern void xpt2046_init(void); +extern void wgl_init(); + +#include +#include +#include + +int uart_char_cnt = 0; + +static void uart_irq_callback(struct device *dev) +{ + unsigned char ch; + + while (uart_poll_in(dev, &ch) == 0) { + uart_char_cnt++; + aee_host_msg_callback(&ch, 1); + } +} + +struct device *uart_dev = NULL; + +static bool host_init() +{ + uart_dev = device_get_binding(HOST_DEVICE_COMM_UART_NAME); + if (!uart_dev) { + printf("UART: Device driver not found.\n"); + return false; + } + uart_irq_rx_enable(uart_dev); + uart_irq_callback_set(uart_dev, uart_irq_callback); + return true; +} + +int host_send(void * ctx, const char *buf, int size) +{ + if (!uart_dev) + return 0; + + for (int i = 0; i < size; i++) + uart_poll_out(uart_dev, buf[i]); + + return size; +} + +void host_destroy() +{ +} + +host_interface interface = { + .init = host_init, + .send = host_send, + .destroy = host_destroy +}; + +timer_ctx_t timer_ctx; + +static char global_heap_buf[270 * 1024] = { 0 }; + +static uint8_t color_copy[320 * 10 * 3]; + +static void display_flush(lv_disp_drv_t *disp_drv, + const lv_area_t *area, + lv_color_t *color) +{ + u16_t w = area->x2 - area->x1 + 1; + u16_t h = area->y2 - area->y1 + 1; + struct display_buffer_descriptor desc; + int i; + uint8_t *color_p = color_copy; + + desc.buf_size = 3 * w * h; + desc.width = w; + desc.pitch = w; + desc.height = h; + + for (i = 0; i < w * h; i++, color++) { + color_p[i * 3] = color->ch.red; + color_p[i * 3 + 1] = color->ch.green; + color_p[i * 3 + 2] = color->ch.blue; + } + + display_write(NULL, area->x1, area->y1, &desc, (void *) color_p); + + lv_disp_flush_ready(disp_drv); /* in v5.3 is lv_flush_ready */ +} + +static bool display_input_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) +{ + return touchscreen_read(data); +} + +/** + * Initialize the Hardware Abstraction Layer (HAL) for the Littlev graphics library + */ +static void hal_init(void) +{ + xpt2046_init(); + ili9340_init(); + display_blanking_off(NULL); + + /*Create a display buffer*/ + static lv_disp_buf_t disp_buf1; + static lv_color_t buf1_1[320*10]; + lv_disp_buf_init(&disp_buf1, buf1_1, NULL, 320*10); + + /*Create a display*/ + lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); /*Basic initialization*/ + disp_drv.buffer = &disp_buf1; + disp_drv.flush_cb = display_flush; + // disp_drv.hor_res = 200; + // disp_drv.ver_res = 100; + lv_disp_drv_register(&disp_drv); + + lv_indev_drv_t indev_drv; + lv_indev_drv_init(&indev_drv); /*Basic initialization*/ + indev_drv.type = LV_INDEV_TYPE_POINTER; + indev_drv.read_cb = display_input_read; + lv_indev_drv_register(&indev_drv); +} + +int iwasm_main() +{ + host_init(); + + if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf)) + != 0) { + printf("Init global heap failed.\n"); + return -1; + } + + if (vm_thread_sys_init() != 0) { + goto fail1; + } + + wgl_init(); + hal_init(); + + // timer manager + init_wasm_timer(); + + // TODO: + app_manager_startup(&interface); + +fail1: + bh_memory_destroy(); + return -1; +} diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/main.c b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/main.c new file mode 100644 index 00000000..708c8ffa --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/main.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "bh_platform.h" +#include "wasm_assert.h" +#include "wasm_log.h" +#include "wasm_platform_log.h" +#include "wasm_thread.h" +#include "wasm_export.h" +#include "wasm_memory.h" +#include "bh_memory.h" + +extern int iwasm_main(); + +void main(void) +{ + iwasm_main(); + for(;;){ + k_sleep(1000); + } +} + diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/pin_config_jlf.h b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/pin_config_jlf.h new file mode 100644 index 00000000..5381b72d --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/pin_config_jlf.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __PIN_CONFIG_JLF_H__ +#define __PIN_CONFIG_JLF_H__ + +#define DT_ILITEK_ILI9340_0_BUS_NAME "SPI_2" +#define DT_ILITEK_ILI9340_0_SPI_MAX_FREQUENCY 10*1000 + +#define DT_ILITEK_ILI9340_0_BASE_ADDRESS 1 +#define DT_ILITEK_ILI9340_0_RESET_GPIOS_CONTROLLER "GPIO_0" +#define DT_ILITEK_ILI9340_0_RESET_GPIOS_PIN 5 +#define DT_ILITEK_ILI9340_0_CMD_DATA_GPIOS_CONTROLLER "GPIO_0" +#define DT_ILITEK_ILI9340_0_CMD_DATA_GPIOS_PIN 4 + +#define XPT2046_SPI_DEVICE_NAME "SPI_2" +#define XPT2046_SPI_MAX_FREQUENCY 10*1000 +#define XPT2046_CS_GPIO_CONTROLLER "GPIO_0" +#define XPT2046_CS_GPIO_PIN 6 + +#define XPT2046_PEN_GPIO_CONTROLLER "GPIO_0" +#define XPT2046_PEN_GPIO_PIN 7 + +#define HOST_DEVICE_COMM_UART_NAME "UART_1" +#endif /* __PIN_CONFIG_JLF_H__ */ diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/pin_config_stm32.h b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/pin_config_stm32.h new file mode 100644 index 00000000..0ab295eb --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/pin_config_stm32.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __PIN_CONFIG_STM32_H__ +#define __PIN_CONFIG_STM32_H__ + +#define DT_ILITEK_ILI9340_0_BUS_NAME "SPI_1" +#define DT_ILITEK_ILI9340_0_SPI_MAX_FREQUENCY 24*1000*1000 + +#define DT_ILITEK_ILI9340_0_BASE_ADDRESS 1 +#define DT_ILITEK_ILI9340_0_RESET_GPIOS_CONTROLLER "GPIOC" +#define DT_ILITEK_ILI9340_0_RESET_GPIOS_PIN 12 +#define DT_ILITEK_ILI9340_0_CMD_DATA_GPIOS_CONTROLLER "GPIOC" +#define DT_ILITEK_ILI9340_0_CMD_DATA_GPIOS_PIN 11 + +#define DT_ILITEK_ILI9340_0_CS_GPIO_CONTROLLER "GPIOC" +#define DT_ILITEK_ILI9340_0_CS_GPIO_PIN 10 + +#define XPT2046_SPI_DEVICE_NAME "SPI_1" +#define XPT2046_SPI_MAX_FREQUENCY 12*1000*1000 +#define XPT2046_CS_GPIO_CONTROLLER "GPIOD" +#define XPT2046_CS_GPIO_PIN 0 + +#define XPT2046_PEN_GPIO_CONTROLLER "GPIOD" +#define XPT2046_PEN_GPIO_PIN 1 + +#define HOST_DEVICE_COMM_UART_NAME "UART_6" + +#endif /* __PIN_CONFIG_STM32_H__ */ diff --git a/samples/gui/wasm-runtime-wgl/zephyr-build/CMakeLists.txt b/samples/gui/wasm-runtime-wgl/zephyr-build/CMakeLists.txt new file mode 100644 index 00000000..8794324e --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/zephyr-build/CMakeLists.txt @@ -0,0 +1,127 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required(VERSION 3.8.2) + +include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) +project(NONE) + +enable_language (ASM) + +zephyr_compile_definitions (-DNVALGRIND + -D__JLF__ + -D__ZEPHYR__ + -DWASM_ENABLE_BASE_LIB + -Dattr_container_malloc=bh_malloc + -Dattr_container_free=bh_free) + +set (IWASM_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/core/iwasm) +set (APP_MGR_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/core/app-mgr) +set (SHARED_LIB_ROOT ${IWASM_ROOT}/../shared-lib) + +target_include_directories(app PRIVATE ${IWASM_ROOT}/runtime/include + ${IWASM_ROOT}/runtime/platform/zephyr + ${IWASM_ROOT}/runtime/platform/include + ${IWASM_ROOT}/runtime/utils + ${IWASM_ROOT}/runtime/vmcore-wasm + ${IWASM_ROOT}/lib/native/base + ${IWASM_ROOT}/lib/native/libc + ${IWASM_ROOT}/lib/native/extension/sensor + ${IWASM_ROOT}/lib/native/extension/connection + ${IWASM_ROOT}/lib/native/extension/gui + ${IWASM_ROOT}/lib/native-interface + ${IWASM_ROOT}/lib/3rdparty + ${IWASM_ROOT}/lib/3rdparty/lvgl + ${IWASM_ROOT}/lib/3rdparty/lvgl/src + ${APP_MGR_ROOT}/app-manager + ${APP_MGR_ROOT}/app-mgr-shared + ${SHARED_LIB_ROOT}/include + ${SHARED_LIB_ROOT}/platform/include + ${SHARED_LIB_ROOT}/platform/zephyr + ${SHARED_LIB_ROOT}/mem-alloc/ems + ${SHARED_LIB_ROOT}/utils + ${SHARED_LIB_ROOT}/coap/er-coap + ${SHARED_LIB_ROOT}/coap/extension + ${CMAKE_CURRENT_SOURCE_DIR}/../src + ${CMAKE_CURRENT_SOURCE_DIR}/../src/platform/zephyr + ) + +file (GLOB_RECURSE GUI_SRC ${IWASM_ROOT}/lib/native/extension/gui/*.c ${IWASM_ROOT}/lib/3rdparty/lvgl/*.c) + +set (IWASM_SRCS + ${IWASM_ROOT}/runtime/platform/zephyr/wasm_native.c + ${IWASM_ROOT}/runtime/utils/wasm_dlfcn.c + ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c + ${IWASM_ROOT}/runtime/utils/wasm_log.c + ${IWASM_ROOT}/runtime/utils/wasm_vector.c + ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_application.c + ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_interp.c + ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_loader.c + ${IWASM_ROOT}/runtime/vmcore-wasm/wasm_runtime.c + ${IWASM_ROOT}/runtime/vmcore-wasm/invokeNative_general.c + ${IWASM_ROOT}/lib/native/base/base_lib_export.c + ${IWASM_ROOT}/lib/native/base/request_response.c + ${IWASM_ROOT}/lib/native/base/timer_wrapper.c + ${IWASM_ROOT}/lib/native/libc/libc_wrapper.c + ${IWASM_ROOT}/lib/native/extension/sensor/runtime_sensor.c + ${IWASM_ROOT}/lib/native/extension/connection/connection_wrapper.c + ${IWASM_ROOT}/lib/native/extension/connection/zephyr/connection_lib_impl.c + ${GUI_SRC} + ${IWASM_ROOT}/lib/native-interface/attr_container.c + ${IWASM_ROOT}/lib/native-interface/restful_utils.c + ${APP_MGR_ROOT}/app-manager/app_manager.c + ${APP_MGR_ROOT}/app-manager/app_manager_host.c + ${APP_MGR_ROOT}/app-manager/ble_msg.c + ${APP_MGR_ROOT}/app-manager/event.c + ${APP_MGR_ROOT}/app-manager/message.c + ${APP_MGR_ROOT}/app-manager/module_jeff.c + ${APP_MGR_ROOT}/app-manager/module_utils.c + ${APP_MGR_ROOT}/app-manager/module_wasm_app.c + ${APP_MGR_ROOT}/app-manager/module_wasm_lib.c + ${APP_MGR_ROOT}/app-manager/resource_reg.c + ${APP_MGR_ROOT}/app-manager/watchdog.c + ${APP_MGR_ROOT}/app-manager/platform/zephyr/app_mgr_zephyr.c + ${SHARED_LIB_ROOT}/platform/zephyr/bh_assert.c + ${SHARED_LIB_ROOT}/platform/zephyr/bh_definition.c + ${SHARED_LIB_ROOT}/platform/zephyr/bh_platform.c + ${SHARED_LIB_ROOT}/platform/zephyr/bh_platform_log.c + ${SHARED_LIB_ROOT}/platform/zephyr/bh_thread.c + ${SHARED_LIB_ROOT}/platform/zephyr/bh_time.c + ${SHARED_LIB_ROOT}/platform/zephyr/bh_math.c + ${SHARED_LIB_ROOT}/mem-alloc/bh_memory.c + ${SHARED_LIB_ROOT}/mem-alloc/mem_alloc.c + ${SHARED_LIB_ROOT}/mem-alloc/ems/ems_alloc.c + ${SHARED_LIB_ROOT}/mem-alloc/ems/ems_hmu.c + ${SHARED_LIB_ROOT}/mem-alloc/ems/ems_kfc.c + ${SHARED_LIB_ROOT}/mem-alloc/tlsf/tlsf.c + ${SHARED_LIB_ROOT}/utils/bh_list.c + ${SHARED_LIB_ROOT}/utils/bh_log.c + ${SHARED_LIB_ROOT}/utils/bh_queue.c + ${SHARED_LIB_ROOT}/utils/runtime_timer.c + ${SHARED_LIB_ROOT}/coap/er-coap/er-coap.c + ${SHARED_LIB_ROOT}/coap/extension/coap_conversion.c + ${SHARED_LIB_ROOT}/coap/extension/coap_over_tcp.c + ) + + set (LVGL_DRV_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/../src/platform/zephyr/display_ili9340_adafruit_1480.c + ${CMAKE_CURRENT_SOURCE_DIR}/../src/platform/zephyr/display_ili9340.c + ${CMAKE_CURRENT_SOURCE_DIR}/../src/platform/zephyr/XPT2046.c + ) + +target_sources(app PRIVATE ${IWASM_SRCS} + ${LVGL_DRV_SRCS} + ${CMAKE_CURRENT_SOURCE_DIR}/../src/platform/zephyr/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/../src/platform/zephyr/iwasm_main.c + ${CMAKE_CURRENT_SOURCE_DIR}/../src/ext_lib_export.c) diff --git a/samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf b/samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf new file mode 100644 index 00000000..79d89205 --- /dev/null +++ b/samples/gui/wasm-runtime-wgl/zephyr-build/prj.conf @@ -0,0 +1,9 @@ +CONFIG_SPI=y +CONFIG_SPI_STM32=y +CONFIG_SPI_1=y +CONFIG_PRINTK=y +CONFIG_LOG=y +#CONFIG_UART_2=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_STACK_SENTINEL=y +CONFIG_MAIN_STACK_SIZE=2048 diff --git a/samples/littlevgl/README.md b/samples/littlevgl/README.md index 006b6624..18e2527f 100644 --- a/samples/littlevgl/README.md +++ b/samples/littlevgl/README.md @@ -21,19 +21,38 @@ The sample also provides the native Linux version of application without the run The number on top will plus one each second, and the number on the bottom will plus one when clicked. +Configure 32 bit or 64 bit build +============== +On 64 bit operating system, there is an option to build 32 bit or 64 bit binaries. In file `./vgl-native-ui-app/CMakeLists.txt` and/or `./vgl-wasm-runtime/CMakeLists.txt` , modify the line: +`set (BUILD_AS_64BIT_SUPPORT "YES")` + where `YES` means 64 bit build while `NO` means 32 bit build. + Install required SDK and libraries ============== -- 32 bit SDL(simple directmedia layer) -Use apt-get
- `sudo apt-get install libsdl2-dev:i386`
-Or download source from www.libsdl.org
- `./configure C_FLAGS=-m32 CXX_FLAGS=-m32 LD_FLAGS=-m32`
- `make`
- `sudo make install`
+- 32 bit SDL(simple directmedia layer) (Note: only necessary when `BUILD_AS_64BIT_SUPPORT` is set to `NO`) +Use apt-get: + `sudo apt-get install libsdl2-dev:i386` +Or download source from www.libsdl.org: +``` +./configure C_FLAGS=-m32 CXX_FLAGS=-m32 LD_FLAGS=-m32 +make +sudo make install +``` +- 64 bit SDL(simple directmedia layer) (Note: only necessary when `BUILD_AS_64BIT_SUPPORT` is set to `YES`) +Use apt-get: + `sudo apt-get install libsdl2-dev` +Or download source from www.libsdl.org: +``` +./configure +make +sudo make install +``` + - Install EMSDK -
+```
     https://emscripten.org/docs/tools_reference/emsdk.html
-
+``` + Build and Run ============== @@ -42,7 +61,7 @@ Linux -------------------------------- - Build
`./build.sh`
- All binaries are in "out", which contains "host_tool", "vgl_native_ui_app", "TestApplet1.wasm" and "vgl_wasm_runtime". + All binaries are in "out", which contains "host_tool", "vgl_native_ui_app", "ui_app.wasm" and "vgl_wasm_runtime". - Run native Linux application
`./vgl_native_ui_app`
diff --git a/samples/littlevgl/build.sh b/samples/littlevgl/build.sh index cc1b72bb..7bdae298 100755 --- a/samples/littlevgl/build.sh +++ b/samples/littlevgl/build.sh @@ -18,6 +18,12 @@ if [ ! -d "tlsf" ]; then git clone https://github.com/mattconte/tlsf fi +cd ${WAMR_DIR}/core/iwasm/lib/3rdparty +if [ ! -d "lvgl" ]; then + git clone https://github.com/littlevgl/lvgl.git --branch v6.0.1 +fi + + echo "##################### 1. build native-ui-app start#####################" cd $BUILD_DIR mkdir -p vgl-native-ui-app @@ -32,6 +38,17 @@ echo $PWD cp vgl_native_ui_app ${OUT_DIR} echo "#####################build native-ui-app success" + +echo "##################### 2. build littlevgl wasm runtime start#####################" +cd $BUILD_DIR +mkdir -p vgl-wasm-runtime +cd vgl-wasm-runtime +cmake ${PROJECT_DIR}/vgl-wasm-runtime +make +cp vgl_wasm_runtime ${OUT_DIR}/ + +echo "##################### build littlevgl wasm runtime end#####################" + echo "#####################build host-tool" cd $BUILD_DIR mkdir -p host-tool @@ -46,17 +63,6 @@ cp host_tool ${OUT_DIR} echo "#####################build host-tool success" -echo "##################### 2. build littlevgl wasm runtime start#####################" -cd $BUILD_DIR -mkdir -p vgl-wasm-runtime -cd vgl-wasm-runtime -cmake ${PROJECT_DIR}/vgl-wasm-runtime -make -cp vgl_wasm_runtime ${OUT_DIR}/ - -echo "##################### build littlevgl wasm runtime end#####################" - - echo "##################### 3. build wasm ui app start#####################" cd ${PROJECT_DIR}/wasm-apps if [ ! -d "${PROJECT_DIR}/wasm-apps/lvgl" ]; then diff --git a/samples/littlevgl/vgl-native-ui-app/CMakeLists.txt b/samples/littlevgl/vgl-native-ui-app/CMakeLists.txt index 56e9d5de..78f64645 100644 --- a/samples/littlevgl/vgl-native-ui-app/CMakeLists.txt +++ b/samples/littlevgl/vgl-native-ui-app/CMakeLists.txt @@ -17,7 +17,22 @@ message ("vgl_native_ui_app...") project (vgl_native_ui_app) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -g -DLV_CONF_INCLUDE_SIMPLE -DPLATFORM_NATIVE_LINUX -DUSE_MONITOR -DUSE_MOUSE=1") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLV_CONF_INCLUDE_SIMPLE -DPLATFORM_NATIVE_LINUX -DUSE_MONITOR -DUSE_MOUSE=1") + +# Currently build as 64-bit by default. Set to "NO" to build 32-bit binaries. +set (BUILD_AS_64BIT_SUPPORT "YES") + +if (CMAKE_SIZEOF_VOID_P EQUAL 8) + if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES") + # Add -fPIC flag if build as 64-bit + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC") + else () + add_definitions (-m32) + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") + set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32") + endif () +endif () set(lv_name lvgl) set(LVGL_SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${lv_name}) diff --git a/samples/littlevgl/vgl-wasm-runtime/CMakeLists.txt b/samples/littlevgl/vgl-wasm-runtime/CMakeLists.txt index 719f866b..69114070 100644 --- a/samples/littlevgl/vgl-wasm-runtime/CMakeLists.txt +++ b/samples/littlevgl/vgl-wasm-runtime/CMakeLists.txt @@ -15,8 +15,8 @@ if (NOT ("$ENV{VALGRIND}" STREQUAL "YES")) add_definitions(-DNVALGRIND) endif () -# Currently build as 32-bit by default. -set (BUILD_AS_64BIT_SUPPORT "NO") +# Currently build as 64-bit by default. +set (BUILD_AS_64BIT_SUPPORT "YES") if (CMAKE_SIZEOF_VOID_P EQUAL 8) if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES") @@ -57,6 +57,8 @@ include (${WASM_DIR}/runtime/vmcore-wasm/vmcore.cmake) include (${WASM_DIR}/lib/native/base/wasm_lib_base.cmake) include (${WASM_DIR}/lib/native/libc/wasm_libc.cmake) include (${WASM_DIR}/lib/native/extension/sensor/wasm_lib_sensor.cmake) +include (${WASM_DIR}/lib/native/extension/connection/wasm_lib_conn.cmake) +include (${WASM_DIR}/lib/native/extension/connection/${TARGET_PLATFORM}/connection_mgr.cmake) include (${WASM_DIR}/lib/native-interface/native_interface.cmake) include (${APP_MGR_DIR}/app-manager/app_mgr.cmake) include (${APP_MGR_DIR}/app-mgr-shared/app_mgr_shared.cmake) @@ -81,6 +83,8 @@ add_library (vmlib ${WASM_LIB_BASE_SOURCE} ${WASM_LIB_EXT_SOURCE} ${WASM_LIB_SENSOR_SOURCE} + ${WASM_LIB_CONN_SOURCE} + ${WASM_LIB_CONN_MGR_SOURCE} ${PLATFORM_SHARED_SOURCE} ${UTILS_SHARED_SOURCE} ${MEM_ALLOC_SHARED_SOURCE} diff --git a/samples/littlevgl/vgl-wasm-runtime/src/ext_lib_export.c b/samples/littlevgl/vgl-wasm-runtime/src/ext_lib_export.c index 8927493a..3897b3b0 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/ext_lib_export.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/ext_lib_export.c @@ -1,8 +1,11 @@ #include "lib_export.h" #include "native_interface.h" +#include "connection_api.h" #include "display_indev.h" + static NativeSymbol extended_native_symbol_defs[] = { #include "runtime_sensor.inl" +#include "connection.inl" EXPORT_WASM_API(display_init), EXPORT_WASM_API(display_input_read), EXPORT_WASM_API(display_flush), diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/display_indev.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/display_indev.c index 6aeaec19..f7d8b5cc 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/display_indev.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/display_indev.c @@ -186,12 +186,29 @@ void display_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, bool display_input_read(int32 data_p_offset) { + bool ret; wasm_module_inst_t module_inst = wasm_runtime_get_current_module_inst(); if (!wasm_runtime_validate_app_addr(module_inst, data_p_offset, 1)) return false; - lv_indev_data_t * data = wasm_runtime_addr_app_to_native(module_inst, - data_p_offset); - return mouse_read(data); + + struct { + lv_point_t point; + int32 user_data_offset; + uint8 state; + } *data_app; + + lv_indev_data_t data; + + ret = mouse_read(&data); + + data_app = wasm_runtime_addr_app_to_native(module_inst, + data_p_offset); + + data_app->point = data.point; + data_app->user_data_offset = (int32_t)data.user_data; + data_app->state = data.state; + + return ret; } void display_deinit(void) diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c index c5d23b05..68b42b3c 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c @@ -46,6 +46,7 @@ static int baudrate = B115200; extern void * thread_timer_check(void *); extern void init_sensor_framework(); extern int aee_host_msg_callback(void *msg, uint16_t msg_len); +extern bool init_connection_framework(); #ifndef CONNECTION_UART int listenfd = -1; @@ -342,7 +343,11 @@ static host_interface interface = { .send = uart_send, .destroy = uart_destroy } #endif +#ifdef __x86_64__ +static char global_heap_buf[300 * 1024] = { 0 }; +#else static char global_heap_buf[270 * 1024] = { 0 }; +#endif static void showUsage() { @@ -441,6 +446,12 @@ int iwasm_main(int argc, char *argv[]) if (vm_thread_sys_init() != 0) { goto fail1; } + + if (!init_connection_framework()) { + vm_thread_sys_destroy(); + goto fail1; + } + extern void display_SDL_init(); display_SDL_init(); diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c index 1fc3eb94..64e27d71 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c @@ -55,7 +55,7 @@ static bool host_init() uart_dev = device_get_binding(HOST_DEVICE_COMM_UART_NAME); if (!uart_dev) { printf("UART: Device driver not found.\n"); - return; + return false; } uart_irq_rx_enable(uart_dev); uart_irq_callback_set(uart_dev, uart_irq_callback); @@ -64,6 +64,9 @@ static bool host_init() int host_send(void * ctx, const char *buf, int size) { + if (!uart_dev) + return 0; + for (int i = 0; i < size; i++) uart_poll_out(uart_dev, buf[i]); diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/main.c index a4313df9..2b91f0b4 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/main.c @@ -16,9 +16,9 @@ #include #include +#include "bh_platform.h" #include "wasm_assert.h" #include "wasm_log.h" -#include "wasm_platform.h" #include "wasm_platform_log.h" #include "wasm_thread.h" #include "wasm_export.h" diff --git a/samples/littlevgl/vgl-wasm-runtime/zephyr-build/CMakeLists.txt b/samples/littlevgl/vgl-wasm-runtime/zephyr-build/CMakeLists.txt index bb5948ed..a564c6aa 100644 --- a/samples/littlevgl/vgl-wasm-runtime/zephyr-build/CMakeLists.txt +++ b/samples/littlevgl/vgl-wasm-runtime/zephyr-build/CMakeLists.txt @@ -38,6 +38,7 @@ target_include_directories(app PRIVATE ${IWASM_ROOT}/runtime/include ${IWASM_ROOT}/lib/native/base ${IWASM_ROOT}/lib/native/libc ${IWASM_ROOT}/lib/native/extension/sensor + ${IWASM_ROOT}/lib/native/extension/connection ${IWASM_ROOT}/lib/native-interface ${APP_MGR_ROOT}/app-manager ${APP_MGR_ROOT}/app-mgr-shared @@ -52,9 +53,8 @@ target_include_directories(app PRIVATE ${IWASM_ROOT}/runtime/include ${CMAKE_CURRENT_SOURCE_DIR}/../src/platform/zephyr ) -set (IWASM_SRCS ${IWASM_ROOT}/runtime/platform/zephyr/wasm_math.c +set (IWASM_SRCS ${IWASM_ROOT}/runtime/platform/zephyr/wasm_native.c - ${IWASM_ROOT}/runtime/platform/zephyr/wasm_platform.c ${IWASM_ROOT}/runtime/utils/wasm_dlfcn.c ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c ${IWASM_ROOT}/runtime/utils/wasm_log.c @@ -69,6 +69,8 @@ set (IWASM_SRCS ${IWASM_ROOT}/runtime/platform/zephyr/wasm_math.c ${IWASM_ROOT}/lib/native/base/timer_wrapper.c ${IWASM_ROOT}/lib/native/libc/libc_wrapper.c ${IWASM_ROOT}/lib/native/extension/sensor/runtime_sensor.c + ${IWASM_ROOT}/lib/native/extension/connection/connection_wrapper.c + ${IWASM_ROOT}/lib/native/extension/connection/zephyr/connection_lib_impl.c ${IWASM_ROOT}/lib/native-interface/attr_container.c ${IWASM_ROOT}/lib/native-interface/restful_utils.c ${APP_MGR_ROOT}/app-manager/app_manager.c @@ -89,6 +91,7 @@ set (IWASM_SRCS ${IWASM_ROOT}/runtime/platform/zephyr/wasm_math.c ${SHARED_LIB_ROOT}/platform/zephyr/bh_platform_log.c ${SHARED_LIB_ROOT}/platform/zephyr/bh_thread.c ${SHARED_LIB_ROOT}/platform/zephyr/bh_time.c + ${SHARED_LIB_ROOT}/platform/zephyr/bh_math.c ${SHARED_LIB_ROOT}/mem-alloc/bh_memory.c ${SHARED_LIB_ROOT}/mem-alloc/mem_alloc.c ${SHARED_LIB_ROOT}/mem-alloc/ems/ems_alloc.c diff --git a/samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf b/samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf index 2375969e..79d89205 100644 --- a/samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf +++ b/samples/littlevgl/vgl-wasm-runtime/zephyr-build/prj.conf @@ -5,3 +5,5 @@ CONFIG_PRINTK=y CONFIG_LOG=y #CONFIG_UART_2=y CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_STACK_SENTINEL=y +CONFIG_MAIN_STACK_SIZE=2048 diff --git a/samples/littlevgl/wasm-apps/Makefile_wasm_app b/samples/littlevgl/wasm-apps/Makefile_wasm_app index dcf7f172..225a7a87 100644 --- a/samples/littlevgl/wasm-apps/Makefile_wasm_app +++ b/samples/littlevgl/wasm-apps/Makefile_wasm_app @@ -14,7 +14,18 @@ CC = emcc LVGL_DIR = ${shell pwd} -CFLAGS += -O3 -DLV_CONF_INCLUDE_SIMPLE=1 -I$(LVGL_DIR)/ -I$(LVGL_DIR)/lvgl/ -I$(LVGL_DIR)/lv_drivers/ -I$(LVGL_DIR)/src/ -I../../../core/iwasm/lib/app-libs/base/ -I../../../core/iwasm/lib/native-interface/ -I../../../core/iwasm/lib/app-libs/extension/sensor +IWASM_DIR=../../../core/iwasm +CFLAGS += -O3 \ + -DLV_CONF_INCLUDE_SIMPLE=1 \ + -I$(LVGL_DIR)/ \ + -I$(LVGL_DIR)/lvgl/ \ + -I$(LVGL_DIR)/lv_drivers/ \ + -I$(LVGL_DIR)/src/ \ + -I$(IWASM_DIR)/lib/app-libs/base/ \ + -I$(IWASM_DIR)/lib/native-interface/ \ + -I$(IWASM_DIR)/lib/app-libs/extension/sensor \ + -I$(IWASM_DIR)/lib/app-libs/extension/gui \ + -I$(IWASM_DIR)/lib/app-libs/extension/connection SRCS += lvgl/lv_draw/lv_draw_line.c lvgl/lv_draw/lv_draw_rbasic.c SRCS += lvgl/lv_draw/lv_draw_img.c lvgl/lv_draw/lv_draw_arc.c @@ -46,10 +57,11 @@ SRCS += lvgl/lv_core/lv_group.c lvgl/lv_core/lv_style.c lvgl/lv_core/lv_indev.c SRCS += lvgl/lv_core/lv_vdb.c lvgl/lv_core/lv_obj.c lvgl/lv_core/lv_refr.c SRCS += $(LVGL_DIR)/src/main.c -SRCS += ../../../core/iwasm/lib/app-libs/base/timer.c +# For app size consideration, not all but necessary app libs are included +SRCS += $(IWASM_DIR)/lib/app-libs/base/timer.c all: @$(CC) $(CFLAGS) $(SRCS) \ -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ -s TOTAL_MEMORY=65536 -s TOTAL_STACK=2048\ - -s "EXPORTED_FUNCTIONS=['_on_init', '_on_request', '_on_sensor_event', '_on_timer_callback']" \ + -s "EXPORTED_FUNCTIONS=['_on_init', '_on_timer_callback']" \ -o ui_app.wasm diff --git a/samples/simple/CMakeLists.txt b/samples/simple/CMakeLists.txt index 01fade44..e5c4e18b 100644 --- a/samples/simple/CMakeLists.txt +++ b/samples/simple/CMakeLists.txt @@ -15,8 +15,8 @@ if (NOT ("$ENV{VALGRIND}" STREQUAL "YES")) add_definitions(-DNVALGRIND) endif () -# Currently build as 32-bit by default. -set (BUILD_AS_64BIT_SUPPORT "NO") +# Currently build as 64-bit by default. +set (BUILD_AS_64BIT_SUPPORT "YES") if (CMAKE_SIZEOF_VOID_P EQUAL 8) if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES") @@ -48,6 +48,10 @@ set(WASM_DIR ${WAMR_ROOT_DIR}/core/iwasm) set(APP_MGR_DIR ${WAMR_ROOT_DIR}/core/app-mgr) set(SHARED_DIR ${WAMR_ROOT_DIR}/core/shared-lib) +set (LV_DRIVERS_DIR ${WASM_DIR}/lib/3rdparty/lv_drivers) +set (LVGL_DIR ${WASM_DIR}/lib/3rdparty/lvgl) + +file(GLOB_RECURSE LV_DRIVERS_SOURCES "${LV_DRIVERS_DIR}/*.c" ) enable_language (ASM) @@ -57,6 +61,9 @@ include (${WASM_DIR}/runtime/vmcore-wasm/vmcore.cmake) include (${WASM_DIR}/lib/native/base/wasm_lib_base.cmake) include (${WASM_DIR}/lib/native/libc/wasm_libc.cmake) include (${WASM_DIR}/lib/native/extension/sensor/wasm_lib_sensor.cmake) +include (${WASM_DIR}/lib/native/extension/gui/wasm_lib_gui.cmake) +include (${WASM_DIR}/lib/native/extension/connection/wasm_lib_conn.cmake) +include (${WASM_DIR}/lib/native/extension/connection/${TARGET_PLATFORM}/connection_mgr.cmake) include (${WASM_DIR}/lib/native-interface/native_interface.cmake) include (${APP_MGR_DIR}/app-manager/app_mgr.cmake) include (${APP_MGR_DIR}/app-mgr-shared/app_mgr_shared.cmake) @@ -67,12 +74,14 @@ include (${SHARED_DIR}/coap/lib_coap.cmake) include_directories(${SHARED_DIR}/include) +include_directories(${CMAKE_CURRENT_LIST_DIR}/src) #Note: uncomment below line to use UART mode #add_definitions (-DCONNECTION_UART) add_definitions (-DWASM_ENABLE_BASE_LIB) add_definitions (-Dattr_container_malloc=bh_malloc) add_definitions (-Dattr_container_free=bh_free) +add_definitions (-DLV_CONF_INCLUDE_SIMPLE) add_library (vmlib ${WASM_PLATFORM_LIB_SOURCE} @@ -83,13 +92,16 @@ add_library (vmlib ${WASM_LIB_BASE_SOURCE} ${WASM_LIB_EXT_SOURCE} ${WASM_LIB_SENSOR_SOURCE} + ${WASM_LIB_GUI_SOURCE} + ${WASM_LIB_CONN_SOURCE} + ${WASM_LIB_CONN_MGR_SOURCE} ${PLATFORM_SHARED_SOURCE} ${UTILS_SHARED_SOURCE} ${MEM_ALLOC_SHARED_SOURCE} ${NATIVE_INTERFACE_SOURCE} ) -add_executable (simple src/main.c src/iwasm_main.c src/ext_lib_export.c) + add_executable (simple src/main.c src/iwasm_main.c src/ext_lib_export.c ${LV_DRIVERS_SOURCES}) -target_link_libraries (simple vmlib -lm -ldl -lpthread) +target_link_libraries (simple vmlib -lm -ldl -lpthread -lSDL2) diff --git a/samples/simple/README.md b/samples/simple/README.md index b17dd9eb..2f8626c1 100644 --- a/samples/simple/README.md +++ b/samples/simple/README.md @@ -16,18 +16,14 @@ simple/ │   ├── iwasm_main.c │   └── main.c └── wasm-apps - ├── event_publisher - │   └── event_publisher.c - ├── event_subscriber - │   └── event_subscriber.c - ├── request_handler - │   └── request_handler.c - ├── request_sender - │   └── request_sender.c - ├── sensor - │   └── sensor.c - └── timer -    └── timer.c + ├── connection.c + ├── event_publisher.c + ├── event_subscriber.c + ├── gui.c + ├── request_handler.c + ├── request_sender.c + ├── sensor.c + └── timer.c ``` - build.sh
@@ -68,6 +64,38 @@ The `host_init_func` is called when the application manager starts up. And `host - wasm-apps
Source files of sample wasm applications. +Configure 32 bit or 64 bit build +============== +On 64 bit operating system, there is an option to build 32 bit or 64 bit binaries. In file `CMakeLists.txt`, modify the line: +`set (BUILD_AS_64BIT_SUPPORT "YES")` + where `YES` means 64 bit build while `NO` means 32 bit build. + +Install required SDK and libraries +============== +- 32 bit SDL(simple directmedia layer) (Note: only necessary when `BUILD_AS_64BIT_SUPPORT` is set to `NO`) +Use apt-get: + `sudo apt-get install libsdl2-dev:i386` +Or download source from www.libsdl.org: +``` +./configure C_FLAGS=-m32 CXX_FLAGS=-m32 LD_FLAGS=-m32 +make +sudo make install +``` +- 64 bit SDL(simple directmedia layer) (Note: only necessary when `BUILD_AS_64BIT_SUPPORT` is set to `YES`) +Use apt-get: + `sudo apt-get install libsdl2-dev` +Or download source from www.libsdl.org: +``` +./configure +make +sudo make install +``` + +- Install EMSDK +``` + https://emscripten.org/docs/tools_reference/emsdk.html +``` + Build all binaries ============== Execute the build.sh script then all binaries including wasm application files would be generated in 'out' directory. @@ -75,18 +103,20 @@ Execute the build.sh script then all binaries including wasm application files w Out directory structure ------------------------------ - ``` +``` out/ ├── host_tool ├── simple └── wasm-apps + ├── connection.wasm ├── event_publisher.wasm ├── event_subscriber.wasm + ├── gui.wasm ├── request_handler.wasm ├── request_sender.wasm ├── sensor.wasm └── timer.wasm - ``` +``` - host_tool: A small testing tool to interact with WAMR. See the usage of this tool by executing "./host_tool -h". @@ -100,10 +130,14 @@ out/ - wasm-apps: Sample wasm applications that demonstrate all APIs of the WAMR programming model. The source codes are in the wasm-apps directory under the root of this project. + + connection.wasm
+ This application shows the connection programming model. It connects to a TCP server on 127.0.0.1:7777 and periodically sends message to it. + event_publisher.wasm
This application shows the sub/pub programming model. The pub application publishes the event "alert/overheat" by calling api_publish_event() API. The subscriber could be host_tool or other wasm application. + event_subscriber.wasm
This application shows the sub/pub programming model. The sub application subscribes the "alert/overheat" event by calling api_subscribe_event() API so that it is able to receive the event once generated and published by the pub application. To make the process clear to interpret, the sub application dumps the event when receiving it. + + gui.wasm
+ This application shows the built-in 2D graphical user interface API with which various widgets could be created. + request_handler.wasm
This application shows the request/response programming model. The request handler application registers 2 resources(/url1 and /url2) by calling api_register_resource_handler() API. The request sender could be host_tool or other wasm application. + request_sender.wasm
diff --git a/samples/simple/build.sh b/samples/simple/build.sh index 1d8b8e1b..f803fff0 100755 --- a/samples/simple/build.sh +++ b/samples/simple/build.sh @@ -8,7 +8,7 @@ BUILD_DIR=${PWD}/build IWASM_ROOT=${PWD}/../../core/iwasm APP_LIBS=${IWASM_ROOT}/lib/app-libs NATIVE_LIBS=${IWASM_ROOT}/lib/native-interface -APP_LIB_SRC="${APP_LIBS}/base/*.c ${APP_LIBS}/extension/sensor/*.c ${NATIVE_LIBS}/*.c" +APP_LIB_SRC="${APP_LIBS}/base/*.c ${APP_LIBS}/extension/sensor/*.c ${APP_LIBS}/extension/connection/*.c ${APP_LIBS}/extension/gui/src/*.c ${NATIVE_LIBS}/*.c" WASM_APPS=${PWD}/wasm-apps rm -rf ${OUT_DIR} @@ -20,6 +20,14 @@ if [ ! -d "tlsf" ]; then git clone https://github.com/mattconte/tlsf fi +cd ${WAMR_DIR}/core/iwasm/lib/3rdparty +if [ ! -d "lvgl" ]; then + git clone https://github.com/littlevgl/lvgl.git --branch v6.0.1 +fi +if [ ! -d "lv_drivers" ]; then + git clone https://github.com/littlevgl/lv_drivers.git +fi + echo "#####################build simple project" cd ${CURR_DIR} mkdir -p cmake_build @@ -49,54 +57,24 @@ echo "#####################build host-tool success" echo "#####################build wasm apps" -cd ${CURR_DIR} +cd ${WASM_APPS} -APP_SRC="${WASM_APPS}/timer/timer.c ${APP_LIB_SRC}" +for i in `ls *.c` +do +APP_SRC="$i ${APP_LIB_SRC}" +OUT_FILE=${i%.*}.wasm emcc -O3 -I${APP_LIBS}/base -I${APP_LIBS}/extension/sensor -I${NATIVE_LIBS} \ + -I${APP_LIBS}/extension/connection \ + -I${APP_LIBS}/extension/gui \ -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 \ -s "EXPORTED_FUNCTIONS=['_on_init', '_on_destroy', '_on_request', '_on_response', \ - '_on_sensor_event', '_on_timer_callback']" \ - -o ${OUT_DIR}/wasm-apps/timer.wasm ${APP_SRC} - -APP_SRC="${WASM_APPS}/request_handler/request_handler.c ${APP_LIB_SRC}" -emcc -O3 -I${APP_LIBS}/base -I${APP_LIBS}/extension/sensor -I${NATIVE_LIBS} \ - -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ - -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 \ - -s "EXPORTED_FUNCTIONS=['_on_init', '_on_destroy', '_on_request', '_on_response', \ - '_on_sensor_event', '_on_timer_callback']" \ - -o ${OUT_DIR}/wasm-apps/request_handler.wasm ${APP_SRC} - -APP_SRC="${WASM_APPS}/request_sender/request_sender.c ${APP_LIB_SRC}" -emcc -O3 -I${APP_LIBS}/base -I${APP_LIBS}/extension/sensor -I${NATIVE_LIBS} \ - -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ - -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 \ - -s "EXPORTED_FUNCTIONS=['_on_init', '_on_destroy', '_on_request', '_on_response', \ - '_on_sensor_event', '_on_timer_callback']" \ - -o ${OUT_DIR}/wasm-apps/request_sender.wasm ${APP_SRC} - -APP_SRC="${WASM_APPS}/event_publisher/event_publisher.c ${APP_LIB_SRC}" -emcc -O3 -I${APP_LIBS}/base -I${APP_LIBS}/extension/sensor -I${NATIVE_LIBS} \ - -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ - -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 \ - -s "EXPORTED_FUNCTIONS=['_on_init', '_on_destroy', '_on_request', '_on_response', \ - '_on_sensor_event', '_on_timer_callback']" \ - -o ${OUT_DIR}/wasm-apps/event_publisher.wasm ${APP_SRC} - -APP_SRC="${WASM_APPS}/event_subscriber/event_subscriber.c ${APP_LIB_SRC}" -emcc -O3 -I${APP_LIBS}/base -I${APP_LIBS}/extension/sensor -I${NATIVE_LIBS} \ - -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ - -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 \ - -s "EXPORTED_FUNCTIONS=['_on_init', '_on_destroy', '_on_request', '_on_response', \ - '_on_sensor_event', '_on_timer_callback']" \ - -o ${OUT_DIR}/wasm-apps/event_subscriber.wasm ${APP_SRC} - -APP_SRC="${WASM_APPS}/sensor/sensor.c ${APP_LIB_SRC}" -emcc -O3 -I${APP_LIBS}/base -I${APP_LIBS}/extension/sensor -I${NATIVE_LIBS} \ - -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \ - -s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 \ - -s "EXPORTED_FUNCTIONS=['_on_init', '_on_destroy', '_on_request', '_on_response', \ - '_on_sensor_event', '_on_timer_callback']" \ - -o ${OUT_DIR}/wasm-apps/sensor.wasm ${APP_SRC} - -echo "#####################build wasm apps success" + '_on_sensor_event', '_on_timer_callback', '_on_connection_data', '_on_widget_event']" \ + -o ${OUT_DIR}/wasm-apps/${OUT_FILE} ${APP_SRC} +if [ -f ${OUT_DIR}/wasm-apps/${OUT_FILE} ]; then + echo "build ${OUT_FILE} success" +else + echo "build ${OUT_FILE} fail" +fi +done +echo "#####################build wasm apps done" diff --git a/samples/simple/src/ext_lib_export.c b/samples/simple/src/ext_lib_export.c index 89e57200..1ba108a0 100644 --- a/samples/simple/src/ext_lib_export.c +++ b/samples/simple/src/ext_lib_export.c @@ -1,8 +1,12 @@ #include "lib_export.h" #include "sensor_api.h" +#include "connection_api.h" +#include "gui_api.h" static NativeSymbol extended_native_symbol_defs[] = { #include "runtime_sensor.inl" +#include "connection.inl" +#include "wamr_gui.inl" }; #include "ext_lib_export.h" diff --git a/samples/simple/src/iwasm_main.c b/samples/simple/src/iwasm_main.c index d70b7e4d..24f9c95f 100644 --- a/samples/simple/src/iwasm_main.c +++ b/samples/simple/src/iwasm_main.c @@ -32,6 +32,10 @@ #include "attr_container.h" #include "module_wasm_app.h" #include "wasm_export.h" + +#include "lv_drivers/display/monitor.h" +#include "lv_drivers/indev/mouse.h" + #define MAX 2048 #ifndef CONNECTION_UART @@ -46,6 +50,8 @@ static int baudrate = B115200; extern void * thread_timer_check(void *); extern void init_sensor_framework(); extern int aee_host_msg_callback(void *msg, uint16_t msg_len); +extern bool init_connection_framework(); +extern void wgl_init(); #ifndef CONNECTION_UART int listenfd = -1; @@ -213,7 +219,7 @@ void* func_server_mode(void* arg) sockfd = -1; pthread_mutex_unlock(&sock_lock); - sleep(2); + sleep(1); break; } @@ -424,6 +430,37 @@ static bool parse_args(int argc, char *argv[]) return true; } +/** + * Initialize the Hardware Abstraction Layer (HAL) for the Littlev graphics library + */ +static void hal_init(void) +{ + /* Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/ + monitor_init(); + + /*Create a display buffer*/ + static lv_disp_buf_t disp_buf1; + static lv_color_t buf1_1[480*10]; + lv_disp_buf_init(&disp_buf1, buf1_1, NULL, 480*10); + + /*Create a display*/ + lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); /*Basic initialization*/ + disp_drv.buffer = &disp_buf1; + disp_drv.flush_cb = monitor_flush; + // disp_drv.hor_res = 200; + // disp_drv.ver_res = 100; + lv_disp_drv_register(&disp_drv); + + /* Add the mouse as input device + * Use the 'mouse' driver which reads the PC's mouse*/ + mouse_init(); + lv_indev_drv_t indev_drv; + lv_indev_drv_init(&indev_drv); /*Basic initialization*/ + indev_drv.type = LV_INDEV_TYPE_POINTER; + indev_drv.read_cb = mouse_read; /*This function will be called periodically (by the library) to get the mouse position and state*/ + lv_indev_drv_register(&indev_drv); +} // Driver function int iwasm_main(int argc, char *argv[]) { @@ -442,6 +479,13 @@ int iwasm_main(int argc, char *argv[]) goto fail1; } + if (!init_connection_framework()) { + vm_thread_sys_destroy(); + goto fail1; + } + + wgl_init(); + hal_init(); init_sensor_framework(); // timer manager diff --git a/samples/simple/src/lv_drv_conf.h b/samples/simple/src/lv_drv_conf.h new file mode 100644 index 00000000..d216a3e9 --- /dev/null +++ b/samples/simple/src/lv_drv_conf.h @@ -0,0 +1,310 @@ +/** + * @file lv_drv_conf.h + * + */ + +/* + * COPY THIS FILE AS lv_drv_conf.h + */ + +#if 1 /*Set it to "1" to enable the content*/ + +#ifndef LV_DRV_CONF_H +#define LV_DRV_CONF_H + +#include "lv_conf.h" + +/********************* + * DELAY INTERFACE + *********************/ +#define LV_DRV_DELAY_INCLUDE /*Dummy include by default*/ +#define LV_DRV_DELAY_US(us) /*delay_us(us)*/ /*Delay the given number of microseconds*/ +#define LV_DRV_DELAY_MS(ms) /*delay_ms(ms)*/ /*Delay the given number of milliseconds*/ + +/********************* + * DISPLAY INTERFACE + *********************/ + +/*------------ + * Common + *------------*/ +#define LV_DRV_DISP_INCLUDE /*Dummy include by default*/ +#define LV_DRV_DISP_CMD_DATA(val) /*pin_x_set(val)*/ /*Set the command/data pin to 'val'*/ +#define LV_DRV_DISP_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ + +/*--------- + * SPI + *---------*/ +#define LV_DRV_DISP_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/ +#define LV_DRV_DISP_SPI_WR_BYTE(data) /*spi_wr(data)*/ /*Write a byte the SPI bus*/ +#define LV_DRV_DISP_SPI_WR_ARRAY(adr, n) /*spi_wr_mem(adr, n)*/ /*Write 'n' bytes to SPI bus from 'adr'*/ + +/*------------------ + * Parallel port + *-----------------*/ +#define LV_DRV_DISP_PAR_CS(val) /*par_cs_set(val)*/ /*Set the Parallel port's Chip select to 'val'*/ +#define LV_DRV_DISP_PAR_SLOW /*par_slow()*/ /*Set low speed on the parallel port*/ +#define LV_DRV_DISP_PAR_FAST /*par_fast()*/ /*Set high speed on the parallel port*/ +#define LV_DRV_DISP_PAR_WR_WORD(data) /*par_wr(data)*/ /*Write a word to the parallel port*/ +#define LV_DRV_DISP_PAR_WR_ARRAY(adr, n) /*par_wr_mem(adr,n)*/ /*Write 'n' bytes to Parallel ports from 'adr'*/ + +/*************************** + * INPUT DEVICE INTERFACE + ***************************/ + +/*---------- + * Common + *----------*/ +#define LV_DRV_INDEV_INCLUDE /*Dummy include by default*/ +#define LV_DRV_INDEV_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ +#define LV_DRV_INDEV_IRQ_READ 0 /*pn_x_read()*/ /*Read the IRQ pin*/ + +/*--------- + * SPI + *---------*/ +#define LV_DRV_INDEV_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/ +#define LV_DRV_INDEV_SPI_XCHG_BYTE(data) 0 /*spi_xchg(val)*/ /*Write 'val' to SPI and give the read value*/ + +/*--------- + * I2C + *---------*/ +#define LV_DRV_INDEV_I2C_START /*i2c_start()*/ /*Make an I2C start*/ +#define LV_DRV_INDEV_I2C_STOP /*i2c_stop()*/ /*Make an I2C stop*/ +#define LV_DRV_INDEV_I2C_RESTART /*i2c_restart()*/ /*Make an I2C restart*/ +#define LV_DRV_INDEV_I2C_WR(data) /*i2c_wr(data)*/ /*Write a byte to the I1C bus*/ +#define LV_DRV_INDEV_I2C_READ(last_read) 0 /*i2c_rd()*/ /*Read a byte from the I2C bud*/ + + +/********************* + * DISPLAY DRIVERS + *********************/ + +/*------------------- + * Monitor of PC + *-------------------*/ +#ifndef USE_MONITOR +# define USE_MONITOR 1 +#endif + +#if USE_MONITOR +# define MONITOR_HOR_RES LV_HOR_RES_MAX +# define MONITOR_VER_RES LV_VER_RES_MAX + +/* Scale window by this factor (useful when simulating small screens) */ +# define MONITOR_ZOOM 1 + +/* Used to test true double buffering with only address changing. + * Set LV_VDB_SIZE = (LV_HOR_RES * LV_VER_RES) and LV_VDB_DOUBLE = 1 and LV_COLOR_DEPTH = 32" */ +# define MONITOR_DOUBLE_BUFFERED 0 + +/*Eclipse: Visual Studio: */ +# define MONITOR_SDL_INCLUDE_PATH + +/*Different rendering might be used if running in a Virtual machine*/ +# define MONITOR_VIRTUAL_MACHINE 0 + +/*Open two windows to test multi display support*/ +# define MONITOR_DUAL 0 +#endif + +/*----------------------------------- + * Native Windows (including mouse) + *----------------------------------*/ +#ifndef USE_WINDOWS +# define USE_WINDOWS 0 +#endif + +#define USE_WINDOWS 0 +#if USE_WINDOWS +# define WINDOW_HOR_RES 480 +# define WINDOW_VER_RES 320 +#endif + +/*---------------- + * SSD1963 + *--------------*/ +#ifndef USE_SSD1963 +# define USE_SSD1963 0 +#endif + +#if USE_SSD1963 +# define SSD1963_HOR_RES LV_HOR_RES +# define SSD1963_VER_RES LV_VER_RES +# define SSD1963_HT 531 +# define SSD1963_HPS 43 +# define SSD1963_LPS 8 +# define SSD1963_HPW 10 +# define SSD1963_VT 288 +# define SSD1963_VPS 12 +# define SSD1963_FPS 4 +# define SSD1963_VPW 10 +# define SSD1963_HS_NEG 0 /*Negative hsync*/ +# define SSD1963_VS_NEG 0 /*Negative vsync*/ +# define SSD1963_ORI 0 /*0, 90, 180, 270*/ +# define SSD1963_COLOR_DEPTH 16 +#endif + +/*---------------- + * R61581 + *--------------*/ +#ifndef USE_R61581 +# define USE_R61581 0 +#endif + +#if USE_R61581 +# define R61581_HOR_RES LV_HOR_RES +# define R61581_VER_RES LV_VER_RES +# define R61581_HSPL 0 /*HSYNC signal polarity*/ +# define R61581_HSL 10 /*HSYNC length (Not Implemented)*/ +# define R61581_HFP 10 /*Horitontal Front poarch (Not Implemented)*/ +# define R61581_HBP 10 /*Horitontal Back poarch (Not Implemented */ +# define R61581_VSPL 0 /*VSYNC signal polarity*/ +# define R61581_VSL 10 /*VSYNC length (Not Implemented)*/ +# define R61581_VFP 8 /*Vertical Front poarch*/ +# define R61581_VBP 8 /*Vertical Back poarch */ +# define R61581_DPL 0 /*DCLK signal polarity*/ +# define R61581_EPL 1 /*ENABLE signal polarity*/ +# define R61581_ORI 0 /*0, 180*/ +# define R61581_LV_COLOR_DEPTH 16 /*Fix 16 bit*/ +#endif + +/*------------------------------ + * ST7565 (Monochrome, low res.) + *-----------------------------*/ +#ifndef USE_ST7565 +# define USE_ST7565 0 +#endif + +#if USE_ST7565 +/*No settings*/ +#endif /*USE_ST7565*/ + +/*----------------------------------------- + * Linux frame buffer device (/dev/fbx) + *-----------------------------------------*/ +#ifndef USE_FBDEV +# define USE_FBDEV 1 +#endif + +#if USE_FBDEV +# define FBDEV_PATH "/dev/fb0" +#endif + +/********************* + * INPUT DEVICES + *********************/ + +/*-------------- + * XPT2046 + *--------------*/ +#ifndef USE_XPT2046 +# define USE_XPT2046 0 +#endif + +#if USE_XPT2046 +# define XPT2046_HOR_RES 480 +# define XPT2046_VER_RES 320 +# define XPT2046_X_MIN 200 +# define XPT2046_Y_MIN 200 +# define XPT2046_X_MAX 3800 +# define XPT2046_Y_MAX 3800 +# define XPT2046_AVG 4 +# define XPT2046_INV 0 +#endif + +/*----------------- + * FT5406EE8 + *-----------------*/ +#ifndef USE_FT5406EE8 +# define USE_FT5406EE8 0 +#endif + +#if USE_FT5406EE8 +# define FT5406EE8_I2C_ADR 0x38 /*7 bit address*/ +#endif + +/*--------------- + * AD TOUCH + *--------------*/ +#ifndef USE_AD_TOUCH +# define USE_AD_TOUCH 0 +#endif + +#if USE_AD_TOUCH +/*No settings*/ +#endif + + +/*--------------------------------------- + * Mouse or touchpad on PC (using SDL) + *-------------------------------------*/ +#ifndef USE_MOUSE +# define USE_MOUSE 1 +#endif + +#if USE_MOUSE +/*No settings*/ +#endif + +/*------------------------------------------- + * Mousewheel as encoder on PC (using SDL) + *------------------------------------------*/ +#ifndef USE_MOUSEWHEEL +# define USE_MOUSEWHEEL 1 +#endif + +#if USE_MOUSEWHEEL +/*No settings*/ +#endif + +/*------------------------------------------------- + * Touchscreen as libinput interface (for Linux based systems) + *------------------------------------------------*/ +#ifndef USE_LIBINPUT +# define USE_LIBINPUT 0 +#endif + +#if USE_LIBINPUT +# define LIBINPUT_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/ +#endif /*USE_LIBINPUT*/ + +/*------------------------------------------------- + * Mouse or touchpad as evdev interface (for Linux based systems) + *------------------------------------------------*/ +#ifndef USE_EVDEV +# define USE_EVDEV 0 +#endif + +#if USE_EVDEV +# define EVDEV_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/ +# define EVDEV_SWAP_AXES 0 /*Swap the x and y axes of the touchscreen*/ + +# define EVDEV_SCALE 0 /* Scale input, e.g. if touchscreen resolution does not match display resolution */ +# if EVDEV_SCALE +# define EVDEV_SCALE_HOR_RES (4096) /* Horizontal resolution of touchscreen */ +# define EVDEV_SCALE_VER_RES (4096) /* Vertical resolution of touchscreen */ +# endif /*EVDEV_SCALE*/ + +# define EVDEV_CALIBRATE 0 /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/ +# if EVDEV_CALIBRATE +# define EVDEV_HOR_MIN 3800 /*If EVDEV_XXX_MIN > EVDEV_XXX_MAX the XXX axis is automatically inverted*/ +# define EVDEV_HOR_MAX 200 +# define EVDEV_VER_MIN 200 +# define EVDEV_VER_MAX 3800 +# endif /*EVDEV_SCALE*/ +#endif /*USE_EVDEV*/ + +/*------------------------------- + * Keyboard of a PC (using SDL) + *------------------------------*/ +#ifndef USE_KEYBOARD +# define USE_KEYBOARD 1 +#endif + +#if USE_KEYBOARD +/*No settings*/ +#endif + +#endif /*LV_DRV_CONF_H*/ + +#endif /*End of "Content enable"*/ diff --git a/samples/simple/wasm-apps/connection.c b/samples/simple/wasm-apps/connection.c new file mode 100644 index 00000000..89aed517 --- /dev/null +++ b/samples/simple/wasm-apps/connection.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wasm_app.h" + +/* User global variable */ +static int num = 0; +static user_timer_t g_timer; +static connection_t *g_conn = NULL; + +void on_data1(connection_t *conn, + conn_event_type_t type, + const char *data, + uint32 len, + void *user_data) +{ + if (type == CONN_EVENT_TYPE_DATA) { + char message[64] = {0}; + memcpy(message, data, len); + printf("Client got a message from server -> %s\n", message); + } else if (type == CONN_EVENT_TYPE_DISCONNECT) { + printf("connection is close by server!\n"); + } else { + printf("error: got unknown event type!!!\n"); + } +} + +/* Timer callback */ +void timer1_update(user_timer_t timer) +{ + char message[64] = {0}; + /* Reply to server */ + snprintf(message, sizeof(message), "Hello %d", num++); + api_send_on_connection(g_conn, message, strlen(message)); +} + +void my_close_handler(request_t * request) +{ + response_t response[1]; + + if (g_conn != NULL) { + api_timer_cancel(g_timer); + api_close_connection(g_conn); + } + + make_response_for_request(request, response); + set_response(response, DELETED_2_02, 0, NULL, 0); + api_response_send(response); +} + +void on_init() +{ + user_timer_t timer; + attr_container_t *args; + char *str = "this is client!"; + + api_register_resource_handler("/close", my_close_handler); + + args = attr_container_create(""); + attr_container_set_string(&args, "address", "127.0.0.1"); + attr_container_set_uint16(&args, "port", 7777); + + g_conn = api_open_connection("TCP", args, on_data1, NULL); + if (g_conn == NULL) { + printf("connect to server fail!\n"); + return; + } + + printf("connect to server success! handle: %p\n", g_conn); + + /* set up a timer */ + timer = api_timer_create(1000, true, false, timer1_update); + api_timer_restart(timer, 1000); +} + +void on_destroy() +{ + /* real destroy work including killing timer and closing sensor is + accomplished in wasm app library version of on_destroy() */ +} diff --git a/samples/simple/wasm-apps/event_publisher/event_publisher.c b/samples/simple/wasm-apps/event_publisher.c similarity index 100% rename from samples/simple/wasm-apps/event_publisher/event_publisher.c rename to samples/simple/wasm-apps/event_publisher.c diff --git a/samples/simple/wasm-apps/event_subscriber/event_subscriber.c b/samples/simple/wasm-apps/event_subscriber.c similarity index 100% rename from samples/simple/wasm-apps/event_subscriber/event_subscriber.c rename to samples/simple/wasm-apps/event_subscriber.c diff --git a/samples/simple/wasm-apps/gui.c b/samples/simple/wasm-apps/gui.c new file mode 100644 index 00000000..b3beb9d0 --- /dev/null +++ b/samples/simple/wasm-apps/gui.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include "wasm_app.h" + +static void btn_event_cb(wgl_obj_t btn, wgl_event_t event); + +uint32_t count = 0; +char count_str[11] = { 0 }; +wgl_obj_t hello_world_label; +wgl_obj_t count_label; +wgl_obj_t btn1; +wgl_obj_t label_count1; +int label_count1_value = 0; +char label_count1_str[11] = { 0 }; + +void timer1_update(user_timer_t timer1) +{ + if ((count % 100) == 0) { + sprintf(count_str, "%d", count / 100); + wgl_label_set_text(count_label, count_str); + } + ++count; +} + +void on_init() +{ + char text[32] = {0}; + + hello_world_label = wgl_label_create((wgl_obj_t)NULL, (wgl_obj_t)NULL); + wgl_label_set_text(hello_world_label, "Hello world!"); + wgl_label_get_text(hello_world_label, text, sizeof(text)); + printf("Label text %d %s \n", wgl_label_get_text_length(hello_world_label), text); + wgl_obj_align(hello_world_label, (wgl_obj_t)NULL, WGL_ALIGN_IN_TOP_LEFT, 0, 0); + + count_label = wgl_label_create((wgl_obj_t)NULL, (wgl_obj_t)NULL); + wgl_obj_align(count_label, (wgl_obj_t)NULL, WGL_ALIGN_IN_TOP_MID, 0, 0); + + btn1 = wgl_btn_create((wgl_obj_t)NULL, (wgl_obj_t)NULL); /*Create a button on the currently loaded screen*/ + wgl_obj_set_event_cb(btn1, btn_event_cb); /*Set function to be called when the button is released*/ + wgl_obj_align(btn1, (wgl_obj_t)NULL, WGL_ALIGN_CENTER, 0, 0); /*Align below the label*/ + + /*Create a label on the button*/ + wgl_obj_t btn_label = wgl_label_create(btn1, (wgl_obj_t)NULL); + wgl_label_set_text(btn_label, "Click ++"); + + label_count1 = wgl_label_create((wgl_obj_t)NULL, (wgl_obj_t)NULL); + wgl_label_set_text(label_count1, "0"); + wgl_obj_align(label_count1, (wgl_obj_t)NULL, WGL_ALIGN_IN_BOTTOM_MID, 0, 0); + + /* set up a timer */ + user_timer_t timer; + timer = api_timer_create(10, true, false, timer1_update); + api_timer_restart(timer, 10); +} + +static void btn_event_cb(wgl_obj_t btn, wgl_event_t event) +{ + if(event == WGL_EVENT_RELEASED) { + label_count1_value++; + sprintf(label_count1_str, "%d", label_count1_value); + wgl_label_set_text(label_count1, label_count1_str); + } +} diff --git a/samples/simple/wasm-apps/gui_lvgl_compatible.c b/samples/simple/wasm-apps/gui_lvgl_compatible.c new file mode 100644 index 00000000..8f2c37a5 --- /dev/null +++ b/samples/simple/wasm-apps/gui_lvgl_compatible.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "wasm_app.h" +#include "lvgl.h" + +extern char g_widget_text[]; + +static void btn_event_cb(lv_obj_t *btn, lv_event_t event); + +uint32_t count = 0; +char count_str[11] = { 0 }; +lv_obj_t *hello_world_label; +lv_obj_t *count_label; +lv_obj_t *btn1; +lv_obj_t *label_count1; +int label_count1_value = 100; +char label_count1_str[11] = { 0 }; + +void timer1_update(user_timer_t timer1) +{ + if ((count % 100) == 0) { + sprintf(count_str, "%d", count / 100); + lv_label_set_text(count_label, count_str); + } + ++count; +} + +void on_init() +{ + char *text; + + hello_world_label = lv_label_create(NULL, NULL); + lv_label_set_text(hello_world_label, "Hello world!"); + text = lv_label_get_text(hello_world_label); + printf("Label text %lu %s \n", strlen(text), text); + lv_obj_align(hello_world_label, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); + + count_label = lv_label_create(NULL, NULL); + lv_obj_align(count_label, NULL, LV_ALIGN_IN_TOP_MID, 0, 0); + + btn1 = lv_btn_create(NULL, NULL); /*Create a button on the currently loaded screen*/ + lv_obj_set_event_cb(btn1, btn_event_cb); /*Set function to be called when the button is released*/ + lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0); /*Align below the label*/ + + /*Create a label on the button*/ + lv_obj_t *btn_label = lv_label_create(btn1, NULL); + lv_label_set_text(btn_label, "Click --"); + + label_count1 = lv_label_create(NULL, NULL); + lv_label_set_text(label_count1, "100"); + lv_obj_align(label_count1, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + + /* set up a timer */ + user_timer_t timer; + timer = api_timer_create(10, true, false, timer1_update); + api_timer_restart(timer, 10); +} + +static void btn_event_cb(lv_obj_t *btn, lv_event_t event) +{ + if(event == LV_EVENT_RELEASED) { + label_count1_value--; + sprintf(label_count1_str, "%d", label_count1_value); + lv_label_set_text(label_count1, label_count1_str); + if (label_count1_value == 0) + label_count1_value = 100; + } +} diff --git a/samples/simple/wasm-apps/request_handler/request_handler.c b/samples/simple/wasm-apps/request_handler.c similarity index 100% rename from samples/simple/wasm-apps/request_handler/request_handler.c rename to samples/simple/wasm-apps/request_handler.c diff --git a/samples/simple/wasm-apps/request_sender/request_sender.c b/samples/simple/wasm-apps/request_sender.c similarity index 100% rename from samples/simple/wasm-apps/request_sender/request_sender.c rename to samples/simple/wasm-apps/request_sender.c diff --git a/samples/simple/wasm-apps/sensor/sensor.c b/samples/simple/wasm-apps/sensor.c similarity index 100% rename from samples/simple/wasm-apps/sensor/sensor.c rename to samples/simple/wasm-apps/sensor.c diff --git a/samples/simple/wasm-apps/timer/timer.c b/samples/simple/wasm-apps/timer.c similarity index 100% rename from samples/simple/wasm-apps/timer/timer.c rename to samples/simple/wasm-apps/timer.c diff --git a/test-tools/IoT-APP-Store-Demo/README.md b/test-tools/IoT-APP-Store-Demo/README.md new file mode 100644 index 00000000..fe69e144 --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/README.md @@ -0,0 +1,34 @@ +# IoT Application Store +Wasm application management portal for WAMR + +# Requirement +Install django with pip3 +``` +pip3 install django +``` + +# Run +1. Start wasm server + ``` + cd wasm_django/server + python3 wasm_server.py + ``` + +2. Start IoT application management web portal + ``` + cd wasm_django + python3 manage.py runserver 0.0.0.0:80 + ``` + +3. Download WAMR runtime from [help](http://localhost/help/) page + > NOTE: You need to start web server according to *step 2* before accessing this link! + +4. Start a WAMR runtime from localhost + ``` + ./simple + ``` + or from other computers + ``` + ./simple -a [your.server.ip.address] + ``` + diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/db.sqlite3 b/test-tools/IoT-APP-Store-Demo/wasm_django/db.sqlite3 new file mode 100755 index 00000000..211576ca Binary files /dev/null and b/test-tools/IoT-APP-Store-Demo/wasm_django/db.sqlite3 differ diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/devices/__init__.py b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/devices/admin.py b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/admin.py new file mode 100755 index 00000000..8c38f3f3 --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/devices/apps.py b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/apps.py new file mode 100755 index 00000000..d43cc4b6 --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class DevicesConfig(AppConfig): + name = 'devices' diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/devices/migrations/__init__.py b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/migrations/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/devices/models.py b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/models.py new file mode 100755 index 00000000..71a83623 --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/application.html b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/application.html new file mode 100644 index 00000000..55852977 --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/application.html @@ -0,0 +1,152 @@ + +{% load static %} + + + + + + + Wasm-Micro-Runtime + + + + + + + + + + +
+
+ +
+
+

WebAssembly Micro Runtime - APP Store Demo

+
+
+ + + +
+
+
+
+

+ +

+
+
IP :
+
Port :
+
Installed apps :
+
+
+
+ + + + + +
+

app is downloading now

+
+
+
+
+ + +
+
+
×
+
HOT Applications
+ +
+
+ +

Product Name:

+

Current Version:

+ +
+
+
+
+ + +
+

List of Installed Apps:

+ +
+ + +
+
+ +
Product Name:
+
Staus:
+
Current Version:
+
+
+
+ +
Copyright© intel.com
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/appstore.html b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/appstore.html new file mode 100644 index 00000000..36f1fb8d --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/appstore.html @@ -0,0 +1,106 @@ + +{% load static %} + + + + + + + + Wasm-Micro-Runtime + + + + + + + + + + +
+
+ +
+
+

WebAssembly Micro Runtime - APP Store Demo

+
+
+ + + + + +
+
+
+
The products
+
Application List
+
+
+ {%csrf_token%} +
+ + Choose File +
+
+ +
+
+
+
+
+
+
+

Product Name:

+

Product Version:

+

Preloaded Apps

+ +
+
+
+
+
+ + +
+ Copyright© intel.com +
+ + + + + + + + + diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/empty.html b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/empty.html new file mode 100644 index 00000000..6aef0f2a --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/empty.html @@ -0,0 +1,119 @@ + + + +wasm-micro-runtime + + + + + + + + + + +
+

404

+

Server Not Found

+

Github

+
+ + + + + + + + + + diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/help.html b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/help.html new file mode 100755 index 00000000..2e77cfad --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/help.html @@ -0,0 +1,110 @@ + +{% load static %} + + + + + + + Wasm-Micro-Runtime + + + + + + + + + + + + +
+
+
+
+

+ How to use? +

+

+ 1. Download a simple runtime (build for ubuntu 16.04 64 bits, other platforms please build + from the source code) +

+

+ 2. In the terminal: cd ~/Download && ./simple -a 39.106.110.7 +

+
+
+ +
+ Notes: +
We also have a UI-enabled runtime, please download here and enjoy. It may require + a few more setups. +

Before running the UI-enabled runtime, please install some required softwares:

+

sudo apt-get install libsdl2-2.0-0:i386

+

For more details please refer to this guide +

+

cd ~/Download && ./wasm_runtime_wgl -a 39.106.110.7

+
+
+

+ 3. Return to device page, find your device according to the IP address and click it, you + will enter application installation page +

+

+ 4. In the application installation page, click the Install Application button, and chose an + app to install. (The "ui_app" is only for UI_enabled_runtimes, simple runtime can't install + this app) +

+

+ 5. If you want to upload a new application, go to App Store page, choose a file and click + upload +

+

+ Go Back + Download + simple_runtime + Download + UI_enabled_runtime +

+
+
+
+
+

Like this project?

+

Join us and build a powerful and interesting world for embedded + devices!

+ + +

+ View + on GitHub +

+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/mysite.html b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/mysite.html new file mode 100644 index 00000000..88f0e923 --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/templates/mysite.html @@ -0,0 +1,99 @@ + +{% load static %} + + + + + + + Wasm-Micro-Runtime + + + + + + + + + + +
+
+ +
+
+

WebAssembly Micro Runtime - APP Store Demo

+
+
+ +
+
+
+
+

+ +

+
+

The devices

+
+
+ +
+ + +
+
+
+
+

+ +

+
+
IP :
+
Port :
+
Installed apps :
+
+
+

+ +

+
+
+
+ + + + +
+ Copyright© intel.com +
+ + + + + + + + \ No newline at end of file diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/devices/tests.py b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/tests.py new file mode 100755 index 00000000..7ce503c2 --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/devices/views.py b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/views.py new file mode 100755 index 00000000..4fd4c09c --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/devices/views.py @@ -0,0 +1,284 @@ +''' + /* Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +''' + +# _*_ +from django.shortcuts import render, render_to_response +from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound +import json +import socket +import os + +# Create your views here. + + +avaliable_list = [ + {'ID': 'timer', 'Version': '1.0'}, + {'ID': 'connection', 'Version': '1.0'}, + {'ID': 'event_publisher', 'Version': '3.0'}, + {'ID': 'event_subscriber', 'Version': '1.0'}, + {'ID': 'request_handler', 'Version': '1.0'}, + {'ID': 'sensor', 'Version': '1.0'}, + {'ID': 'ui_app', 'Version': '1.0'} +] + +# Help +def help(req): +# return "Help" page + return render(req, "help.html") + +# View +def index(req): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + host = '127.0.0.1' + port = 8889 + msg = "" + err = "" + + try: + s.connect((host, port)) + s.send(bytes("query:all", encoding='utf8')) + s.settimeout(10) + msg = s.recv(1024) + except socket.timeout as e: + err = "empty" + print("no client connected") + except socket.error as e: + err = "refused" + print("server not started") + + s.close() + + device_list = [] + if msg != "": + devices = msg.decode('utf-8').split("*") + for dev in devices: + dev_info = eval(dev) + addr = dev_info['addr'] + port = dev_info['port'] + apps = dev_info['num'] + device_list.append({'IP': addr, 'Port': port, 'apps': apps}) + else: + if err == "refused": + return render(req, "empty.html") + + dlist = device_list + + return render(req, 'mysite.html', {'dlist': json.dumps(dlist)}) + + +def apps(req): + open_status = '' + search_node = [] + if req.method == "POST": + dev_search = req.POST['mykey'] + dev_addr = req.POST['voip'] + dev_port = req.POST['voport'] + open_status = 'open' + for i in avaliable_list: + if i['ID'] == dev_search: + search_node = [{'ID':dev_search, 'Version': '1.0'}] + print("search_node:",search_node) + break + else: + search_node = ["Nothing find"] + print( "final:",search_node) + else: + dev_addr = req.GET['ip'] + dev_port = req.GET['port'] + open_status = 'close' + + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + host = '127.0.0.1' + port = 8889 + msg = "" + err = "" + + try: + s.connect((host, port)) + s.send(bytes("query:"+dev_addr+":"+str(dev_port), encoding='utf8')) + msg = s.recv(1024) + except socket.error as e: + print("unable to connect to server") + msg = b"fail" + s.close() + + app_list = [] + + if msg != "": + if msg.decode() == "fail": + return render(req, "empty.html") + else: + dic = eval(msg.decode(encoding='utf8')) + app_num = dic["num"] + for i in range(app_num): + app_list.append( + {'pname': dic["applet"+str(i+1)], 'status': 'Installed', 'current_version': '1.0'}) + + alist = app_list + device_info = [] + device_info.append( + {'IP': dev_addr, 'Port': str(dev_port), 'apps': app_num}) + + print(device_info) + return render(req, 'application.html', {'alist': json.dumps(alist), 'dlist': json.dumps(device_info), 'llist': json.dumps(avaliable_list), + "open_status":json.dumps(open_status),"search_node": json.dumps(search_node),}) + + +def appDownload(req): + dev_addr = req.GET['ip'] + dev_port = req.GET['port'] + app_name = req.GET['name'] + + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + host = '127.0.0.1' + port = 8889 + msg = "" + + app_path = os.path.abspath(os.path.join(os.getcwd(), "static", "upload")) + if app_path[-1] != '/': + app_path += '/' + + try: + s.connect((host, port)) + s.send(bytes("install:"+dev_addr+":"+str(dev_port)+":"+app_name + + ":"+app_path + app_name + ".wasm", encoding='utf8')) + msg = s.recv(1024) + except socket.error as e: + print("unable to connect to server") + s.close() + + success = "ok" + fail = "Fail!" + status = [success, fail] + print(msg) + if msg == b"fail": + return HttpResponse(json.dumps({ + "status": fail + })) + elif msg == b"success": + return HttpResponse(json.dumps({ + "status": success + })) + else: + return HttpResponse(json.dumps({ + "status": eval(msg.decode())["error message"].split(':')[1] + })) + + +def appDelete(req): + dev_addr = req.GET['ip'] + dev_port = req.GET['port'] + app_name = req.GET['name'] + + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + host = '127.0.0.1' + port = 8889 + s.connect((host, port)) + s.send(bytes("uninstall:"+dev_addr+":" + + str(dev_port)+":"+app_name, encoding='utf8')) + msg = s.recv(1024) + s.close() + r = HttpResponse("ok") + return r + +static_list = [{'ID': 'timer', 'Version': '1.0'}, {'ID': 'connection', 'Version': '1.0'}, {'ID': 'event_publisher', 'Version': '3.0'}, { + 'ID': 'event_subscriber', 'Version': '1.0'}, {'ID': 'reuqest_handler', 'Version': '1.0'}, {'ID': 'sensor', 'Version': '1.0'}, {'ID': 'ui_app', 'Version': '1.0'}] + +def store(req): + + store_path = os.path.join('static', 'upload') + status = [] + + print(user_file_list) + return render(req, 'appstore.html', {'staticlist': json.dumps(static_list), 'flist': json.dumps(user_file_list),'ulist':json.dumps(status)}) + +user_file_list = [] +files_list = [] +def uploadapps(req): + status = [] + local_list = ['timer','connection','event_publisher','event_subscriber','reuqest_handler','sensor'] + req.encoding = 'utf-8' + if req.method == 'POST': + myfile = req.FILES.get("myfile", None) + obj = req.FILES.get('myfile') + store_path = os.path.join('static', 'upload') + file_path = os.path.join('static', 'upload', obj.name) + + if not os.path.exists(store_path): + os.makedirs(store_path) + + file_name = obj.name.split(".")[0] + file_prefix = obj.name.split(".")[-1] + + + if file_prefix != "wasm": + status = ["Not a wasm file"] + elif file_name in local_list: + status = ["This App is preloaded"] + elif file_name in files_list: + status = ["This App is already uploaded"] + else: + status = [] + avaliable_list.append({'ID': file_name, 'Version': '1.0'}) + user_file_list.append({'ID': file_name, 'Version': '1.0'}) + files_list.append(file_name) + + print(user_file_list) + f = open(file_path, 'wb') + for chunk in obj.chunks(): + f.write(chunk) + f.close() + return render(req, 'appstore.html', {'staticlist': json.dumps(static_list), 'flist': json.dumps(user_file_list),'ulist':json.dumps(status)}) + +appname_list = [] + +def addapps(request): + types = '' + print("enter addapps") + request.encoding = 'utf-8' + app_dic = {'ID': '', 'Version': ''} + + # if request.method == 'get': + if "NAME" in request.GET: + a_name = request.GET['NAME'] + if a_name != "" and a_name not in appname_list: + appname_list.append(a_name) + message = request.GET['NAME'] + request.GET['Version'] + app_dic['ID'] = request.GET['NAME'] + app_dic['Version'] = request.GET['Version'] + avaliable_list.append(app_dic) + else: + types = "Exist" + print(avaliable_list) + return render(request, 'appstore.html', {'alist': json.dumps(avaliable_list)}) + +def removeapps(req): + app_name = req.GET['name'] + app_version = req.GET['version'] + remove_app = {'ID': app_name, 'Version': app_version} + avaliable_list.remove(remove_app) + user_file_list.remove(remove_app) + files_list.remove(app_name) + return render(req, 'appstore.html', {'alist': json.dumps(avaliable_list),'flist': json.dumps(user_file_list)}) + +# Test +if __name__ == "__main__": + print(device_list[0]['IP']) + print(device['IP']) diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/manage.py b/test-tools/IoT-APP-Store-Demo/wasm_django/manage.py new file mode 100755 index 00000000..341863cf --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/manage.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/mysite/__init__.py b/test-tools/IoT-APP-Store-Demo/wasm_django/mysite/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/mysite/settings.py b/test-tools/IoT-APP-Store-Demo/wasm_django/mysite/settings.py new file mode 100755 index 00000000..7eb3685c --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/mysite/settings.py @@ -0,0 +1,136 @@ +""" +Django settings for mysite project. + +Generated by 'django-admin startproject' using Django 2.2.2. + +For more information on this file, see +https://docs.djangoproject.com/en/2.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/2.2/ref/settings/ +""" + +import os +from django.conf.global_settings import STATIC_ROOT + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '8m05#6yx5wcygj*a+v6+=-y(#o+(z58-3!epq$u@5)64!mmu8q' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = ['*'] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + + 'devices', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'mysite.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'mysite.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/2.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/2.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + +APPEND_SLASH = False + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.2/howto/static-files/ + +STATIC_URL = '/static/' +HERE = os.path.dirname(os.path.abspath(__file__)) +HERE = os.path.join(HERE,'../') +STATICFILES_DIRS = (os.path.join(HERE,'static/'),) +#STATICFILES_DIRS = (os.path.join(BASE_DIR,'static'),) +#STATIC_ROOT = (os.path.join(os.path.dirname(_file_),'static') +#templates +TEMPLATE_DIRS=[ + '/home/xujun/mysite/templates', +] + diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/mysite/urls.py b/test-tools/IoT-APP-Store-Demo/wasm_django/mysite/urls.py new file mode 100755 index 00000000..8a74b550 --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/mysite/urls.py @@ -0,0 +1,41 @@ +#config:utf-8 + +"""mysite URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/2.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +#from django.conf.urls import include,url +from django.urls import path,include +from devices import views as devices_views +#from login import views as login_views + + +urlpatterns = [ + + path('admin/', admin.site.urls), + path('',devices_views.index), + path('apps/',devices_views.apps), + path('appDownload/', devices_views.appDownload), + path('appDelete/', devices_views.appDelete), + path('appstore/',devices_views.store), +## path('apps/appstore/',devices_views.storeofdevic), +## path('search/',devices_views.search), + path('upload',devices_views.uploadapps), + path('removeapps/',devices_views.removeapps), + path('help/',devices_views.help), + +] + + diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/mysite/wsgi.py b/test-tools/IoT-APP-Store-Demo/wasm_django/mysite/wsgi.py new file mode 100755 index 00000000..45e28c9a --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/mysite/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for mysite project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings') + +application = get_wsgi_application() diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/server/wasm_server.py b/test-tools/IoT-APP-Store-Demo/wasm_django/server/wasm_server.py new file mode 100755 index 00000000..1754b368 --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/server/wasm_server.py @@ -0,0 +1,616 @@ +''' + /* Copyright (C) 2019 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +''' +import select +import socket +import queue +from time import sleep +import struct +import threading +import time +from ctypes import * +import json +import logging +import os + +attr_type_list = [ + "ATTR_NONE", + "ATTR_TYPE_SHORT", + "ATTR_TYPE_INT", + "ATTR_TYPE_INT64", + "ATTR_TYPE_BYTE", + "ATTR_TYPE_UINT16", + "ATTR_TYPE_FLOAT", + "ATTR_TYPE_DOUBLE", + "ATTR_TYPE_BOOLEAN", + "ATTR_TYPE_STRING", + "ATTR_TYPE_BYTEARRAY" +] + + +Phase_Non_Start = 0 +Phase_Leading = 1 +Phase_Type = 2 +Phase_Size = 3 +Phase_Payload = 4 + + + +class imrt_link_message(object): + def __init__(self): + self.leading = bytes([0x12, 0x34]) + self.phase = Phase_Non_Start + self.size_in_phase = 0 + self.message_type = bytes() + self.message_size = bytes() + self.payload = bytes() + self.msg = bytes() + + def set_recv_phase(self, phase): + self.phase = phase + + def on_imrt_link_byte_arrive(self, ch): + self.msg += ch + if self.phase == Phase_Non_Start: + if ch == b'\x12': + self.set_recv_phase(Phase_Leading) + else: + return -1 + elif self.phase == Phase_Leading: + if ch == b'\x34': + self.set_recv_phase(Phase_Type) + else: + self.set_recv_phase(Phase_Non_Start) + return -1 + elif self.phase == Phase_Type: + self.message_type += ch + self.size_in_phase += 1 + + if self.size_in_phase == 2: + (self.message_type, ) = struct.unpack('!H', self.message_type) + self.size_in_phase = 0 + self.set_recv_phase(Phase_Size) + elif self.phase == Phase_Size: + self.message_size += ch + self.size_in_phase += 1 + + if self.size_in_phase == 4: + (self.message_size, ) = struct.unpack('!I', self.message_size) + self.size_in_phase = 0 + self.set_recv_phase(Phase_Payload) + + if self.message_size == b'\x00': + self.set_recv_phase(Phase_Non_Start) + return 0 + + self.set_recv_phase(Phase_Payload) + + elif self.phase == Phase_Payload: + self.payload += ch + self.size_in_phase += 1 + + if self.size_in_phase == self.message_size: + self.set_recv_phase(Phase_Non_Start) + return 0 + + return 2 + + return 1 + + + +def read_file_to_buffer(file_name): + file_object = open(file_name, 'rb') + buffer = None + + if not os.path.exists(file_name): + logging.error("file {} not found.".format(file_name)) + return "file not found" + + try: + buffer = file_object.read() + finally: + file_object.close() + + return buffer + +def decode_attr_container(msg): + + attr_dict = {} + + buf = msg[26 : ] + (total_len, tag_len) = struct.unpack('@IH', buf[0 : 6]) + tag_name = buf[6 : 6 + tag_len].decode() + buf = buf[6 + tag_len : ] + (attr_num, ) = struct.unpack('@H', buf[0 : 2]) + buf = buf[2 : ] + + logging.info("parsed attr:") + logging.info("total_len:{}, tag_len:{}, tag_name:{}, attr_num:{}" + .format(str(total_len), str(tag_len), str(tag_name), str(attr_num))) + + for i in range(attr_num): + (key_len, ) = struct.unpack('@H', buf[0 : 2]) + key_name = buf[2 : 2 + key_len - 1].decode() + buf = buf[2 + key_len : ] + (type_index, ) = struct.unpack('@c', buf[0 : 1]) + + attr_type = attr_type_list[int(type_index[0])] + buf = buf[1 : ] + + if attr_type == "ATTR_TYPE_SHORT": + (attr_value, ) = struct.unpack('@h', buf[0 : 2]) + buf = buf[2 : ] + # continue + elif attr_type == "ATTR_TYPE_INT": + (attr_value, ) = struct.unpack('@I', buf[0 : 4]) + buf = buf[4 : ] + # continue + elif attr_type == "ATTR_TYPE_INT64": + (attr_value, ) = struct.unpack('@q', buf[0 : 8]) + buf = buf[8 : ] + # continue + elif attr_type == "ATTR_TYPE_BYTE": + (attr_value, ) = struct.unpack('@c', buf[0 : 1]) + buf = buf[1 : ] + # continue + elif attr_type == "ATTR_TYPE_UINT16": + (attr_value, ) = struct.unpack('@H', buf[0 : 2]) + buf = buf[2 : ] + # continue + elif attr_type == "ATTR_TYPE_FLOAT": + (attr_value, ) = struct.unpack('@f', buf[0 : 4]) + buf = buf[4 : ] + # continue + elif attr_type == "ATTR_TYPE_DOUBLE": + (attr_value, ) = struct.unpack('@d', buf[0 : 8]) + buf = buf[8 : ] + # continue + elif attr_type == "ATTR_TYPE_BOOLEAN": + (attr_value, ) = struct.unpack('@?', buf[0 : 1]) + buf = buf[1 : ] + # continue + elif attr_type == "ATTR_TYPE_STRING": + (str_len, ) = struct.unpack('@H', buf[0 : 2]) + attr_value = buf[2 : 2 + str_len - 1].decode() + buf = buf[2 + str_len : ] + # continue + elif attr_type == "ATTR_TYPE_BYTEARRAY": + (byte_len, ) = struct.unpack('@I', buf[0 : 4]) + attr_value = buf[4 : 4 + byte_len] + buf = buf[4 + byte_len : ] + # continue + + attr_dict[key_name] = attr_value + + logging.info(str(attr_dict)) + return attr_dict + +class Request(): + mid = 0 + url = "" + action = 0 + fmt = 0 + payload = "" + payload_len = 0 + sender = 0 + + def __init__(self, url, action, fmt, payload, payload_len): + self.url = url + self.action = action + self.fmt = fmt + # if type(payload) == bytes: + # self.payload = bytes(payload, encoding = "utf8") + # else: + self.payload_len = payload_len + if self.payload_len > 0: + self.payload = payload + + + def pack_request(self): + url_len = len(self.url) + 1 + buffer_len = url_len + self.payload_len + + req_buffer = struct.pack('!2BH2IHI',1, self.action, self.fmt, self.mid, self.sender, url_len, self.payload_len) + for i in range(url_len - 1): + req_buffer += struct.pack('!c', bytes(self.url[i], encoding = "utf8")) + req_buffer += bytes([0]) + for i in range(self.payload_len): + req_buffer += struct.pack('!B', self.payload[i]) + + return req_buffer, len(req_buffer) + + + def send(self, conn, is_install): + leading = struct.pack('!2B', 0x12, 0x34) + + if not is_install: + msg_type = struct.pack('!H', 0x0002) + else: + msg_type = struct.pack('!H', 0x0004) + buff, buff_len = self.pack_request() + lenth = struct.pack('!I', buff_len) + + try: + conn.send(leading) + conn.send(msg_type) + conn.send(lenth) + conn.send(buff) + except socket.error as e: + logging.error("device closed") + for dev in tcpserver.devices: + if dev.conn == conn: + tcpserver.devices.remove(dev) + return -1 + + +def query(conn): + req = Request("/applet", 1, 0, "", 0) + if req.send(conn, False) == -1: + return "fail" + time.sleep(0.05) + try: + receive_context = imrt_link_message() + start = time.time() + while True: + if receive_context.on_imrt_link_byte_arrive(conn.recv(1)) == 0: + break + elif time.time() - start >= 5.0: + return "fail" + query_resp = receive_context.msg + print(query_resp) + except OSError as e: + logging.error("OSError exception occur") + return "fail" + + res = decode_attr_container(query_resp) + + logging.info('Query device infomation success') + return res + +def install(conn, app_name, wasm_file): + wasm = read_file_to_buffer(wasm_file) + if wasm == "file not found": + return "failed to install: file not found" + + print("wasm file len:") + print(len(wasm)) + req = Request("/applet?name=" + app_name, 3, 98, wasm, len(wasm)) + if req.send(conn, True) == -1: + return "fail" + time.sleep(0.05) + try: + receive_context = imrt_link_message() + start = time.time() + while True: + if receive_context.on_imrt_link_byte_arrive(conn.recv(1)) == 0: + break + elif time.time() - start >= 5.0: + return "fail" + msg = receive_context.msg + except OSError as e: + logging.error("OSError exception occur") + # TODO: check return message + + if len(msg) == 24 and msg[8 + 1] == 65: + logging.info('Install application success') + return "success" + else: + res = decode_attr_container(msg) + logging.warning('Install application failed: %s' % (str(res))) + print(str(res)) + + return str(res) + + +def uninstall(conn, app_name): + req = Request("/applet?name=" + app_name, 4, 99, "", 0) + if req.send(conn, False) == -1: + return "fail" + time.sleep(0.05) + try: + receive_context = imrt_link_message() + start = time.time() + while True: + if receive_context.on_imrt_link_byte_arrive(conn.recv(1)) == 0: + break + elif time.time() - start >= 5.0: + return "fail" + msg = receive_context.msg + except OSError as e: + logging.error("OSError exception occur") + # TODO: check return message + + if len(msg) == 24 and msg[8 + 1] == 66: + logging.info('Uninstall application success') + return "success" + else: + res = decode_attr_container(msg) + logging.warning('Uninstall application failed: %s' % (str(res))) + print(str(res)) + + return str(res) + +class Device: + def __init__(self, conn, addr, port): + self.conn = conn + self.addr = addr + self.port = port + self.app_num = 0 + self.apps = [] + +cmd = [] + +class TCPServer: + def __init__(self, server, server_address, inputs, outputs, message_queues): + # Create a TCP/IP + self.server = server + self.server.setblocking(False) + + # Bind the socket to the port + self.server_address = server_address + print('starting up on %s port %s' % self.server_address) + self.server.bind(self.server_address) + + # Listen for incoming connections + self.server.listen(10) + + self.cmd_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.cmd_sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) + + self.cmd_sock.bind(('127.0.0.1', 8889)) + self.cmd_sock.listen(5) + + + # Sockets from which we expect to read + self.inputs = inputs + self.inputs.append(self.cmd_sock) + + # Sockets to which we expect to write + # 处理要发送的消息 + self.outputs = outputs + # Outgoing message queues (socket: Queue) + self.message_queues = message_queues + + self.devices = [] + self.conn_dict = {} + + def handler_recever(self, readable): + # Handle inputs + for s in readable: + if s is self.server: + # A "readable" socket is ready to accept a connection + connection, client_address = s.accept() + self.client_address = client_address + print('connection from', client_address) + # this is connection not server + # connection.setblocking(0) + self.inputs.append(connection) + + # Give the connection a queue for data we want to send + # self.message_queues[connection] = queue.Queue() + + res = query(connection) + + if res != "fail": + dev = Device(connection, client_address[0], client_address[1]) + self.devices.append(dev) + self.conn_dict[client_address] = connection + + dev_info = {} + dev_info['addr'] = dev.addr + dev_info['port'] = dev.port + dev_info['apps'] = 0 + + logging.info('A new client connected from ("%s":"%s")' % (dev.conn, dev.port)) + + elif s is self.cmd_sock: + connection, client_address = s.accept() + print("web server socket connected") + logging.info("Django server connected") + self.inputs.append(connection) + self.message_queues[connection] = queue.Queue() + + else: + data = s.recv(1024) + if data != b'': + # A readable client socket has data + logging.info('received "%s" from %s' % (data, s.getpeername())) + + # self.message_queues[s].put(data) + # # Add output channel for response + + # if s not in self.outputs: + # self.outputs.append(s) + + if(data.decode().split(':')[0] == "query"): + if data.decode().split(':')[1] == "all": + resp = [] + print('start query all devices') + for dev in self.devices: + dev_info = query(dev.conn) + if dev_info == "fail": + continue + dev_info["addr"] = dev.addr + dev_info["port"] = dev.port + resp.append(str(dev_info)) + + print(resp) + + if self.message_queues[s] is not None: + # '*' is used in web server to sperate the string + self.message_queues[s].put(bytes("*".join(resp), encoding = 'utf8')) + if s not in self.outputs: + self.outputs.append(s) + else: + client_addr = (data.decode().split(':')[1],int(data.decode().split(':')[2])) + + if client_addr in self.conn_dict.keys(): + print('start query device from (%s:%s)' % (client_addr[0], client_addr[1])) + resp = query(self.conn_dict[client_addr]) + print(resp) + + if self.message_queues[s] is not None: + self.message_queues[s].put(bytes(str(resp), encoding = 'utf8')) + if s not in self.outputs: + self.outputs.append(s) + else: # no connection + if self.message_queues[s] is not None: + self.message_queues[s].put(bytes(str("fail"), encoding = 'utf8')) + if s not in self.outputs: + self.outputs.append(s) + elif(data.decode().split(':')[0] == "install"): + client_addr = (data.decode().split(':')[1],int(data.decode().split(':')[2])) + app_name = data.decode().split(':')[3] + app_file = data.decode().split(':')[4] + + if client_addr in self.conn_dict.keys(): + print('start install application %s to ("%s":"%s")' % (app_name, client_addr[0], client_addr[1])) + res = install(self.conn_dict[client_addr], app_name, app_file) + if self.message_queues[s] is not None: + logging.info("response {} to cmd server".format(res)) + self.message_queues[s].put(bytes(res, encoding = 'utf8')) + if s not in self.outputs: + self.outputs.append(s) + elif(data.decode().split(':')[0] == "uninstall"): + client_addr = (data.decode().split(':')[1],int(data.decode().split(':')[2])) + app_name = data.decode().split(':')[3] + + if client_addr in self.conn_dict.keys(): + print("start uninstall") + res = uninstall(self.conn_dict[client_addr], app_name) + if self.message_queues[s] is not None: + logging.info("response {} to cmd server".format(res)) + self.message_queues[s].put(bytes(res, encoding = 'utf8')) + if s not in self.outputs: + self.outputs.append(s) + + + # if self.message_queues[s] is not None: + # self.message_queues[s].put(data) + # if s not in self.outputs: + # self.outputs.append(s) + else: + logging.warning(data) + + # Interpret empty result as closed connection + try: + for dev in self.devices: + if s == dev.conn: + self.devices.remove(dev) + # Stop listening for input on the connection + if s in self.outputs: + self.outputs.remove(s) + self.inputs.remove(s) + + # Remove message queue + if s in self.message_queues.keys(): + del self.message_queues[s] + s.close() + except OSError as e: + logging.error("OSError raised, unknown connection") + return "got it" + + def handler_send(self, writable): + # Handle outputs + for s in writable: + try: + message_queue = self.message_queues.get(s) + send_data = '' + if message_queue is not None: + send_data = message_queue.get_nowait() + except queue.Empty: + self.outputs.remove(s) + else: + # print "sending %s to %s " % (send_data, s.getpeername) + # print "send something" + if message_queue is not None: + s.send(send_data) + else: + print("client has closed") + # del message_queues[s] + # writable.remove(s) + # print "Client %s disconnected" % (client_address) + return "got it" + + def handler_exception(self, exceptional): + # # Handle "exceptional conditions" + for s in exceptional: + print('exception condition on', s.getpeername()) + # Stop listening for input on the connection + self.inputs.remove(s) + if s in self.outputs: + self.outputs.remove(s) + s.close() + + # Remove message queue + del self.message_queues[s] + return "got it" + + +def event_loop(tcpserver, inputs, outputs): + while inputs: + # Wait for at least one of the sockets to be ready for processing + print('waiting for the next event') + readable, writable, exceptional = select.select(inputs, outputs, inputs) + if readable is not None: + tcp_recever = tcpserver.handler_recever(readable) + if tcp_recever == 'got it': + print("server have received") + if writable is not None: + tcp_send = tcpserver.handler_send(writable) + if tcp_send == 'got it': + print("server have send") + if exceptional is not None: + tcp_exception = tcpserver.handler_exception(exceptional) + if tcp_exception == 'got it': + print("server have exception") + + + sleep(0.1) + +def run_wasm_server(): + server_address = ('localhost', 8888) + server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) + inputs = [server] + outputs = [] + message_queues = {} + tcpserver = TCPServer(server, server_address, inputs, outputs, message_queues) + + task = threading.Thread(target=event_loop,args=(tcpserver,inputs,outputs)) + task.start() + +if __name__ == '__main__': + logging.basicConfig(level=logging.DEBUG, + filename='wasm_server.log', + filemode='a', + format= + '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s' + ) + server_address = ('0.0.0.0', 8888) + server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) + inputs = [server] + outputs = [] + message_queues = {} + tcpserver = TCPServer(server, server_address, inputs, outputs, message_queues) + logging.info("TCP Server start at {}:{}".format(server_address[0], "8888")) + + task = threading.Thread(target=event_loop,args=(tcpserver,inputs,outputs)) + task.start() + + # event_loop(tcpserver, inputs, outputs) \ No newline at end of file diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/static/css/application.css b/test-tools/IoT-APP-Store-Demo/wasm_django/static/css/application.css new file mode 100644 index 00000000..5876b942 --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/static/css/application.css @@ -0,0 +1,411 @@ +/* Copyright (C) 2019 Intel Corporation. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{% load static %} + diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/static/js/application.js b/test-tools/IoT-APP-Store-Demo/wasm_django/static/js/application.js new file mode 100644 index 00000000..d359962e --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/static/js/application.js @@ -0,0 +1,228 @@ +/* Copyright (C) 2019 Intel Corporation. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* + * Dom Location + * + */ + + function setDivCenter(divname) +// make qn element center aligned + { + var Top =($(window).height()-$(divname).height())/2; + var Left = ($(window).width()-$(divname).width())/2; + var scrollTop = $(document).scrollTop(); + var scrollLeft = $(document).scrollLeft(); + $(divname).css({posisiton:'absolute','top':Top+scrollTop,'left':Left+scrollLeft}); + +}; + +setDivCenter(".middlebox"); +setDivCenter(".deletebox"); + +function setmain(divname){ +// Set the pop-up window of apps for download at the right place + var x = $('#btn').offset().top; + var Top = x + $('#btn').height()+15; + var y = $('#btn').offset().left; + var Left = y + ($('#btn').width()/2)-($(divname).width()/2); + console.log(Top,Left) + $(divname).css({'top':Top,'left':Left}); +} +setmain(".main") + +/* + * download apps + * + */ + +function getthis(val) +//Telling background which app to be loaded from appstore_list and to be installed in the current device. +{ + + /* Get the ip adress and the port of a device, as well as the application ID to be downloaded on this device*/ + var ip,port,name,version; + var ipArr=$("#IPs").text().split(":"); + ip=ipArr[1]; + var portArr=$("#ports").text().split(":"); + port=portArr[1]; + name = $(val).parent().find("#appsinfo1").text().split(":")[1]; + version = $(val).parent().find("#appsinfo2").text().split(":")[1]; + $(".main").fadeOut(); + + for (num in alist){ + if (alist[num]['pname'].trim() == name.trim()) + {alert("This app has been downloaded."); + return;}}; + $("#loading").fadeIn(); + var sNode = document.getElementById("APPS"); + var tempNode= sNode.cloneNode(true); + sNode.parentNode.appendChild(tempNode); + $("#appinfo1").html("Product Name : "+ name); + $("#appinfo2").html("Status : "+"Installing"); + $("#appinfo3").html("Current_Version : "+ version); + + $.get("/appDownload/",{'ip':ip.trim(),'port':port.trim(),'name':name.trim(),},function (ret) { + var status = $.trim(ret.split(":")[1].split("}")[0]); + $(".loadapp").html(name+" is downloading now"); + var msg = JSON.parse(status) + console.log(msg) + if (JSON.parse(status)=="ok"){ + $(".middlebox").fadeIn(); + $(".sourceapp").fadeOut(); + $("#loading").fadeOut(); + $(".findapp").html("Download "+name +" successfully"); + $(".surebtn").click(function (){ + $(".middlebox").fadeOut(); + window.location.reload(); + })} + else if (JSON.parse(status)=="Fail!"){ + alert("Download failed!"); + $("#loading").fadeOut(); + sNode.remove(); + } + else { + alert("Install app failed:" + msg) + $("#loading").fadeOut(); + sNode.remove(); + } + }) +}; + +window.onload = function clone() +//Add & Delete apps to the device. +{ + /*Install Apps*/ + var sourceNode = document.getElementById("APPS"); + if (alist.length != 0) + { + $("#appinfo1").html("Product Name : "+ alist[0]['pname']); + $("#appinfo2").html("Status : "+ alist[0]['status']); + $("#appinfo3").html("Current_Version : "+ alist[0]['current_version']); + $("#delete").attr('class','delet0'); + $("#APPS").attr('class','app0'); + + for (var i=1; i=3){ + alert("Install app failed: exceed max app installations.") + } + $(".main").fadeOut(); + getthis(".mybtn2"); + var newurl = "?"+"ip="+ip+"&port="+port; + window.location.href= newurl; + }); + + } +} +givevalue(); + +function popbox(){ +/*Open and close the "install apps" window*/ + $(".btn").click(function(){ + $(".main").fadeIn(); + }); + $(".close").click(function(){ + $(".main").fadeOut(); + }); +}; +popbox(); diff --git a/test-tools/IoT-APP-Store-Demo/wasm_django/static/js/appstore.js b/test-tools/IoT-APP-Store-Demo/wasm_django/static/js/appstore.js new file mode 100644 index 00000000..911de1f0 --- /dev/null +++ b/test-tools/IoT-APP-Store-Demo/wasm_django/static/js/appstore.js @@ -0,0 +1,136 @@ +/* Copyright (C) 2019 Intel Corporation. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +function setDivCenter(divname) +//Center a dom +{ + var Top =($(window).height()-$(divname).height())/2; + var Left = ($(window).width()-$(divname).width())/2; + var scrollTop = $(document).scrollTop(); + var scrollLeft = $(document).scrollLeft(); + $(divname).css({posisiton:'absolute','top':Top+scrollTop,'left':Left+scrollLeft}); + +}; +setDivCenter(".deletebox"); + +function setDivheight(divname) +//set the height of "appbook" to contain all its child elements. +{ + var leng = elist.length + flist.length; + var heig = 51 * leng; + $(divname).css({height:'heig'}); +}; +setDivheight(".appbook"); + +function setfooterposition(divname) +//Locate footer on the right place +{ + var Top = flist.length* $("#devices").height()+300; + var scrollTop = $(document).scrollTop(); + if (flist.length >=4){ + $(divname).css({posisiton:'absolute','top':Top+scrollTop}); + } +} +setfooterposition(".footer"); + +function deleteClick (obj) +//Remove an app from apppstore if clicks the "OK" button +{ + var indexapp = $(obj).attr('class').match(/\d+\b/); + var removeitem = $(".applic"+indexapp); + var name=removeitem.find('#appinfo1').text().split(":")[1].trim(); + var version=removeitem.find('#appinfo2').text().split(":")[1].trim(); + + if (flist.length >= 1){ + $(".deletebox").fadeIn(); + $(".findapp").html("Are you sure to delete "+name); + $(".suresbtn").click(function (){ + removeitem.remove(); + $.get("/removeapps/",{'name':name,'version':version},function (ret) { + console.log(ret);}); + $(".deletebox").fadeOut(); + window.location.href="/appstore/"; + }) + $(".delsbtn").click(function (){ + $(".deletebox").fadeOut(); })} +}; + +function upload_file() +//Make sure the uploading file is eligible +{ + var type = ulist[0]; + console.log(type); + if (type == "Not a wasm file"){ + alert(type); + window.location.href="/appstore/"; + } + if (type == "This App is preloaded"){ + alert(type); + window.location.href="/appstore/"; + } + if (type == "This App is already uploaded"){ + alert(type); + window.location.href="/appstore/"; + } +}; +upload_file(); + + +function clone() +//Render a interface that shows all the apps for installing in appstore, +//including preloaded ones and locally uploaded ones. +{ + + var sourceNode = document.getElementById("applications"); + $("#appinfo1").html("product name : "+ elist[0]['ID']); + $("#appinfo2").html("product Version : "+ elist[0]['Version']); + $("#delbutton").attr('class','del0'); + $("#applications").attr('class','applic0'); + + + for (var i=1; i=4){ + $(divname).css({posisiton:'absolute','top':Top+scrollTop}); + } +} +setfooterposition(".footer"); + +window.onload = function clone() +//Show the list of connected devices +{ + var sourceNode = document.getElementById("devices"); + $("#IPs").html("IP : "+ dlist[0]['IP']); + $("#ports").html("Port : "+ dlist[0]['Port']); + $("#installs").html("Installed Apps : "+ dlist[0]['apps']); + $("#devices").attr('class','devic0'); + $("#dbutton").attr('class','bt0'); + $("#choose").attr('class','chos0'); + + for (var i=1; i