A lightweight Forth-compatible bytecode VM written in C++17.
- Stack-based architecture with 32-bit cells
- Preemptive multitasking system (v0.9.0+)
- Priority-based scheduler with up to 8 concurrent tasks
- Inter-task message passing with 16-message queue
- Task sleep, yield, and critical sections
- Platform-abstracted timer interrupts
- Panic Handler (v0.12.0+)
- Comprehensive error diagnostics with
vm_panic() - Stack trace and register dump
- Custom panic handler support for embedded systems
- Comprehensive error diagnostics with
- Memory-mapped I/O support
- Little-endian byte ordering
- No exceptions, no RTTI
- Zero dependencies (except tests)
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -jV4 can optionally use the V4-hal C++17 CRTP implementation for zero-cost hardware abstraction:
cmake -B build -DCMAKE_BUILD_TYPE=Release -DV4_USE_V4HAL=ON
cmake --build build -jThis provides:
- Zero-cost abstraction via compile-time polymorphism
- Platform support: POSIX, ESP32, CH32V203
- Minimal runtime footprint (~5.7KB for GPIO+Timer)
- Backward compatible with existing
v4_hal_*API
V4 includes a preemptive multitasking system with pluggable task backends:
Custom Backend (default):
- V4's own priority-based + round-robin scheduler
- Suitable for bare-metal and testing
- Minimal dependencies
FreeRTOS Backend:
- Native FreeRTOS task integration
- For ESP32, ESP-IDF, and other FreeRTOS platforms
- Full FreeRTOS scheduler features
Configure backend via CMake:
# Custom backend (default)
cmake -B build -DV4_TASK_BACKEND=CUSTOM
# FreeRTOS backend
cmake -B build -DV4_TASK_BACKEND=FREERTOS -DFREERTOS_PATH=/path/to/freertosFor ESP-IDF, FreeRTOS is provided automatically (no FREERTOS_PATH needed).
- Task scheduler: ~400 bytes
- Per-task overhead: 32 bytes + stack allocation
- Total VM with tasks: ~42KB (Release build with LTO)
#include "v4/task.h"
// Initialize task system (10ms time slice)
vm_task_init(vm, 10);
// Spawn a task
int task_id = vm_task_spawn(vm, word_idx, priority, ds_size, rs_size);
// Task control
vm_task_sleep(vm, 100); // Sleep 100ms
vm_task_yield(vm); // Yield to other tasks
// Inter-task messaging
vm_task_send(vm, target_task, msg_type, data);
vm_task_receive(vm, msg_type, &data, &src_task);TASK_SPAWN,TASK_EXIT,TASK_SLEEP,TASK_YIELDCRITICAL_ENTER,CRITICAL_EXITTASK_SEND,TASK_RECEIVE,TASK_RECEIVE_BLOCKINGTASK_SELF,TASK_COUNT
See v4/task.h for full API documentation.
V4 includes a comprehensive panic handler for debugging errors in production:
- Automatic diagnostics: Collects PC, stack depths, top stack values
- Stack trace: Full return stack dump for call trace analysis
- Custom handlers: Register application-specific panic handlers
- Embedded-friendly: No dynamic allocation, minimal overhead
#include "v4/panic.h"
// Optional: Register custom panic handler
void my_panic_handler(void* user_data, const V4PanicInfo* info) {
// Log to external storage, blink LED, etc.
printf("Custom handler: Error %d at PC=0x%08X\n",
info->error_code, info->pc);
}
vm_set_panic_handler(vm, my_panic_handler, NULL);
// Panic is called automatically on errors
// Or call manually for custom error conditions
vm_panic(vm, V4_ERR_CUSTOM);========== V4 PANIC ==========
Error: StackOverflow (code=-3)
PC: 0x00001234
Data Stack: [256] TOS=42, NOS=100
Return Stack: [3]
Call trace:
[0] 0x00001200
[1] 0x00001180
[2] 0x00001100
==============================
See include/v4/panic.h and tests/test_panic.cpp for details.
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DV4_BUILD_TESTS=ON
cmake --build build -j
cd build && ctest --output-on-failurecmake -B build -DCMAKE_BUILD_TYPE=Debug -DV4_BUILD_TESTS=ON -DV4_USE_V4HAL=ON
cmake --build build -j
cd build && ctest --output-on-failureLicensed under either of:
- MIT License (LICENSE-MIT)
- Apache License, Version 2.0 (LICENSE-APACHE)
at your option.