DMVFS is a Virtual File System (VFS) layer for DMOD-based embedded systems. It provides a unified interface for managing multiple file systems simultaneously, allowing applications to work with different file system implementations through a single, consistent API.
DMVFS acts as a virtual file system layer that sits on top of various file system implementations (such as FatFS, RamFS, FlashFS, etc.). It allows multiple file systems to be mounted at different mount points in a unified directory tree, similar to how traditional operating systems handle multiple partitions and storage devices.
The key advantage of DMVFS is that it leverages the DMOD (Dynamic Modules) system to dynamically load file system implementations at runtime, providing flexibility and modularity for embedded applications.
- Multi-Mount Point Support: Mount multiple file systems at different locations in a unified directory tree
- Dynamic Module Loading: Load file system implementations dynamically at runtime using DMOD
- POSIX-like API: Familiar file operations (open, read, write, seek, etc.)
- Process-Based File Management: Track open files per process ID
- Thread-Safe Operations: Built-in mutex protection for concurrent access
- Path Resolution: Automatic conversion between relative and absolute paths
- Comprehensive File Operations: Support for files, directories, and metadata operations
- Modular Architecture: Clean separation between VFS layer and file system implementations
DMVFS is built on top of two key DMOD components:
The foundation that provides:
- Dynamic loading and unloading of modules at runtime
- Inter-module communication through a common API
- Resource management and dependency handling
- Module lifecycle management
A standardized interface specification that:
- Defines a comprehensive set of file system operations
- Provides POSIX-like semantics for file and directory operations
- Enables different file system implementations to work interchangeably
- Ensures compatibility between VFS and underlying file systems
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Application Layer β
β (Uses DMVFS API for file operations) β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β DMVFS (This Project) β
β β’ Path resolution & mount point management β
β β’ File descriptor management β
β β’ Process-based file tracking β
β β’ Thread-safe operations β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β DMFSI (File System Interface) β
β β’ Standardized FS operation signatures β
β β’ POSIX-like API definition β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β File System Implementations β
β (FatFS, RamFS, FlashFS, etc. - loaded via DMOD)β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Storage Hardware β
β (SD Card, Flash Memory, RAM, etc.) β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
- Compiler: GCC or compatible C compiler
- Build System: CMake 3.10 or higher
- Dependencies:
- DMOD library (automatically fetched via CMake)
- DMFSI interface (automatically fetched via CMake)
- Dynamic Memory: Your system must support dynamic memory allocation
DMVFS uses CMake with FetchContent to automatically download and build dependencies:
# Create build directory
mkdir build
cd build
# Configure the project
cmake -DCMAKE_BUILD_TYPE=Release ..
# Build the library
cmake --build .The build process will:
- Fetch and build the DMOD library from GitHub
- Fetch and build the DMFSI interface from GitHub
- Build the DMVFS static library (
libdmvfs.a) - Build the test suite
After building, you'll find:
build/libdmvfs.a- The DMVFS static librarybuild/tests/fs_tester- Test executable for file system validation
Here's a simple example of using DMVFS in your application:
#include "dmvfs.h"
#include "dmod.h"
int main(void) {
// Initialize DMVFS with 16 mount points and 32 max open files
if (!dmvfs_init(16, 32)) {
printf("Failed to initialize DMVFS\n");
return -1;
}
// Mount a file system at /mnt
// "fatfs" is the name of a DMOD module implementing DMFSI
if (!dmvfs_mount_fs("fatfs", "/mnt", "device=/dev/sda1")) {
printf("Failed to mount file system\n");
dmvfs_deinit();
return -1;
}
// Open a file for writing
void* fp = NULL;
if (dmvfs_fopen(&fp, "/mnt/test.txt", DMFSI_O_CREAT | DMFSI_O_WRONLY, 0, 0) == 0) {
const char* data = "Hello, DMVFS!";
size_t written = 0;
dmvfs_fwrite(fp, data, strlen(data), &written);
dmvfs_fclose(fp);
}
// Read the file back
if (dmvfs_fopen(&fp, "/mnt/test.txt", DMFSI_O_RDONLY, 0, 0) == 0) {
char buffer[256] = {0};
size_t read_bytes = 0;
dmvfs_fread(fp, buffer, sizeof(buffer), &read_bytes);
printf("Read: %s\n", buffer);
dmvfs_fclose(fp);
}
// Unmount and cleanup
dmvfs_unmount_fs("/mnt");
dmvfs_deinit();
return 0;
}dmvfs_init(max_mount_points, max_open_files)- Initialize the VFSdmvfs_deinit()- Clean up and deinitialize
dmvfs_mount_fs(fs_name, mount_point, config)- Mount a file systemdmvfs_unmount_fs(mount_point)- Unmount a file system
dmvfs_fopen(fp, path, mode, attr, pid)- Open a filedmvfs_fclose(fp)- Close a filedmvfs_fread(fp, buffer, size, read_bytes)- Read from a filedmvfs_fwrite(fp, buffer, size, written_bytes)- Write to a filedmvfs_lseek(fp, offset, whence)- Seek to a positiondmvfs_ftell(fp)- Get current positiondmvfs_feof(fp)- Check for end-of-filedmvfs_fflush(fp)- Flush file buffers
dmvfs_mkdir(path, mode)- Create a directorydmvfs_rmdir(path)- Remove a directorydmvfs_opendir(dp, path)- Open a directorydmvfs_readdir(dp, entry)- Read directory entrydmvfs_closedir(dp)- Close a directorydmvfs_chdir(path)- Change current directorydmvfs_getcwd(buffer, size)- Get current working directory
dmvfs_stat(path, stat)- Get file/directory informationdmvfs_rename(oldpath, newpath)- Rename a filedmvfs_unlink(path)- Delete a filedmvfs_chmod(path, mode)- Change file permissionsdmvfs_utime(path, atime, mtime)- Update file timestamps
For complete API documentation, see inc/dmvfs.h.
DMVFS includes a comprehensive test suite that validates file system implementations.
# Build the project (if not already done)
cd build
cmake --build .
# Build the test file system module
cd ../tests/testfs/build
cmake .. -DDMOD_MODE=DMOD_MODULE -DDMOD_DIR=../../../build/_deps/dmod-src
cmake --build .
# Run the test suite
cd ../../../build
./tests/fs_tester ../tests/testfs/build/dmf/testfs.dmfThe test suite supports different modes:
Tests all file system operations including creation, modification, and deletion:
./tests/fs_tester path/to/filesystem.dmfTests only read operations on existing files and directories:
./tests/fs_tester --read-only-fs \
--test-file /mnt/existing_file.txt \
--test-dir /mnt/existing_directory \
path/to/filesystem.dmfAdd DMVFS as a subdirectory or use FetchContent:
include(FetchContent)
FetchContent_Declare(
dmvfs
GIT_REPOSITORY https://github.com/choco-technologies/dmvfs.git
GIT_TAG master
)
FetchContent_MakeAvailable(dmvfs)
# Link to your target
target_link_libraries(your_target PRIVATE dmvfs)- Include the
inc/directory in your include path - Link against
libdmvfs.a - Ensure DMOD and DMFSI are also linked
dmvfs/
βββ inc/ # Public header files
β βββ dmvfs.h # Main DMVFS API
βββ src/ # Source files
β βββ dmvfs.c # DMVFS implementation
βββ tests/ # Test suite
β βββ main.c # Test runner
β βββ testfs/ # Example test file system
βββ CMakeLists.txt # Build configuration
βββ LICENSE # MIT License
βββ README.md # This file
Contributions are welcome! Please feel free to submit issues, fork the repository, and create pull requests.
This project is licensed under the MIT License - see the LICENSE file for details.
- Patryk Kubiak
- Choco-Technologies Team
For questions, issues, or feature requests, please open an issue on GitHub.