Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)

# ======================================================================
Expand Down Expand Up @@ -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")
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ 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
```

**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:**
Expand Down
12 changes: 12 additions & 0 deletions linker/common.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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__);
Expand Down
74 changes: 68 additions & 6 deletions scripts/romfs.cmake
Original file line number Diff line number Diff line change
@@ -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
# 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()
32 changes: 32 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,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)
{
Expand Down Expand Up @@ -266,6 +269,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];
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)
{
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)
Expand Down