A high-performance, modular embedded operating system kernel for the ESP32, delivering Linux-style command-line power within a microcontroller's constraints.
⚡ Esp32OS — A lightweight open-source operating system for ESP32
→ Build multitasking IoT apps faster
→ Simple APIs, modular kernel
→ Designed for hobbyists & embedded devs
ESP32OS layers a clean OS architecture on top of FreeRTOS and ESP-IDF, giving you:
- A full interactive shell (UART + Telnet over WiFi) with command history, ANSI colours, and line editing
- Process management — create, list, kill, suspend, resume tasks like Linux processes
- SPIFFS file system —
ls,cd,cat,write,rm,mkdir,df - Networking — WiFi scan/connect, ping, HTTP GET, auto-reconnect
- Hardware control — GPIO, ADC, I2C scan, SPI via CLI commands
- Feature modules — PWM, IPC (message queues/events/shared memory), MQTT, OTA
- Multi-level logging — ring buffer + SPIFFS log file with rotation
- Watchdog integration and graceful crash recovery
- Extensible command/module API — register new commands in 5 lines
ESP32OS is designed to bring a practical subset of Linux-like operational experience to low-cost microcontrollers.
The core idea is not to replace Linux, but to provide a familiar operational model for embedded products where Linux is too heavy in terms of boot time, RAM, flash footprint, and power budget.
- Many embedded teams need shell-driven diagnostics and remote support, but cannot afford a full Linux stack.
- Traditional firmware projects often hide system internals; ESP32OS exposes runtime state (
ps,top,free,dmesg) in a clean, operator-friendly way. - A command-driven service architecture makes field debugging and production validation faster.
- Provide a stable command shell over UART and Telnet for development and field maintenance.
- Offer a modular service layer (
os_kernel,os_fs,os_networking,os_logging,os_drivers) with clean boundaries. - Keep APIs simple so contributors can add drivers and commands quickly.
- Preserve deterministic embedded behavior using FreeRTOS scheduling and ESP-IDF device support.
- Device bring-up labs where engineers need direct runtime visibility.
- Education and training for RTOS + embedded networking concepts.
- Product prototypes that need CLI-managed networking, logging, and peripheral control.
- Factory and support tooling where scripted command execution is valuable.
- Small memory budget and limited CPU compared with Linux-class systems.
- Real-time responsiveness must be preserved while still offering shell convenience.
- Hardware integration tests still require real boards even when CI is automated.
┌─────────────────────────────────────────────────────────────────┐
│ Applications / User Code │
├─────────────────────────────────────────────────────────────────┤
│ Shell (CLI) │
│ UART Session │ Telnet Session │
├────────────────────────────────┼────────────────────────────────┤
│ System Services │
│ ┌──────────┐ ┌──────────┐ ┌─────────────┐ ┌────────────────┐ │
│ │ os_kernel│ │ os_fs │ │os_networking│ │ os_logging │ │
│ │ (process │ │ (SPIFFS) │ │ (WiFi/TCP) │ │ (ring+file) │ │
│ │ mgmt) │ │ │ │ │ │ │ │
│ └──────────┘ └──────────┘ └─────────────┘ └────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ Hardware Abstraction Layer (HAL) │
│ os_drivers: GPIO │ ADC │ I2C │ SPI │ UART │
├─────────────────────────────────────────────────────────────────┤
│ ESP-IDF Peripheral APIs │
├─────────────────────────────────────────────────────────────────┤
│ FreeRTOS Kernel (task scheduler) │
├─────────────────────────────────────────────────────────────────┤
│ ESP32 Hardware │
└─────────────────────────────────────────────────────────────────┘
If you want a shorter operational guide, see docs/USER_GUIDE.md.
. $IDF_PATH/export.sh
idf.py set-target esp32s3
idf.py build
idf.py -p /dev/ttyUSB0 flash
python3 -m pip install pyserial
python3 tools/test_integration.py --port /dev/ttyUSB0If all tests pass, you have a working baseline.
| Tool | Version |
|---|---|
| ESP-IDF | ≥ 5.0 |
| Python | ≥ 3.8 |
| CMake | ≥ 3.16 |
| Ninja | any recent |
git clone https://github.com/faizannazir/Esp32OS.git
cd Esp32OS
# Source ESP-IDF environment
. $IDF_PATH/export.shidf.py set-target esp32 # or esp32s3, esp32c3
idf.py menuconfig # optional — review sdkconfigidf.py buildRun the hardware integration script from the project root after flashing:
python3 -m pip install pyserial
python3 tools/test_integration.py --port /dev/ttyUSB0Expected result: all checks pass (count may change as the script evolves).
idf.py -p /dev/ttyUSB0 flash monitorDefault baud rate: 115200
Open any serial terminal (minicom, PuTTY, idf.py monitor):
_____ ____ ____ ____ ____ ___ ____
| ____|/ ___|| _ \|___ \|___ \/ _ \/ ___|
| _| \___ \| |_) | __) | __) | | | \___ \
| |___ ___) | __/ / __/ / __/| |_| |___) |
|_____|____/|_| |_____|_____|\___|____/
ESP32 Embedded OS v1.0.0
Type 'help' for commands
esp32os>
# First connect to WiFi from the serial shell:
esp32os> wifi connect MySSID MyPassword
# Then from your computer:
telnet <esp32-ip> 2222
# Default credentials:
Username: admin
Password: esp32osUse the terminal for build, flash, and local shell work. In VS Code, the same flow can be driven from the integrated terminal and the serial monitor.
$ idf.py set-target esp32s3
$ idf.py build
$ idf.py -p /dev/cu.usbserial-0001 flash monitor
ESP32OS Embedded OS v1.0.0
Type 'help' for commands
esp32os> uname -a
esp32os ESP32-S3 WiFi IDF-v6.0 2 core(s) Flash:4MB
esp32os> free
total used free
Heap: 334684 116600 218084
The UI path is straightforward:
- Use the VS Code terminal for
idf.py buildandidf.py flash - Use
idf.py monitoror a serial terminal for shell interaction - Use the GitHub Actions UI to review PR Checks and Master Release runs
| Command | Description | Example |
|---|---|---|
help |
List all commands | help |
uname -a |
System info | uname -a |
uptime |
System uptime + process count | uptime |
free |
Heap memory usage | free |
reboot |
Restart system | reboot |
echo |
Print text | echo hello world |
sleep |
Wait N seconds | sleep 5 |
clear |
Clear screen | clear |
| Command | Description | Example |
|---|---|---|
ps |
List all processes | ps |
top |
Live heap + process view | top |
kill <pid> |
Terminate process | kill 4 |
suspend <pid> |
Pause process | suspend 3 |
resume <pid> |
Resume process | resume 3 |
| Command | Description | Example |
|---|---|---|
ls [path] |
List directory | ls /logs |
pwd |
Print working directory | pwd |
cd <path> |
Change directory | cd /logs |
cat <file> |
Print file | cat /etc/config.txt |
write <file> <text> |
Write file | write /tmp/note.txt hello |
append <file> <text> |
Append to file | append /tmp/log.txt line2 |
rm <file> |
Remove file | rm /tmp/note.txt |
mkdir <dir> |
Create directory | mkdir /tmp/test |
mv <src> <dst> |
Move/rename | mv /tmp/a.txt /tmp/b.txt |
df |
Filesystem usage | df |
| Command | Description | Example |
|---|---|---|
wifi scan |
Scan for APs | wifi scan |
wifi connect |
Connect to AP | wifi connect SSID pass |
wifi disconnect |
Disconnect | wifi disconnect |
wifi status |
Show IP, RSSI, MAC | wifi status |
ifconfig |
Network interface info | ifconfig |
ping <host> |
ICMP ping | ping 8.8.8.8 |
http <url> |
HTTP GET | http http://example.com |
| Command | Description | Example |
|---|---|---|
gpio read <pin> |
Read GPIO level | gpio read 4 |
gpio write <pin> <val> |
Set GPIO output | gpio write 2 1 |
gpio mode <pin> <mode> |
Set pin mode | gpio mode 4 in_pullup |
gpio info |
Show all GPIO state | gpio info |
adc read <ch> |
Read raw ADC | adc read 0 |
adc readv <ch> |
Read ADC millivolts | adc readv 0 |
adc readall |
Read all channels | adc readall |
i2c scan |
Scan I2C bus | i2c scan 21 22 |
i2c read <addr> <reg> <len> |
I2C read | i2c read 0x48 0x00 2 |
i2c write <addr> <reg> <bytes> |
I2C write | i2c write 0x48 0x01 0xFF |
| Command | Description | Example |
|---|---|---|
dmesg [n] |
Show log ring buffer | dmesg 20 |
loglevel [level] |
Get/set log level | loglevel debug |
logfile <on|off> |
Enable SPIFFS logging | logfile on |
| Command | Description | Example |
|---|---|---|
nvs get <key> |
Read NVS value | nvs get hostname |
nvs set <key> <val> |
Write NVS value | nvs set hostname esp32 |
nvs del <key> |
Delete NVS key | nvs del hostname |
nvs erase |
Erase all NVS | nvs erase |
| Command | Description | Example |
|---|---|---|
pwm init <channel> <pin> <freq_hz> |
Initialize PWM channel | pwm init 0 2 5000 |
pwm duty <channel> <percent> |
Set PWM duty in percent | pwm duty 0 25 |
pwm freq <channel> <freq_hz> |
Change PWM frequency | pwm freq 0 1000 |
pwm deinit <channel> |
Deinitialize PWM channel | pwm deinit 0 |
msgq create <name> <size> <count> |
Create IPC message queue | msgq create q1 16 8 |
msgq send <name> <data> |
Send text payload to queue | msgq send q1 hello |
msgq recv <name> [timeout_ms] |
Receive queue payload | msgq recv q1 1000 |
event create <name> |
Create event group | event create ev1 |
event set <name> <bits> |
Set event bits | event set ev1 0x03 |
event wait <name> <bits> [timeout_ms] |
Wait for event bits | event wait ev1 0x01 5000 |
mqtt config <broker_url> |
Set MQTT broker URL | mqtt config mqtt://broker.hivemq.com |
mqtt connect |
Connect MQTT client | mqtt connect |
mqtt pub <topic> <message> [-q QoS] |
Publish text payload | mqtt pub dev/status online -q 1 |
mqtt pubhex <topic> <hex> [-q QoS] |
Publish binary payload from hex | mqtt pubhex dev/raw DEADBEEF -q 0 |
mqtt sub <topic> [-q QoS] |
Subscribe to topic | mqtt sub dev/status -q 1 |
ota update <url> |
Start OTA firmware update | ota update https://example.com/fw.bin |
ota status |
Show OTA state and progress | ota status |
ota confirm |
Confirm updated firmware | ota confirm |
ota rollback |
Roll back to previous firmware | ota rollback |
| Command | Description | Example |
|---|---|---|
test mqtt |
Run MQTT component tests | test mqtt |
test ipc |
Run IPC component tests | test ipc |
test ota |
Run OTA component tests | test ota |
test pwm |
Run PWM component tests | test pwm |
test all |
Run all feature test suites | test all |
esp32os/
├── CMakeLists.txt # Root CMake
├── partitions.csv # Custom flash partition table
├── sdkconfig.defaults # Default SDK config
│
├── main/
│ ├── CMakeLists.txt
│ └── main.c # Boot sequence (app_main)
│
└── components/
├── os_logging/ # Multi-level logging subsystem
│ ├── include/os_logging.h
│ └── src/os_logging.c
│
├── os_kernel/ # Process/task management
│ ├── include/os_kernel.h
│ └── src/os_kernel.c
│
├── os_fs/ # SPIFFS file system abstraction
│ ├── include/os_fs.h
│ └── src/os_fs.c
│
├── os_hal/ # HAL umbrella header
│ └── include/os_hal.h
│
├── os_drivers/ # GPIO, ADC, I2C, SPI, UART drivers
│ ├── include/os_drivers.h
│ └── src/os_drivers.c
│
├── os_networking/ # WiFi manager, ping, HTTP client
│ ├── include/os_networking.h
│ └── src/os_networking.c
│
└── os_shell/ # Shell engine + all built-in commands
├── include/os_shell.h
└── src/
├── os_shell.c # Shell engine (readline, telnet, history)
└── shell_commands.c # All built-in command handlers
The project now includes two GitHub Actions workflows:
-
master-release.yml:- Trigger: push to
master - Builds:
esp32,esp32s3 - Creates auto tag and GitHub Release
- Uploads release artifacts (
.bin,.elf,.map,.json,.zip,sdkconfig)
- Trigger: push to
-
pr-checks.yml:- Trigger: pull requests targeting
master - Builds:
esp32,esp32s3 - Runs test-harness sanity checks
- Uploads build artifacts for reviewer validation
- Trigger: pull requests targeting
See docs/TESTING.md and docs/CONTRIBUTING.md for contribution workflow details.
ESP32OS is open source under the MIT license.
What this means:
- You can use, modify, and distribute this code in personal and commercial projects.
- You must retain copyright and license notices from this repository.
Attribution and brand rules:
- Credit must be preserved in source distributions and derivative works.
- You may not market a fork or derivative as the official ESP32OS project.
- Use of the
ESP32OSproject name, logo, or branding for product marketing requires prior written permission from project maintainers.
For details, read:
// In your component source file:
#include "os_shell.h"
static int cmd_hello(int fd, int argc, char **argv) {
shell_printf(fd, "Hello from custom command! args=%d\r\n", argc - 1);
return SHELL_CMD_OK;
}
static const shell_command_t my_cmd =
SHELL_CMD_ENTRY("hello", "Say hello", "hello [name]", cmd_hello);
void my_module_init(void) {
shell_register_command(&my_cmd);
}Then call my_module_init() from app_main after shell_init().
| Component | Flash | RAM |
|---|---|---|
| FreeRTOS kernel | ~40 KB | ~8 KB |
| ESP-IDF WiFi | ~300 KB | ~70 KB |
| ESP32OS shell | ~18 KB | ~4 KB |
| os_kernel | ~6 KB | ~2 KB |
| os_fs + SPIFFS | ~20 KB | ~3 KB |
| os_logging | ~4 KB | ~16 KB (ring buf) |
| os_drivers (HAL) | ~8 KB | ~1 KB |
| Total ESP32OS | ~56 KB | ~26 KB |
ESP32 has 520 KB SRAM and 4 MB flash — ESP32OS uses well under 10% RAM headroom.
Edit sdkconfig.defaults or run idf.py menuconfig:
| Key | Default | Description |
|---|---|---|
FREERTOS_HZ |
1000 | Tick rate (1 ms resolution) |
ESP_MAIN_TASK_STACK_SIZE |
8192 | app_main stack |
ESP_TASK_WDT_TIMEOUT_S |
30 | Watchdog timeout |
ESP_CONSOLE_UART_BAUDRATE |
115200 | Serial baud |
Telnet credentials are set at compile time in os_shell.c:
#define TELNET_USERNAME "admin"
#define TELNET_PASSWORD "esp32os"WiFi auto-connect is stored in NVS via os_wifi_save_credentials().
The roadmap below highlights high-impact improvements planned for ESP32OS.
- Command auto-completion (tab completion for commands and file paths)
- Persistent shell history across reboots (NVS-backed)
- Command aliases and simple shell variables
- Lightweight scripting mode (
script run <file>) for batch command execution
- Per-task CPU usage tracking integrated into
top - Better process supervision with automatic restart policies
- Priority and affinity controls exposed through shell commands
- Improved stack watermark diagnostics and runtime task health checks
- MQTT client commands (
mqtt connect,pub,sub) - HTTPS enhancements with certificate pinning support
- mDNS/Bonjour service advertisement for zero-config discovery
- Optional WebSocket-based remote shell gateway
- Stronger directory compatibility layer for SPIFFS/LittleFS parity
- Optional LittleFS backend for improved directory semantics
- File integrity utilities (
sha256,fsck-lite, log verification) - Structured config files under
/etcwith validation helpers
- PWM and servo command set
- Expanded sensor driver templates (I2C, SPI, UART)
- Better ADC calibration workflows and per-channel profiles
- Power management helpers (sleep modes, wake source diagnostics)
- Log export commands (serial dump, HTTP upload, compressed archive)
- Metrics endpoint for runtime counters and health snapshots
- Event tracing for major subsystem state transitions
- Optional panic report summarizer from coredump metadata
- Role-based shell access policies (operator/admin)
- Configurable credential storage hardening for Telnet/WiFi
- Optional secure remote shell transport strategy
- Safer defaults for production (
releaseprofile configs)
- Hardware-in-the-loop CI on self-hosted runners
- Automated regression suites for shell command behavior
- Performance benchmark reporting in CI artifacts
- Versioned changelog generation tied to release tags
If you want to contribute one of these items, see docs/CONTRIBUTING.md and open an issue describing scope and acceptance criteria.
MIT License — see LICENSE.
| File | Description |
|---|---|
| docs/ARCHITECTURE.md | Detailed architecture & design decisions |
| docs/COMPONENTS.md | Per-component API reference |
| docs/TESTING.md | Test strategy and test procedures |
| docs/CONTRIBUTING.md | Contribution guide |
| docs/EXTENDING.md | How to add commands, drivers, services |
| NOTICE.md | Attribution notice for reuse and distribution |
| BRANDING_POLICY.md | Rules for project name and branding usage |
ESP32OS is built on top of excellent open-source ecosystems. Thanks to the maintainers and contributors of:
-
Espressif Systems
- ESP-IDF: https://github.com/espressif/esp-idf
- GitHub profile: https://github.com/espressif
-
FreeRTOS
- Kernel repository: https://github.com/FreeRTOS/FreeRTOS-Kernel
- GitHub profile: https://github.com/FreeRTOS
-
LwIP TCP/IP stack
- Repository: https://github.com/lwip-tcpip/lwip
- GitHub profile: https://github.com/lwip-tcpip
-
Python Serial ecosystem (used by integration tooling)
- pyserial: https://github.com/pyserial/pyserial
- GitHub profile: https://github.com/pyserial
ESP32OS is an independent project and is not officially affiliated with Espressif, FreeRTOS, or LwIP maintainers.