This project provides a GPIO Sysfs simulator implemented in C++ using the libfuse library. It creates a user-space filesystem that emulates the Linux GPIO sysfs interface, allowing you to simulate GPIO pin operations on a desktop or development machine. This is especially useful for development, testing, and experimentation when you do not have access to actual embedded hardware.
-
Filesystem Operations: Implements the key filesystem operations required for GPIO sysfs simulation:
getattr: Retrieve file and directory attributes.readdir: List the contents of directories.read: Read data from files.write: Write data to files.poll: Notify the kernel when files are modified, enabling event-driven monitoring.
-
Asynchronous Monitoring: Changes to
valueanddirectionare signalled asPOLLPRI | POLLERR, exactly like the real sysfs interface, so clients written for actual hardware work unmodified.POLLIN-based clients usingpollorepollare supported as well. -
Dynamic Pin Management: Writing a pin number to
/exportcreates new entries in the simulated filesystem, mimicking the behavior of the Linux kernel. Writing a pin number to/unexportremoves those entries. -
Sysfs Error Semantics: Invalid operations fail with the same errors as the real interface: exporting an exported pin returns
EBUSY, unexporting an unknown pin or writing malformed input returnsEINVAL, and writing the value of an input pin returnsEPERM.
- C++23 compiler (GCC 14 or newer)
- CMake
- Meson and Ninja (required for building libfuse)
- pkg-config
- fuse3 (provides the setuid
fusermount3helper needed to mount as an unprivileged user)
Install the dependencies (example for Debian-based systems):
sudo apt install ninja-build meson pkg-config fuse3cmake -B build -S . -DCMAKE_INSTALL_PREFIX=$(pwd)/build/INSTALLDIR
cmake --build build --parallelexport LD_LIBRARY_PATH=$(pwd)/build/INSTALLDIR/lib
$(pwd)/build/INSTALLDIR/bin/gpio-sysfs-simulator <mount-point>This command mounts the simulated GPIO sysfs filesystem at <mount-point>. You can then use standard sysfs operations to export/unexport pins and manipulate their state.
The simulator logs pin operations via spdlog. Run it in the foreground with -f to see the output, and set the SPDLOG_LEVEL environment variable to adjust verbosity:
SPDLOG_LEVEL=debug $(pwd)/build/INSTALLDIR/bin/gpio-sysfs-simulator -f <mount-point>Asynchronous Monitoring:
Use the provided client.py script to monitor pin changes. It polls for POLLPRI | POLLERR and re-reads the polled descriptor, the same pattern used with the real /sys/class/gpio interface, so it works against actual hardware too:
python3 examples/client.py --pins 1 2 3 4 -m <mount-point>