From e267d5c7f2d00ff92f1a031d7c632731ab4a57d9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Dec 2025 12:37:15 +0000 Subject: [PATCH 1/3] Initial plan From f499bdf7fcfc5d4ab264b863e24f7c1c22a9edb5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Dec 2025 12:43:12 +0000 Subject: [PATCH 2/3] Add config directory mounting with dmffs Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- CMakeLists.txt | 12 ++++++++ README.md | 2 ++ linker/common.ld | 12 ++++++++ scripts/romfs.cmake | 74 +++++++++++++++++++++++++++++++++++++++++---- src/main.c | 33 ++++++++++++++++++++ 5 files changed, 127 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6b7a35..ba6740a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ cmake_minimum_required(VERSION 3.10) set(TARGET "STM32F746xG" CACHE STRING "Target microcontroller") set(STARTUP_DMP_FILE "" CACHE FILEPATH "Optional startup.dmp file to embed in ROM") set(USER_DATA_FILE "" CACHE FILEPATH "Optional user_data file to embed in ROM") +set(DMBOOT_CONFIG_DIR "" CACHE PATH "Optional config directory to mount as /configs/ using dmffs") option(DMBOOT_EMULATION "Enable Renode emulation mode" OFF) # ====================================================================== @@ -74,6 +75,17 @@ else() message(STATUS "No user data file provided (USER_DATA_FILE not set or file doesn't exist)") endif() +# Include romfs.cmake to handle config filesystem embedding +include(scripts/romfs.cmake) +if(CONFIG_FS_OBJECT) + list(APPEND EMBEDDED_OBJECTS "${CONFIG_FS_OBJECT}") + # Add dependency on the filesystem generation + add_custom_command( + OUTPUT "${CONFIG_FS_OBJECT}" + DEPENDS generate_config_fs + ) +endif() + # Embed modules.dmp if it exists after build # Note: modules.dmp is created during build, not configuration, so we check for it at build time set(MODULES_DMP_FILE "${CMAKE_BINARY_DIR}/modules.dmp") diff --git a/README.md b/README.md index 805e96a..7eb5ed6 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ cmake -DCMAKE_BUILD_TYPE=Debug \ -DTARGET=STM32F746xG \ -DSTARTUP_DMP_FILE=path/to/startup.dmp \ -DUSER_DATA_FILE=path/to/user_data.dat \ + -DDMBOOT_CONFIG_DIR=path/to/config_directory \ -S . -B build cmake --build build ``` @@ -44,6 +45,7 @@ cmake --build build **Build Parameters:** - `STARTUP_DMP_FILE` (optional) - Path to a startup package file (`.dmp`) that will be automatically loaded using `Dmod_AddPackageBuffer` at boot - `USER_DATA_FILE` (optional) - Path to a user data file that will be embedded in ROM, with its address and size available via environment variables `USER_DATA_ADDR` and `USER_DATA_SIZE` +- `DMBOOT_CONFIG_DIR` (optional) - Path to a directory that will be converted to a dmffs filesystem image and mounted at `/configs/` at boot time - `DMBOOT_EMULATION` (optional) - Enable Renode simulation mode instead of hardware mode **Automatic Build-Time Embedding:** diff --git a/linker/common.ld b/linker/common.ld index 3fdfea8..05da257 100644 --- a/linker/common.ld +++ b/linker/common.ld @@ -113,6 +113,18 @@ SECTIONS PROVIDE(__modules_dmp_size = __modules_dmp_end - __modules_dmp_start); } > rom AT > rom + . = ALIGN(16); + .embedded.config_fs : + { + __config_fs_start = .; + PROVIDE(__config_fs_start = .); + KEEP(*(.embedded.config_fs)) + __config_fs_end = .; + PROVIDE(__config_fs_end = .); + __config_fs_size = __config_fs_end - __config_fs_start; + PROVIDE(__config_fs_size = __config_fs_end - __config_fs_start); + } > rom AT > rom + . = ALIGN(4); __exidx_start__ = .; PROVIDE(__exidx_start__ = __exidx_start__); diff --git a/scripts/romfs.cmake b/scripts/romfs.cmake index 0acf197..9011b85 100644 --- a/scripts/romfs.cmake +++ b/scripts/romfs.cmake @@ -1,9 +1,71 @@ # This script sets up a ROM filesystem using dmffs and integrates it into the build # It checks for the required tools, creates the ROMFS image, and embeds it into the firmware -# Check if DMBOOT_ROMFS_DIR is set and exists -if(DMBOOT_ROMFS_DIR AND EXISTS "${DMBOOT_ROMFS_DIR}") - message(STATUS "ROMFS directory specified: ${DMBOOT_ROMFS_DIR}") - # Locate make_dmffs executable if not provided - if(NOT DMBOOT_MAKE_DMFFS_MODULE) - # Search the make_dmffs.dmf \ No newline at end of file +# Check if DMBOOT_CONFIG_DIR is set and exists +if(DMBOOT_CONFIG_DIR AND EXISTS "${DMBOOT_CONFIG_DIR}") + message(STATUS "Config directory specified: ${DMBOOT_CONFIG_DIR}") + + # Set output path for the config filesystem image + set(CONFIG_FS_IMAGE "${CMAKE_BINARY_DIR}/config_fs.dmffs") + + # Find make_dmffs tool + # First check if DMOD_DMF_DIR environment variable is set + if(DEFINED ENV{DMOD_DMF_DIR}) + set(MAKE_DMFFS_MODULE "$ENV{DMOD_DMF_DIR}/make_dmffs.dmf") + if(EXISTS "${MAKE_DMFFS_MODULE}") + message(STATUS "Found make_dmffs.dmf at: ${MAKE_DMFFS_MODULE}") + else() + message(WARNING "DMOD_DMF_DIR is set but make_dmffs.dmf not found at: ${MAKE_DMFFS_MODULE}") + set(MAKE_DMFFS_MODULE "") + endif() + endif() + + # If not found, try to use make_dmffs directly from PATH + if(NOT MAKE_DMFFS_MODULE) + find_program(DMOD_LOADER dmod_loader) + if(DMOD_LOADER) + message(STATUS "Found dmod_loader, will attempt to use make_dmffs module") + set(MAKE_DMFFS_COMMAND "${DMOD_LOADER}" "make_dmffs.dmf" "--args") + else() + message(FATAL_ERROR "Could not find make_dmffs tool. Please install it or set DMOD_DMF_DIR environment variable") + endif() + else() + find_program(DMOD_LOADER dmod_loader) + if(DMOD_LOADER) + set(MAKE_DMFFS_COMMAND "${DMOD_LOADER}" "${MAKE_DMFFS_MODULE}" "--args") + else() + message(FATAL_ERROR "Could not find dmod_loader executable") + endif() + endif() + + # Create custom command to generate the config filesystem image + add_custom_command( + OUTPUT "${CONFIG_FS_IMAGE}" + COMMAND ${MAKE_DMFFS_COMMAND} -d "${DMBOOT_CONFIG_DIR}" -o "${CONFIG_FS_IMAGE}" + DEPENDS "${DMBOOT_CONFIG_DIR}" + COMMENT "Creating config filesystem image from ${DMBOOT_CONFIG_DIR}" + VERBATIM + ) + + # Create a custom target to ensure the filesystem image is generated + add_custom_target(generate_config_fs + DEPENDS "${CONFIG_FS_IMAGE}" + ) + + # Embed the config filesystem image + embed_binary_file( + INPUT_FILE "${CONFIG_FS_IMAGE}" + SECTION_NAME ".embedded.config_fs" + SYMBOL_PREFIX "__config_fs" + ) + + set(CONFIG_FS_OBJECT "${CMAKE_BINARY_DIR}/__config_fs.o") + + # Export variables to parent scope + set(CONFIG_FS_OBJECT "${CONFIG_FS_OBJECT}" PARENT_SCOPE) + set(CONFIG_FS_IMAGE "${CONFIG_FS_IMAGE}" PARENT_SCOPE) + + message(STATUS "Config filesystem will be embedded from: ${DMBOOT_CONFIG_DIR}") +else() + message(STATUS "No config directory specified (DMBOOT_CONFIG_DIR not set or doesn't exist)") +endif() \ No newline at end of file diff --git a/src/main.c b/src/main.c index e331ef1..828ead9 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #define DMOD_ENABLE_REGISTRATION #include +#include #include "dmod.h" #include "dmlog.h" #include "dmheap.h" @@ -22,6 +23,9 @@ extern void* __user_data_size; extern void* __modules_dmp_start; extern void* __modules_dmp_end; extern void* __modules_dmp_size; +extern void* __config_fs_start; +extern void* __config_fs_end; +extern void* __config_fs_size; void delay(int cycles) { @@ -266,6 +270,35 @@ static void setup_embedded_user_data(dmenv_ctx_t dmenv_ctx) static void mount_embedded_filesystems(void) { dmvfs_mount_fs("dmramfs", "/", NULL); + + // Mount config filesystem if embedded + void* config_fs_start = &__config_fs_start; + void* config_fs_end = &__config_fs_end; + size_t config_fs_size = (size_t)((uintptr_t)config_fs_end - (uintptr_t)config_fs_start); + + if(config_fs_size > 0) + { + DMOD_LOG_INFO("Config filesystem found in ROM: addr=0x%X, size=%u bytes\n", + (uintptr_t)config_fs_start, (unsigned int)config_fs_size); + + // Mount the dmffs filesystem at /configs/ + char mount_opts[128]; + snprintf(mount_opts, sizeof(mount_opts), "addr=0x%X,size=%u", + (uintptr_t)config_fs_start, (unsigned int)config_fs_size); + + if(dmvfs_mount_fs("dmffs", "/configs", mount_opts) == 0) + { + DMOD_LOG_INFO("Config filesystem mounted at /configs/\n"); + } + else + { + DMOD_LOG_ERROR("Failed to mount config filesystem at /configs/\n"); + } + } + else + { + DMOD_LOG_INFO("No config filesystem embedded in ROM\n"); + } } int main(int argc, char** argv) From 9716f7d63d305f1fb8754f6252a644e01e72885d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 29 Dec 2025 14:17:35 +0000 Subject: [PATCH 3/3] Replace snprintf with Dmod_SnPrintf and remove stdio.h Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- src/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 828ead9..513c2be 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,5 @@ #define DMOD_ENABLE_REGISTRATION #include -#include #include "dmod.h" #include "dmlog.h" #include "dmheap.h" @@ -283,7 +282,7 @@ static void mount_embedded_filesystems(void) // Mount the dmffs filesystem at /configs/ char mount_opts[128]; - snprintf(mount_opts, sizeof(mount_opts), "addr=0x%X,size=%u", + Dmod_SnPrintf(mount_opts, sizeof(mount_opts), "addr=0x%X,size=%u", (uintptr_t)config_fs_start, (unsigned int)config_fs_size); if(dmvfs_mount_fs("dmffs", "/configs", mount_opts) == 0)