From 8dba1745691ec80f98167f6add93f6e7a5891af6 Mon Sep 17 00:00:00 2001 From: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> Date: Wed, 12 Nov 2025 16:06:10 +0100 Subject: [PATCH] Extended support for External Memory Initial commit to support larger containers Replace custom functions with zephyr ones Use input container as a name for containers Rename base container Cleanup psram support Fixed container naming Signed-off-by: Krisztian Szilvasi <34309983+kr-t@users.noreply.github.com> --- CMakeLists.txt | 8 ++++- Kconfig | 7 ++++ boards/b_u585i_iot02a.conf | 3 +- boards/b_u585i_iot02a.overlay | 35 +++++++++++++++++-- .../container_supervisor/cs_sm_impl.c | 33 +++++++++-------- src/samples-mini/zephyr/main.c | 8 +++-- src/shared/platform/ocre_psram.h | 31 ++++++++++++++++ 7 files changed, 101 insertions(+), 24 deletions(-) create mode 100644 src/shared/platform/ocre_psram.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 269a731f..38367542 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,9 +57,15 @@ add_custom_target(generate_messages DEPENDS ${MSG_GENERATED_FILE}) if(NOT "${OCRE_INPUT_FILE}" STREQUAL "") message("Using input file: ${OCRE_INPUT_FILE}") + + # Extract filename without extension for use in software + get_filename_component(OCRE_INPUT_FILE_NAME ${OCRE_INPUT_FILE} NAME_WE) + message("Input file name (without extension): ${OCRE_INPUT_FILE_NAME}") + add_definitions(-DOCRE_INPUT_FILE_NAME="${OCRE_INPUT_FILE_NAME}") + add_custom_command( OUTPUT ${CMAKE_CURRENT_LIST_DIR}/src/ocre/ocre_input_file.g - COMMAND xxd -n wasm_binary -i ${OCRE_INPUT_FILE} > ${CMAKE_CURRENT_LIST_DIR}/src/ocre/ocre_input_file.g + COMMAND xxd -i ${OCRE_INPUT_FILE} | sed 's/unsigned char .*\\[/static const unsigned char wasm_binary[/' | sed 's/unsigned int .*_len/static const unsigned int wasm_binary_len/' > ${CMAKE_CURRENT_LIST_DIR}/src/ocre/ocre_input_file.g DEPENDS ${OCRE_INPUT_FILE} COMMENT "Generating C header from ${OCRE_INPUT_FILE}" ) diff --git a/Kconfig b/Kconfig index 722d11f4..bf2d4a01 100644 --- a/Kconfig +++ b/Kconfig @@ -39,6 +39,13 @@ config OCRE_WAMR_HEAP_BUFFER_SIZE help A static memory allocation for WAMR to use as a heap. +config OCRE_STORAGE_HEAP_BUFFER_SIZE + int "Storage heap buffer size in bytes" + default 500000 + depends on MEMC + help + A static memory allocation for container storage to use as a heap. + config OCRE_CONTAINER_DEFAULT_HEAP_SIZE int "Default value for the container heap size" default 4096 diff --git a/boards/b_u585i_iot02a.conf b/boards/b_u585i_iot02a.conf index 92d3ea9e..90d47674 100644 --- a/boards/b_u585i_iot02a.conf +++ b/boards/b_u585i_iot02a.conf @@ -8,7 +8,8 @@ CONFIG_MEMC=y # Container defaults CONFIG_MAX_CONTAINERS=5 -CONFIG_OCRE_WAMR_HEAP_BUFFER_SIZE=8388608 +CONFIG_OCRE_WAMR_HEAP_BUFFER_SIZE=6388608 +CONFIG_OCRE_STORAGE_HEAP_BUFFER_SIZE=2000000 # Bus interfaces CONFIG_GPIO=y diff --git a/boards/b_u585i_iot02a.overlay b/boards/b_u585i_iot02a.overlay index c838f7ba..1419cd47 100644 --- a/boards/b_u585i_iot02a.overlay +++ b/boards/b_u585i_iot02a.overlay @@ -1,6 +1,10 @@ #include / { + chosen { + zephyr,code-partition = &slot0_partition; + }; + aliases { rng0 = &rng_device; led0 = &green_led_1; @@ -82,12 +86,37 @@ }; }; -/* Optional: flash partitions */ +/* Flash partitions - 2MB total, no MCUboot */ &flash0 { + /delete-node/ partitions; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Application partition - 1900KB */ + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x00000000 DT_SIZE_K(2000)>; + }; + /* Dummy slot1 partition for MCUboot compatibility (unused) */ + slot1_partition: partition@1F5000 { + label = "image-1"; + reg = <0x001F5000 DT_SIZE_K(44)>; + }; + }; +}; + +// 64MB external flash +&mx25lm51245 { partitions { - user_data_partition: partition@100000 { + /delete-node/ partition; + + /* Use the whole flash for the filesystem. */ + user_data_partition: storage_partition: partition@0 { label = "user_data"; - reg = <0x00100000 DT_SIZE_K(256)>; + reg = <0x00000000 DT_SIZE_M(64)>; }; }; }; diff --git a/src/ocre/components/container_supervisor/cs_sm_impl.c b/src/ocre/components/container_supervisor/cs_sm_impl.c index c86a4fdc..04ba07ae 100644 --- a/src/ocre/components/container_supervisor/cs_sm_impl.c +++ b/src/ocre/components/container_supervisor/cs_sm_impl.c @@ -34,18 +34,15 @@ LOG_MODULE_DECLARE(ocre_cs_component, OCRE_LOG_LEVEL); #include "cs_sm.h" #include "cs_sm_impl.h" -// External RAM support for WAMR heap on boards that have it +#include "ocre_psram.h" + +// WAMR heap buffer - uses PSRAM when available #if defined(CONFIG_MEMC) - #if defined(CONFIG_BOARD_ARDUINO_PORTENTA_H7) - __attribute__((section("SDRAM1"), aligned(32))) - #elif defined(CONFIG_BOARD_B_U585I_IOT02A) - __attribute__((section(".stm32_psram"), aligned(32))) - #elif defined(CONFIG_BOARD_MIMXRT1064_EVK) - __attribute__((section("SDRAM"), aligned(32))) - #endif // defined () -#endif // defined(CONFIG_MEMC) + PSRAM_SECTION_ATTR +#endif static char wamr_heap_buf[CONFIG_OCRE_WAMR_HEAP_BUFFER_SIZE] = {0}; + // Thread pool for container execution #define CONTAINER_THREAD_POOL_SIZE 4 static core_thread_t container_threads[CONTAINER_THREAD_POOL_SIZE]; @@ -178,6 +175,7 @@ static int load_binary_to_buffer_fs(ocre_runtime_arguments_t *container_argument size_t file_size = 0; void *file_handle = NULL; char filepath[FILE_PATH_MAX]; + ret = core_construct_filepath(filepath, sizeof(filepath), container_data->sha256); if (ret < 0) { @@ -191,9 +189,9 @@ static int load_binary_to_buffer_fs(ocre_runtime_arguments_t *container_argument } container_arguments->size = file_size; - container_arguments->buffer = malloc(file_size); + container_arguments->buffer = storage_heap_alloc(file_size); if (!container_arguments->buffer) { - LOG_ERR("Failed to allocate memory for container binary."); + LOG_ERR("Failed to allocate memory for container binary from PSRAM."); return -ENOMEM; } @@ -202,7 +200,7 @@ static int load_binary_to_buffer_fs(ocre_runtime_arguments_t *container_argument ret = core_fileopen(filepath, &file_handle); if (ret < 0) { LOG_ERR("Failed to open file %s: %d", filepath, ret); - free(container_arguments->buffer); + storage_heap_free(container_arguments->buffer); return ret; } @@ -210,14 +208,14 @@ static int load_binary_to_buffer_fs(ocre_runtime_arguments_t *container_argument if (ret < 0) { LOG_ERR("Failed to read file %s: %d", filepath, ret); core_fileclose(file_handle); - free(container_arguments->buffer); + storage_heap_free(container_arguments->buffer); return ret; } ret = core_fileclose(file_handle); if (ret < 0) { LOG_ERR("Failed to close file %s: %d", filepath, ret); - free(container_arguments->buffer); + storage_heap_free(container_arguments->buffer); return ret; } return 0; @@ -268,6 +266,7 @@ ocre_container_runtime_status_t CS_runtime_init(ocre_cs_ctx *ctx, ocre_container #ifdef CONFIG_OCRE_CONTAINER_MESSAGING ocre_messaging_init(); #endif + storage_heap_init(); return RUNTIME_STATUS_INITIALIZED; } @@ -322,7 +321,7 @@ ocre_container_status_t CS_create_container(ocre_container_t *container) { curr_container_arguments->error_buf, sizeof(curr_container_arguments->error_buf)); if (!curr_container_arguments->module) { LOG_ERR("Failed to load WASM module: %s", curr_container_arguments->error_buf); - free(curr_container_arguments->buffer); + storage_heap_free(curr_container_arguments->buffer); return CONTAINER_STATUS_ERROR; } @@ -381,7 +380,7 @@ ocre_container_status_t CS_run_container(ocre_container_t *container) { LOG_ERR("Failed to instantiate WASM module: %s, for containerID= %d", curr_container_arguments->error_buf, curr_container_ID); wasm_runtime_unload(curr_container_arguments->module); - free(curr_container_arguments->buffer); + storage_heap_free(curr_container_arguments->buffer); return CONTAINER_STATUS_ERROR; } #if defined(CONFIG_OCRE_TIMER) || defined(CONFIG_OCRE_GPIO) || defined(CONFIG_OCRE_SENSORS) || \ @@ -514,7 +513,7 @@ ocre_container_status_t CS_destroy_container(ocre_container_t *container, ocre_c } if (container->ocre_runtime_arguments.buffer) { - free(container->ocre_runtime_arguments.buffer); + storage_heap_free(container->ocre_runtime_arguments.buffer); container->ocre_runtime_arguments.buffer = NULL; } diff --git a/src/samples-mini/zephyr/main.c b/src/samples-mini/zephyr/main.c index 024cf0a4..049bb203 100644 --- a/src/samples-mini/zephyr/main.c +++ b/src/samples-mini/zephyr/main.c @@ -26,7 +26,11 @@ int ocre_network_init(); int main(int argc, char *argv[]) { ocre_cs_ctx ctx; ocre_container_init_arguments_t args; - char *container_filename = "hello"; +#ifdef OCRE_INPUT_FILE_NAME + const char *container_filename = OCRE_INPUT_FILE_NAME; +#else + const char *container_filename = "hello-from-ocre"; +#endif #ifdef CONFIG_OCRE_NETWORKING int net_status = ocre_network_init(); @@ -52,7 +56,7 @@ int main(int argc, char *argv[]) { int container_ID; ocre_container_data.heap_size = 0; - snprintf(ocre_container_data.name, sizeof(ocre_container_data.name), "Hello World"); + snprintf(ocre_container_data.name, sizeof(ocre_container_data.name), "%s", container_filename); snprintf(ocre_container_data.sha256, sizeof(ocre_container_data.sha256), "%s", container_filename); ocre_container_data.timers = 0; ocre_container_runtime_create_container(&ctx, &ocre_container_data, &container_ID, NULL); diff --git a/src/shared/platform/ocre_psram.h b/src/shared/platform/ocre_psram.h new file mode 100644 index 00000000..1072b49b --- /dev/null +++ b/src/shared/platform/ocre_psram.h @@ -0,0 +1,31 @@ +#ifndef OCRE_PSRAM +#define OCRE_PSRAM + +// PSRAM configuration - centralized for different platforms +#if defined(CONFIG_MEMC) + // Board-specific PSRAM section attributes + #if defined(CONFIG_BOARD_ARDUINO_PORTENTA_H7) + #define PSRAM_SECTION_ATTR __attribute__((section("SDRAM1"), aligned(32))) + #elif defined(CONFIG_BOARD_B_U585I_IOT02A) + #define PSRAM_SECTION_ATTR __attribute__((section(".stm32_psram"), aligned(32))) + #elif defined(CONFIG_BOARD_MIMXRT1064_EVK) + #define PSRAM_SECTION_ATTR __attribute__((section("SDRAM"), aligned(32))) + #else + #define PSRAM_SECTION_ATTR __attribute__((aligned(32))) + #endif + + PSRAM_SECTION_ATTR + static char storage_heap_buf[CONFIG_OCRE_STORAGE_HEAP_BUFFER_SIZE] = {0}; + + static struct k_heap storage_heap; + #define storage_heap_init() k_heap_init(&storage_heap, storage_heap_buf, CONFIG_OCRE_STORAGE_HEAP_BUFFER_SIZE) + #define storage_heap_alloc(size) k_heap_alloc(&storage_heap, (size), K_SECONDS(1)) + #define storage_heap_free(buffer) k_heap_free(&storage_heap, (void*)buffer) +#else + // No PSRAM - use system malloc + #define storage_heap_init() /* No initialization needed */ + #define storage_heap_alloc(size) malloc(size) + #define storage_heap_free(buffer) free(buffer) +#endif + +#endif /* OCRE_PSRAM*/