Implement file system API and add shutdown functionality for desktop builds

This commit is contained in:
Lukas Höppner
2026-08-09 22:38:43 +02:00
parent 1654d366b2
commit 8e99fca404
13 changed files with 318 additions and 25 deletions
+17 -2
View File
@@ -1,13 +1,12 @@
#include "nova64_core.h"
#include "nova64_internal.h"
#include "FreeRTOS.h"
#include "nova64_internal.h"
#include "queue.h"
#include "task.h"
#include "wasm_runner.h"
#include <stdarg.h>
#include <stdio.h>
#if defined(ESP_PLATFORM)
#include "esp_pm.h"
#include "esp_rom_sys.h"
@@ -26,8 +25,11 @@ static const nova64_io_interface_t *g_io_interface = NULL;
static QueueHandle_t event_queue = NULL;
static TaskHandle_t boot_task_handle = NULL;
static TaskHandle_t launcher_task_handle = NULL;
#if defined(NOVA64_SHUTDOWN_AVAILABLE)
static TaskHandle_t shutdown_task_handle = NULL;
static volatile bool shutdown_requested = false;
#endif
static const char *const kInternalLauncherPath = "SYS:/launcher.wasm";
@@ -83,6 +85,7 @@ static bool start_launcher_task(void) {
return true;
}
#if defined(NOVA64_SHUTDOWN_AVAILABLE)
static void nova64_shutdown_task(void *params) {
(void)params;
@@ -110,6 +113,7 @@ static bool start_shutdown_task(void) {
nova64_log("Shutdown task created successfully.\n");
return true;
}
#endif
static void nova64_boot_task(void *params) {
(void)params;
@@ -137,6 +141,10 @@ static void nova64_boot_task(void *params) {
vTaskDelete(NULL);
}
const nova64_io_interface_t *nova64_get_io_interface(void) {
return g_io_interface;
}
NOVA64_API bool nova64_init(const nova64_io_interface_t *io_interface) {
if (is_initialized || io_interface == NULL) {
return false;
@@ -144,7 +152,10 @@ NOVA64_API bool nova64_init(const nova64_io_interface_t *io_interface) {
g_io_interface_storage = *io_interface;
g_io_interface = &g_io_interface_storage;
#if defined(NOVA64_SHUTDOWN_AVAILABLE)
shutdown_requested = false;
#endif
nova64_log("System Initializing...\n");
@@ -154,9 +165,11 @@ NOVA64_API bool nova64_init(const nova64_io_interface_t *io_interface) {
return false;
}
#if defined(NOVA64_SHUTDOWN_AVAILABLE)
if (!start_shutdown_task()) {
return false;
}
#endif
nova64_log("Starting boot process...\n");
BaseType_t created =
@@ -186,6 +199,7 @@ NOVA64_API int32_t nova64_main() {
return 1;
}
#if defined(NOVA64_SHUTDOWN_AVAILABLE)
NOVA64_API bool nova64_shutdown(void) {
if (!is_initialized) {
return false;
@@ -195,6 +209,7 @@ NOVA64_API bool nova64_shutdown(void) {
shutdown_requested = true;
return true;
}
#endif
NOVA64_API uint32_t nova64_get_version(void) {
return 0x010000; // v1.0.0
+98
View File
@@ -0,0 +1,98 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "nova64_fs.h"
#include "nova64_core.h"
#include "nova64_internal.h"
/* Helper for parsing the drive prefix from a path like "SYS:/file" or "EXA:/file".
* Returns the drive index on success, or -1 on failure. */
static int parse_drive_index(const char *path)
{
if (!path || path[0] == '\0') {
return -1;
}
if (strncmp(path, "SYS:/", 5) == 0) {
return 0;
}
if (strncmp(path, "EX", 2) == 0 && path[3] == ':' && path[4] == '/') {
char drive_letter = path[2];
if (drive_letter >= 'A' && drive_letter <= 'Z') {
return drive_letter - ('A' - 1);
}
}
return -1;
}
bool nova64_read_file_to_buffer(const char *file_path,
uint8_t *buffer,
size_t buffer_size)
{
if (!file_path || !buffer || buffer_size == 0) {
return false;
}
int drive_index = parse_drive_index(file_path);
if (drive_index < 0) {
return false;
}
const char *relative_path = file_path + 5;
if (*relative_path == '\0') {
return false;
}
const nova64_io_interface_t *io = nova64_get_io_interface();
if (!io || !io->sd_read_file || !io->sd_get_file_size) {
return false;
}
/* Get the file size first */
int32_t file_size = io->sd_get_file_size(drive_index, relative_path);
if (file_size < 0) {
return false;
}
/* Determine how much to read */
size_t bytes_to_read = (size_t)file_size;
if (bytes_to_read > buffer_size) {
bytes_to_read = buffer_size;
}
/* Read the entire file into the buffer */
int32_t bytes_read = io->sd_read_file(drive_index, relative_path, buffer, bytes_to_read);
if (bytes_read < 0) {
return false;
}
return bytes_read > 0;
}
int32_t nova64_get_file_size(const char *file_path)
{
if (!file_path) {
return -1;
}
int drive_index = parse_drive_index(file_path);
if (drive_index < 0) {
return -1;
}
const char *relative_path = file_path + 5;
if (*relative_path == '\0') {
return -1;
}
const nova64_io_interface_t *io = nova64_get_io_interface();
if (!io || !io->sd_get_file_size) {
return -1;
}
return io->sd_get_file_size(drive_index, relative_path);
}
+34
View File
@@ -1,6 +1,8 @@
#include "wasm_runner.h"
#include "nova64_fs.h"
#include "nova64_internal.h"
#include "wasm_export.h"
#include <stdlib.h>
struct wasm_runner_instance {
void *native_instance;
@@ -9,8 +11,40 @@ struct wasm_runner_instance {
wasm_runner_instance_t *next;
};
char error_buf[128];
uint32_t stack_size = 8092, heap_size = 8092;
bool wasm_runner_initialize(void) {
wasm_runtime_init();
nova64_log("WASM runtime initialized successfully.\n");
const char *module_file = "SYS:/init.wasm";
int32_t file_size = nova64_get_file_size(module_file);
if (file_size <= 0) {
nova64_log("Failed to determine WASM module size.\n");
return false;
}
unsigned char *buffer = malloc((size_t)file_size);
if (!buffer) {
nova64_log("Failed to allocate WASM module buffer.\n");
return false;
}
if (!nova64_read_file_to_buffer(module_file, buffer, (size_t)file_size)) {
nova64_log("Failed to read WASM module into buffer.\n");
free(buffer);
return false;
}
wasm_module_t module = wasm_runtime_load(buffer, (uint32_t)file_size,
error_buf, sizeof(error_buf));
wasm_module_inst_t module_inst = wasm_runtime_instantiate(
module, stack_size, heap_size, error_buf, sizeof(error_buf));
wasm_exec_env_t exec_env = wasm_runtime_create_exec_env(module_inst, stack_size);
return true;
}