Refactor WASM runner and logging functionality; add heartbeat task and improve initialization process
This commit is contained in:
+2
-2
@@ -84,10 +84,11 @@ else()
|
|||||||
# WAMR Desktop-Konfiguration
|
# WAMR Desktop-Konfiguration
|
||||||
set(WAMR_BUILD_INTERP 1 CACHE BOOL "" FORCE)
|
set(WAMR_BUILD_INTERP 1 CACHE BOOL "" FORCE)
|
||||||
set(WAMR_BUILD_FAST_INTERP 1 CACHE BOOL "" FORCE)
|
set(WAMR_BUILD_FAST_INTERP 1 CACHE BOOL "" FORCE)
|
||||||
|
# set(WAMR_BUILD_INTERP_TICKS 1 CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
set(WAMR_BUILD_JIT 0 CACHE BOOL "" FORCE)
|
set(WAMR_BUILD_JIT 0 CACHE BOOL "" FORCE)
|
||||||
set(WAMR_BUILD_AOT 0 CACHE BOOL "" FORCE)
|
set(WAMR_BUILD_AOT 0 CACHE BOOL "" FORCE)
|
||||||
set(WAMR_BUILD_LIBC_BUILTIN 1 CACHE BOOL "" FORCE)
|
set(WAMR_BUILD_LIBC_BUILTIN 1 CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
# Disable WASI
|
# Disable WASI
|
||||||
set(WAMR_BUILD_LIBC_WASI 0 CACHE BOOL "" FORCE)
|
set(WAMR_BUILD_LIBC_WASI 0 CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
@@ -99,7 +100,6 @@ else()
|
|||||||
set(WAMR_BUILD_PLATFORM "linux" CACHE STRING "" FORCE)
|
set(WAMR_BUILD_PLATFORM "linux" CACHE STRING "" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# define Target 'freertos_kernel'
|
|
||||||
FetchContent_MakeAvailable(FreeRTOS_Kernel wamr_runtime)
|
FetchContent_MakeAvailable(FreeRTOS_Kernel wamr_runtime)
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
/* Desktop Simulator Settings */
|
/* Desktop Simulator Settings */
|
||||||
#define configUSE_PREEMPTION 1
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_TIME_SLICING 1
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
#define configUSE_IDLE_HOOK 1
|
#define configUSE_IDLE_HOOK 1
|
||||||
#define configUSE_TICK_HOOK 0
|
#define configUSE_TICK_HOOK 0
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#ifndef NOVA64_API_H
|
#ifndef NOVA64_API_H
|
||||||
#define NOVA64_API_H
|
#define NOVA64_API_H
|
||||||
|
|
||||||
void register_nova64_imports(void);
|
void nova64_register_imports(void);
|
||||||
|
|
||||||
#endif // NOVA64_API_H
|
#endif // NOVA64_API_H
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ bool wasm_runner_initialize(void);
|
|||||||
*/
|
*/
|
||||||
bool wasm_runner_start_program(
|
bool wasm_runner_start_program(
|
||||||
const char *module_path,
|
const char *module_path,
|
||||||
const wasm_runner_framebuffer_config_t *framebuffer_config,
|
const wasm_runner_framebuffer_config_t *framebuffer_config);
|
||||||
wasm_runner_instance_t **out_instance);
|
|
||||||
|
void wasm_runner_terminate(void);
|
||||||
|
|
||||||
#endif // WASM_RUNNER_H
|
#endif // WASM_RUNNER_H
|
||||||
|
|||||||
+23
-5
@@ -1,24 +1,42 @@
|
|||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
#include "nova64_internal.h"
|
||||||
|
#include "projdefs.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "wasm_export.h"
|
#include "wasm_export.h"
|
||||||
#include "projdefs.h"
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
static void native_yield(wasm_exec_env_t exec_env, uint32_t timeout_ms) {
|
static void native_yield(wasm_exec_env_t exec_env, uint32_t timeout_ms) {
|
||||||
if (timeout_ms == 0) {
|
if (timeout_ms == 0) {
|
||||||
// Gibt die Rest-Quantenzeit ab, blockiert aber nicht künstlich
|
|
||||||
taskYIELD();
|
taskYIELD();
|
||||||
} else {
|
} else {
|
||||||
// Blockiert den Task für x Millisekunden
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(timeout_ms));
|
vTaskDelay(pdMS_TO_TICKS(timeout_ms));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void native_log(wasm_exec_env_t exec_env, const char *message) {
|
||||||
|
(void)exec_env;
|
||||||
|
|
||||||
|
nova64_log("[WASM LOG] ");
|
||||||
|
|
||||||
|
const char *text = message ? message : "";
|
||||||
|
size_t len = strlen(text);
|
||||||
|
bool has_newline = len > 0 && text[len - 1] == '\n';
|
||||||
|
|
||||||
|
if (has_newline) {
|
||||||
|
nova64_log("%s", text);
|
||||||
|
} else {
|
||||||
|
nova64_log("%s\n", text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static NativeSymbol native_symbols[] = {
|
static NativeSymbol native_symbols[] = {
|
||||||
{"yield", (void *)native_yield, "(i)", NULL},
|
{"nova64_yield", (void *)native_yield, "(i)", NULL},
|
||||||
|
{"nova64_log", (void *)native_log, "($)", NULL},
|
||||||
// { "flush_framebuffer", (void*)native_flush_framebuffer, "()", NULL }
|
// { "flush_framebuffer", (void*)native_flush_framebuffer, "()", NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
void register_nova64_imports(void) {
|
void nova64_register_imports(void) {
|
||||||
wasm_runtime_register_natives("nova64", native_symbols,
|
wasm_runtime_register_natives("nova64", native_symbols,
|
||||||
sizeof(native_symbols) / sizeof(NativeSymbol));
|
sizeof(native_symbols) / sizeof(NativeSymbol));
|
||||||
}
|
}
|
||||||
+105
-40
@@ -24,14 +24,48 @@ static nova64_io_interface_t g_io_interface_storage;
|
|||||||
static const nova64_io_interface_t *g_io_interface = NULL;
|
static const nova64_io_interface_t *g_io_interface = NULL;
|
||||||
static QueueHandle_t event_queue = NULL;
|
static QueueHandle_t event_queue = NULL;
|
||||||
static TaskHandle_t boot_task_handle = NULL;
|
static TaskHandle_t boot_task_handle = NULL;
|
||||||
static TaskHandle_t launcher_task_handle = NULL;
|
static TaskHandle_t init_task_handle = NULL;
|
||||||
|
static TaskHandle_t heartbeat_task_handle = NULL;
|
||||||
|
|
||||||
#if defined(NOVA64_SHUTDOWN_AVAILABLE)
|
#if defined(NOVA64_SHUTDOWN_AVAILABLE)
|
||||||
static TaskHandle_t shutdown_task_handle = NULL;
|
static TaskHandle_t shutdown_task_handle = NULL;
|
||||||
static volatile bool shutdown_requested = false;
|
volatile bool shutdown_requested = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char *const kInternalLauncherPath = "SYS:/launcher.wasm";
|
static const char *const kInternalInitPath = "SYS:/init.wasm";
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
static SRWLOCK g_log_lock = SRWLOCK_INIT;
|
||||||
|
|
||||||
|
static inline void log_lock(void) { AcquireSRWLockExclusive(&g_log_lock); }
|
||||||
|
static inline void log_unlock(void) { ReleaseSRWLockExclusive(&g_log_lock); }
|
||||||
|
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
#include <pthread.h>
|
||||||
|
static pthread_mutex_t g_log_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
static inline void log_lock(void) { pthread_mutex_lock(&g_log_lock); }
|
||||||
|
static inline void log_unlock(void) { pthread_mutex_unlock(&g_log_lock); }
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include "semphr.h"
|
||||||
|
static SemaphoreHandle_t g_log_lock = NULL;
|
||||||
|
|
||||||
|
static inline void log_lock(void) {
|
||||||
|
if (!g_log_lock) {
|
||||||
|
g_log_lock = xSemaphoreCreateMutex();
|
||||||
|
}
|
||||||
|
if (g_log_lock && xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
|
xSemaphoreTake(g_log_lock, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static inline void log_unlock(void) {
|
||||||
|
if (g_log_lock && xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
|
xSemaphoreGive(g_log_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void nova64_log(const char *format, ...) {
|
void nova64_log(const char *format, ...) {
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
@@ -40,48 +74,41 @@ void nova64_log(const char *format, ...) {
|
|||||||
vsnprintf(buffer, sizeof(buffer), format, args);
|
vsnprintf(buffer, sizeof(buffer), format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
|
log_lock();
|
||||||
|
|
||||||
if (g_io_interface && g_io_interface->log_message) {
|
if (g_io_interface && g_io_interface->log_message) {
|
||||||
g_io_interface->log_message(buffer);
|
g_io_interface->log_message(buffer);
|
||||||
} else {
|
} else {
|
||||||
fputs(buffer, stdout);
|
fputs(buffer, stdout);
|
||||||
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool initialize_wasm_runtime(void) {
|
static bool initialize_wasm_runtime(void) {
|
||||||
nova64_log("Initializing WASM runtime...\n");
|
nova64_log("Initializing WASM runtime...\n");
|
||||||
wasm_runner_initialize();
|
wasm_runner_initialize();
|
||||||
// TODO: Replace this stub with real WAMR initialization.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool load_launcher_from_internal_storage(void) {
|
static void start_init_from_internal_storage(void *params) {
|
||||||
nova64_log("Loading launcher from internal storage (%s)...\n",
|
|
||||||
kInternalLauncherPath);
|
|
||||||
// TODO: Implement the actual internal storage filesystem and launcher load.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nova64_wasm_launcher_task(void *params) {
|
|
||||||
(void)params;
|
(void)params;
|
||||||
nova64_log("WASM launcher task started.\n");
|
wasm_runner_start_program(kInternalInitPath, NULL);
|
||||||
|
|
||||||
// TODO: Execute the loaded WASM launcher module here with the WAMR engine.
|
|
||||||
for (;;) {
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool start_launcher_task(void) {
|
static bool start_init_task(void) {
|
||||||
BaseType_t result = xTaskCreate(nova64_wasm_launcher_task, "Nova64Launcher",
|
BaseType_t result =
|
||||||
4096 / sizeof(StackType_t), NULL,
|
xTaskCreate(start_init_from_internal_storage, "Nova64Init",
|
||||||
tskIDLE_PRIORITY + 1, &launcher_task_handle);
|
4096 / sizeof(StackType_t), NULL, tskIDLE_PRIORITY + 1,
|
||||||
|
&init_task_handle);
|
||||||
|
|
||||||
if (result != pdPASS) {
|
if (result != pdPASS) {
|
||||||
nova64_log("Failed to create launcher task.\n");
|
nova64_log("Failed to create init task.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nova64_log("Launcher task created successfully.\n");
|
nova64_log("Init task created successfully.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,14 +117,34 @@ static void nova64_shutdown_task(void *params) {
|
|||||||
(void)params;
|
(void)params;
|
||||||
|
|
||||||
nova64_log("Shutdown task started.\n");
|
nova64_log("Shutdown task started.\n");
|
||||||
|
shutdown_requested = false;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
ulTaskNotifyTake(pdTRUE,
|
||||||
|
pdMS_TO_TICKS(50)); // Wait for notification or timeout
|
||||||
if (shutdown_requested) {
|
if (shutdown_requested) {
|
||||||
nova64_log("Shutdown requested; ending scheduler.\n");
|
break;
|
||||||
vTaskEndScheduler();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nova64_log("Shutdown requested; terminating WASM runtime.\n");
|
||||||
|
|
||||||
|
wasm_runner_terminate();
|
||||||
|
|
||||||
|
if (heartbeat_task_handle != NULL) {
|
||||||
|
vTaskDelete(heartbeat_task_handle);
|
||||||
|
heartbeat_task_handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(100)); // Allow time for tasks to clean up
|
||||||
|
|
||||||
|
shutdown_task_handle = NULL;
|
||||||
|
#if defined(_WIN32)
|
||||||
|
ExitThread(0);
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
pthread_exit(NULL);
|
||||||
|
#else
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool start_shutdown_task(void) {
|
static bool start_shutdown_task(void) {
|
||||||
@@ -115,6 +162,27 @@ static bool start_shutdown_task(void) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void heartbeat_task(void *pvParameters) {
|
||||||
|
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||||
|
const TickType_t xFrequency = pdMS_TO_TICKS(1000);
|
||||||
|
|
||||||
|
uint32_t seconds = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
vTaskDelayUntil(&xLastWakeTime, xFrequency);
|
||||||
|
|
||||||
|
seconds++;
|
||||||
|
|
||||||
|
nova64_log("[Heartbeat] System running for %lu s | FreeRTOS Tick: %lu\n",
|
||||||
|
(unsigned long)seconds, (unsigned long)xTaskGetTickCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_heartbeat_task(void) {
|
||||||
|
xTaskCreate(heartbeat_task, "heartbeat", 2048, NULL, 1,
|
||||||
|
&heartbeat_task_handle);
|
||||||
|
}
|
||||||
|
|
||||||
static void nova64_boot_task(void *params) {
|
static void nova64_boot_task(void *params) {
|
||||||
(void)params;
|
(void)params;
|
||||||
nova64_log("Boot task started.\n");
|
nova64_log("Boot task started.\n");
|
||||||
@@ -125,17 +193,12 @@ static void nova64_boot_task(void *params) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!load_launcher_from_internal_storage()) {
|
if (!start_init_task()) {
|
||||||
nova64_log("Launcher loading failed.\n");
|
nova64_log("Init startup failed.\n");
|
||||||
vTaskDelete(NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!start_launcher_task()) {
|
|
||||||
nova64_log("Launcher startup failed.\n");
|
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
start_heartbeat_task();
|
||||||
|
|
||||||
nova64_log("Boot process completed.\n");
|
nova64_log("Boot process completed.\n");
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
@@ -153,10 +216,6 @@ NOVA64_API bool nova64_init(const nova64_io_interface_t *io_interface) {
|
|||||||
g_io_interface_storage = *io_interface;
|
g_io_interface_storage = *io_interface;
|
||||||
g_io_interface = &g_io_interface_storage;
|
g_io_interface = &g_io_interface_storage;
|
||||||
|
|
||||||
#if defined(NOVA64_SHUTDOWN_AVAILABLE)
|
|
||||||
shutdown_requested = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nova64_log("System Initializing...\n");
|
nova64_log("System Initializing...\n");
|
||||||
|
|
||||||
event_queue = xQueueCreate(10, sizeof(uint32_t));
|
event_queue = xQueueCreate(10, sizeof(uint32_t));
|
||||||
@@ -206,7 +265,13 @@ NOVA64_API bool nova64_shutdown(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nova64_log("Scheduler shutdown requested from host.\n");
|
nova64_log("Scheduler shutdown requested from host.\n");
|
||||||
|
|
||||||
shutdown_requested = true;
|
shutdown_requested = true;
|
||||||
|
if (shutdown_task_handle != NULL) {
|
||||||
|
xTaskNotifyGive(shutdown_task_handle);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+107
-23
@@ -1,28 +1,75 @@
|
|||||||
#include "wasm_runner.h"
|
#include "wasm_runner.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "nova64_api.h"
|
||||||
#include "nova64_fs.h"
|
#include "nova64_fs.h"
|
||||||
#include "nova64_internal.h"
|
#include "nova64_internal.h"
|
||||||
#include "nova64_api.h"
|
#include "task.h"
|
||||||
#include "wasm_export.h"
|
#include "wasm_export.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
struct wasm_runner_instance {
|
#define MAX_WASM_TASKS 4
|
||||||
void *native_instance;
|
|
||||||
char *module_path;
|
typedef enum { SLOT_FREE = 0, SLOT_RUNNING, SLOT_STOPPING } slot_state_t;
|
||||||
wasm_runner_framebuffer_config_t framebuffer_config;
|
|
||||||
wasm_runner_instance_t *next;
|
typedef struct {
|
||||||
};
|
int id;
|
||||||
|
slot_state_t state;
|
||||||
|
// TaskHandle_t freertos_handle;
|
||||||
|
wasm_module_inst_t module_inst;
|
||||||
|
wasm_exec_env_t exec_env;
|
||||||
|
} wasm_task_slot_t;
|
||||||
|
|
||||||
|
static wasm_task_slot_t g_wasm_slots[MAX_WASM_TASKS];
|
||||||
|
|
||||||
char error_buf[128];
|
char error_buf[128];
|
||||||
uint32_t stack_size = 8092, heap_size = 8092;
|
uint32_t stack_size = 8092, heap_size = 8092;
|
||||||
|
|
||||||
bool wasm_runner_initialize(void) {
|
bool wasm_runner_initialize(void) {
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_WASM_TASKS; i++) {
|
||||||
|
g_wasm_slots[i].id = i;
|
||||||
|
g_wasm_slots[i].state = SLOT_FREE;
|
||||||
|
// g_wasm_slots[i].freertos_handle = NULL;
|
||||||
|
g_wasm_slots[i].module_inst = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
wasm_runtime_init();
|
wasm_runtime_init();
|
||||||
register_nova64_imports();
|
nova64_register_imports();
|
||||||
nova64_log("WASM runtime initialized successfully.\n");
|
nova64_log("WASM runtime initialized successfully.\n");
|
||||||
|
|
||||||
const char *module_file = "SYS:/init.wasm";
|
return true;
|
||||||
int32_t file_size = nova64_get_file_size(module_file);
|
}
|
||||||
|
|
||||||
|
bool wasm_runner_destroy(void) {
|
||||||
|
wasm_runtime_destroy();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wasm_runner_start_program(
|
||||||
|
const char *module_path,
|
||||||
|
const wasm_runner_framebuffer_config_t *framebuffer_config) {
|
||||||
|
|
||||||
|
nova64_log("Running WASM module: %s\n", module_path);
|
||||||
|
|
||||||
|
wasm_task_slot_t *slot = NULL;
|
||||||
|
for (int i = 0; i < MAX_WASM_TASKS; i++) {
|
||||||
|
if (g_wasm_slots[i].state == SLOT_FREE) {
|
||||||
|
slot = &g_wasm_slots[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!slot) {
|
||||||
|
nova64_log("Maximum number of WASM tasks (%d) reached!\n", MAX_WASM_TASKS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wasm_runtime_init_thread_env()) {
|
||||||
|
nova64_log("Failed to initialize WASM runtime thread environment.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t file_size = nova64_get_file_size(module_path);
|
||||||
if (file_size <= 0) {
|
if (file_size <= 0) {
|
||||||
nova64_log("Failed to determine WASM module size.\n");
|
nova64_log("Failed to determine WASM module size.\n");
|
||||||
return false;
|
return false;
|
||||||
@@ -34,7 +81,7 @@ bool wasm_runner_initialize(void) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nova64_read_file_to_buffer(module_file, buffer, (size_t)file_size)) {
|
if (!nova64_read_file_to_buffer(module_path, buffer, (size_t)file_size)) {
|
||||||
nova64_log("Failed to read WASM module into buffer.\n");
|
nova64_log("Failed to read WASM module into buffer.\n");
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return false;
|
return false;
|
||||||
@@ -43,36 +90,73 @@ bool wasm_runner_initialize(void) {
|
|||||||
wasm_module_t module = wasm_runtime_load(buffer, (uint32_t)file_size,
|
wasm_module_t module = wasm_runtime_load(buffer, (uint32_t)file_size,
|
||||||
error_buf, sizeof(error_buf));
|
error_buf, sizeof(error_buf));
|
||||||
|
|
||||||
wasm_module_inst_t module_inst = wasm_runtime_instantiate(
|
slot->module_inst = wasm_runtime_instantiate(module, stack_size, heap_size,
|
||||||
module, stack_size, heap_size, error_buf, sizeof(error_buf));
|
error_buf, sizeof(error_buf));
|
||||||
|
|
||||||
wasm_function_inst_t start_func =
|
wasm_function_inst_t start_func =
|
||||||
wasm_runtime_lookup_function(module_inst, "_start");
|
wasm_runtime_lookup_function(slot->module_inst, "_start");
|
||||||
|
|
||||||
if (start_func == NULL) {
|
if (start_func == NULL) {
|
||||||
nova64_log("Failed to find '_start' function in WASM module: %s\n",
|
nova64_log("Failed to find '_start' function in WASM module: %s\n",
|
||||||
wasm_runtime_get_exception(module_inst));
|
wasm_runtime_get_exception(slot->module_inst));
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_exec_env_t exec_env =
|
slot->exec_env = wasm_runtime_create_exec_env(slot->module_inst, stack_size);
|
||||||
wasm_runtime_create_exec_env(module_inst, stack_size);
|
|
||||||
|
nova64_log("WASM module execution environment created successfully.\n");
|
||||||
|
|
||||||
uint32_t argv[2] = {5, 3}; // Example arguments for the "add" function
|
uint32_t argv[2] = {5, 3}; // Example arguments for the "add" function
|
||||||
|
|
||||||
if (wasm_runtime_call_wasm(exec_env, start_func, 2, argv)) {
|
slot->state = SLOT_RUNNING;
|
||||||
nova64_log("WASM module executed successfully. Sum: %d\n", argv[0]);
|
|
||||||
|
if (wasm_runtime_call_wasm(slot->exec_env, start_func, 0, NULL)) {
|
||||||
|
nova64_log("WASM module executed successfully.\n");
|
||||||
} else {
|
} else {
|
||||||
nova64_log("Failed to execute WASM module: %s\n",
|
nova64_log("Failed to execute WASM module: %s\n",
|
||||||
wasm_runtime_get_exception(module_inst));
|
wasm_runtime_get_exception(slot->module_inst));
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_runtime_destroy_exec_env(exec_env);
|
slot->state = SLOT_STOPPING;
|
||||||
wasm_runtime_deinstantiate(module_inst);
|
|
||||||
|
wasm_runtime_destroy_exec_env(slot->exec_env);
|
||||||
|
wasm_runtime_deinstantiate(slot->module_inst);
|
||||||
wasm_runtime_unload(module);
|
wasm_runtime_unload(module);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
wasm_runtime_destroy();
|
wasm_runtime_destroy_thread_env();
|
||||||
|
|
||||||
|
slot->module_inst = NULL;
|
||||||
|
slot->exec_env = NULL;
|
||||||
|
slot->state = SLOT_FREE;
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wasm_runner_terminate(void) {
|
||||||
|
nova64_log("Stopping all WASM tasks...\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_WASM_TASKS; i++) {
|
||||||
|
if (g_wasm_slots[i].state == SLOT_RUNNING && g_wasm_slots[i].module_inst) {
|
||||||
|
g_wasm_slots[i].state = SLOT_STOPPING;
|
||||||
|
wasm_runtime_terminate(g_wasm_slots[i].module_inst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool any_running = true;
|
||||||
|
while (any_running) {
|
||||||
|
any_running = false;
|
||||||
|
for (int i = 0; i < MAX_WASM_TASKS; i++) {
|
||||||
|
if (g_wasm_slots[i].state != SLOT_FREE) {
|
||||||
|
any_running = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (any_running) {
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nova64_log("All WASM tasks successfully stopped.\n");
|
||||||
|
}
|
||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
|
||||||
using Zio;
|
using Zio;
|
||||||
using Zio.FileSystems;
|
using Zio.FileSystems;
|
||||||
|
|
||||||
@@ -76,6 +73,7 @@ internal static class Program
|
|||||||
private static readonly Nova64Core.LogMessageDelegate LogMessage = (message) =>
|
private static readonly Nova64Core.LogMessageDelegate LogMessage = (message) =>
|
||||||
{
|
{
|
||||||
Console.Write($"[Core] {message}");
|
Console.Write($"[Core] {message}");
|
||||||
|
Console.Out.Flush();
|
||||||
};
|
};
|
||||||
|
|
||||||
private static GCHandle? _ioHandle;
|
private static GCHandle? _ioHandle;
|
||||||
|
|||||||
Binary file not shown.
@@ -1,17 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// Declare a main function, this is the entrypoint into our go module
|
|
||||||
// That will be run. In our example, we won't need this
|
|
||||||
func main() {
|
|
||||||
_ = add(1, 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This exports an add function.
|
|
||||||
// It takes in two 32-bit integer values
|
|
||||||
// And returns a 32-bit integer value.
|
|
||||||
// To make this function callable from JavaScript,
|
|
||||||
// we need to add the: "export add" comment above the function
|
|
||||||
//export add
|
|
||||||
func add(x int, y int) int {
|
|
||||||
return x + y
|
|
||||||
}
|
|
||||||
+3
-2
@@ -1,9 +1,10 @@
|
|||||||
extern "nova64" fn yield(timeout_ms: u32) void;
|
const nova64 = @import("nova64.zig");
|
||||||
|
|
||||||
pub fn main() void {
|
pub fn main() void {
|
||||||
_ = add(1, 2);
|
_ = add(1, 2);
|
||||||
while (true) {
|
while (true) {
|
||||||
yield(16); // Yield for 1 second
|
nova64.log("Hello from Zig!");
|
||||||
|
// nova64.yield(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
pub extern "nova64" fn nova64_yield(timeout_ms: u32) void;
|
||||||
|
pub extern "nova64" fn nova64_log(message: [*]const u8) void;
|
||||||
|
|
||||||
|
pub fn log(message: []const u8) void {
|
||||||
|
nova64_log(message.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn yield(timeout_ms: u32) void {
|
||||||
|
nova64_yield(timeout_ms);
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
extern "nova64" fn log(message: [*]const u8) void;
|
||||||
|
|
||||||
|
pub fn main() void {
|
||||||
|
log(&"Hello from Zig!"[0]);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user