This repository is the dedicated simulator project for ElenixOS on desktop platforms. It is pre-configured for VSCode and supports Windows, Linux, and macOS. FreeRTOS is also included and can be optionally enabled to better simulate embedded system behavior.
Clone the simulator project and related submodules:
git clone --recursive https://github.com/ElenixOS/ElenixOS-SimulatorYou can download SDL from https://www.libsdl.org/
For Ubuntu, run:
sudo apt-get update && sudo apt-get install -y build-essential libsdl2-dev cmakeFor Arch Linux, run:
sudo pacman -Syu && sudo pacman -S sdl2 libsdl2-devel sdl2_mixer sdl2-devel base-devel gcc makeThe usage guide has been moved to the ElenixOS documentation site.
Please read the Simulator overview.
The current Watchface Metric and complex-widget API is documented in docs/watchface_widget_api.md.
Before the first official ElenixOS release, this repository periodically updates its LVGL submodule from the LVGL upstream master branch.
After the official release, the project will follow a stable LVGL release as its integration baseline.
Updating LVGL requires regenerating its API metadata with the Simulator's lv_conf.h, then running the unified SNI generator. The metadata is written under build/ and is not a hand-maintained type inventory.
To refresh the pre-release integration, update the lvgl submodule to the intended master revision, then regenerate the API description and SNI bindings:
python3 lvgl/scripts/gen_json/gen_json.py \
--lvgl-config lv_conf.h \
--output-path build/lvgl-api
python3 ElenixOS/scripts/sni/generate_sni.py generate \
--lvgl-json build/lvgl-api/lvgl.jsonThe SNI generator reads lvgl.json and ElenixOS/scripts/sni/config/sni_lvgl_bindings.json, validates the complete binding model, then writes sni_type_ids.h, sni_lv_types.c, and sni_api_lv.c. Its analyze, validate, generate, update-config, and dump-ir commands use the same resolver and reporter.
This repository includes the workflow .github/workflows/deploy-wasm-pages.yml.
It builds the WASM target and publishes the output to GitHub Pages automatically on pushes to main.
After enabling Pages in repository settings (Build and deployment -> Source: GitHub Actions), artifacts are published to:
Important: make sure the repository Pages source is set to GitHub Actions, not Deploy from a branch. The branch-based Pages path runs the Jekyll build pipeline and can hide the WASM output.
https://<owner>.github.io/<repo>/wasm/latest/main.htmlhttps://<owner>.github.io/<repo>/wasm/latest/main.jshttps://<owner>.github.io/<repo>/wasm/latest/main.wasmhttps://<owner>.github.io/<repo>/wasm/latest/main.data
The workflow also keeps a commit-pinned copy under:
https://<owner>.github.io/<repo>/wasm/<sha7>/...
Use latest for always-updated preview links, and use <sha7> for stable references in external pages.
If your page is hosted under the same GitHub Pages site, you can link directly:
<a href="/ElenixOS-Simulator/wasm/latest/main.html" target="_blank" rel="noopener">Open ElenixOS Simulator</a>You can also embed it in an iframe:
<iframe
src="/ElenixOS-Simulator/wasm/latest/main.html"
width="100%"
height="720"
style="border:0"
loading="lazy"
referrerpolicy="no-referrer"
></iframe>If your page is hosted elsewhere, use this full absolute URL: https://<owner>.github.io/<repo>/wasm/latest/main.html.
pip install kconfiglib # one-time dependency
cmake -B build
cmake --build buildThe Native Simulator also accepts --headless and does not create an SDL window.
LVGL rendering, timers, animation, application logic, and the normal touch injection path continue to run.
The headless display starts a loopback WebSocket server for the VS Code Webview and keeps the existing local IPC endpoint as a compatibility/control channel:
./bin/main --headless --ipc-socket /tmp/elenixos-simulator.sockThe atomic *.ready marker contains the tokenized WebSocket URL.
On macOS/Linux the compatibility endpoint is a Unix-domain socket; on Windows it is loopback TCP.
The VS Code extension consumes the marker, opens the Webview automatically when a marked Native debug session starts, and removes the endpoint/marker when the session, Webview, or extension stops.
The tracked simulator.code-workspace contains separate Native configurations for SDL windows and headless Webview sessions.
Choose a configuration whose name ends in (SDL window) for a native window, or (headless Webview) for the Toolkit Webview.
The Webview converts raw little-endian RGB565 WebSocket frames in a WebGL texture (with Canvas 2D fallback) and sends Pointer Events back as logical 390x450 coordinates.
The Simulator injects them through the existing eos_touch_bind_indev / eos_touch_inject_* backend.
Dirty rectangles and compressed image frames are intentionally not part of the first version.
cmake -B build-wasm -D EOS_PLATFORM=WASM
cmake --build build-wasm# Install dependency (one-time)
pip install kconfiglib
# Edit per-build overrides (saves to build/.config, NOT committed)
make menuconfig
# Edit project defaults (saves to main/src/config/defaults.conf, COMMITTED)
make menuconfig-defaults
# Reconfigure after changes
cmake -B build && cmake --build buildEach build directory has its own .config (e.g. build/.config, build-wasm/.config), allowing Native and WASM to use completely different kernel settings.
The generated header is written to build/generated/eos_config_gen.h and is automatically included during compilation.
The simulator-level Kconfig composes the ElenixOS kernel configuration with platform-specific options from main/src/config/Kconfig.
Platform port behavior is therefore configured by the consuming simulator project, not by the ElenixOS core.
For example, to prevent the macOS simulator from changing the host system volume, open make menuconfig, go to Platform Ports, and disable Enable macOS system volume control.
The setting is stored in the build-specific build/.config file.
# FreeType support
wget https://kumisystems.dl.sourceforge.net/project/freetype/freetype2/2.13.2/freetype-2.13.2.tar.xz
tar -xf freetype-2.13.2.tar.xz
cd freetype-2.13.2
make
make install# FFmpeg support
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
cd ffmpeg
git checkout release/6.0
./configure --disable-all --disable-autodetect --disable-podpages --disable-asm --enable-avcodec --enable-avformat --enable-decoders --enable-encoders --enable-demuxers --enable-parsers --enable-protocol='file' --enable-swscale --enable-zlib
make
sudo make installWorks with any OS like pthred, Windows, FreeRTOS, etc. It has build in support for FreeRTOS.
This project is configured for VSCode and is tested on:
- Ubuntu Linux
- Windows WSL (Ubuntu Linux)
It requires a working version of GCC, GDB and make in your path.
To allow debugging inside VSCode you will also require a GDB extension or other suitable debugger. All the requirements, build and debug settings have been pre-configured in the .workspace file.
On Linux, macOS, and Windows, use Debug ElenixOS with CodeLLDB (headless Webview) when you want the Simulator Webview and ESH input/output in VSCode. It requires the recommended vadimcn.vscode-lldb extension. Choose Debug ElenixOS with CodeLLDB (SDL window) when you want the normal native window. The existing cppdbg configurations remain available as compatibility options. Do not run codelldb-launch manually; it only works while the CodeLLDB adapter started by VSCode is listening.
ESH requires a real interactive stdin/stdout terminal. The headless Native path keeps ESH active alongside the framebuffer WebSocket; on Windows it supports both CodeLLDB pipe input and a native console without blocking the LVGL loop. The cppdbg/MI-based configurations in this workspace are intended for non-interactive debugging: on macOS, lldb-mi cannot reliably provide an integrated interactive terminal, while an external console may create a separate Terminal.app window; the VSCode Debug Console does not provide stdin for the debuggee. Therefore, use CodeLLDB when you need to type ESH commands. If the program only needs breakpoints, stepping, variables, or log output, you may use the existing GDB or LLDB configurations without CodeLLDB.
The project can use SDL but it can be easily relaced by any other built-in LVGL dirvers.