| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Small Bits. Solid Systems.
ZeroKernel is the embedded execution runtime built by ZeroBits for microcontrollers that need deterministic scheduling, bounded memory, and fault-aware orchestration without the weight of a full RTOS.
Official URL: https://kernel.zerobits.tech
ZeroKernel is designed for firmware that has outgrown ad-hoc loop() code but does not need a preemptive RTOS.
The intended position is simple:
The repository now ships with project-level release and validation scaffolding:
Start points:
Latest measured references:
These are regression references, not marketing numbers. The most important gate is still deterministic timing.
Measured on Wemos D1 mini using the blocking baseline and the current ZeroKernel compare sketch:
| Metric | Before (blocking) | After (ZeroKernel) |
|---|---|---|
| RAM usage | 28300 / 80192 | 29044 / 80192 |
| Fast avg lag | 2512 us | 0 us |
| Fast max lag | 11054 us | 0 us |
| Fast misses | 126 | 0 |
Tradeoff summary:
That overhead buys bounded scheduling, watchdog supervision, panic flow, capability-aware task gating, and fixed-capacity queues. On ESP8266-class hardware the measured free heap remains comfortably high, so the extra runtime footprint is a small and controlled tradeoff rather than a practical memory risk.
Measured on ESP32 using the blocking baseline and the current ZeroKernel compare sketch:
| Metric | Before (blocking) | After (ZeroKernel) |
|---|---|---|
| RAM usage | 22116 / 327680 | 22820 / 327680 |
| Fast avg lag | 2022 us | 0 us |
| Fast max lag | 8156 us | 0 us |
| Fast misses | 124 | 0 |
Tradeoff summary:
The ESP32 tradeoff is also healthy: the footprint increase is small relative to total headroom, while the scheduling result is materially better under the same workload.
The optional network helpers are currently marked BETA:
They are already useful and validated on desktop plus ESP32 hardware, but they are still under active tuning for footprint, retry behavior, and cross-board transport quirks. The core runtime is the stable layer; the network helpers should be treated as add-on modules that are ready for evaluation and controlled deployments.
Current target maturity:
Recommended board-specific path:
Current best module tradeoff reference (ESP32, LEAN_NET, manual pattern vs module pattern):
In other words: the modules do cost memory, but the current tuned path keeps that cost bounded and pays it back with better transport throughput and less queue buildup under the same synthetic workload window.
The current network helper stack is now strong enough on ESP32 to treat as a practical deployment target, not just a lab demo, as long as you still validate it against your own endpoint, payload size, and retry policy.
Current accepted live compare reference on ESP32:
The important part is the shape of the tradeoff: timing improves materially, MQTT delivery becomes clean, and HTTP stays alive under the same live window. That is why the ESP32 path is now documented as stable enough, even though the global module label remains BETA until the ESP8266 path is cleaned up too.
To avoid overfitting the runtime to a single project, ZeroKernel now also ships with three reusable compare workloads:
Current ESP32 references from the compare runners:
These workloads are intentionally broader than the micro-benchmarks: they show the runtime under sensor, transport, and control-loop pressure without depending on a single application codebase.
Measured on a real ESP8266 direct-AP seismic node using:
The original firmware was a single blocking loop. The ZeroKernel rewrite split the workload into sampling, heartbeat, flush, buzzer, temperature, and status tasks.
| Metric | Before (direct loop) | After (ZeroKernel, tuned) |
|---|---|---|
| Sample runs (5s window) | 476 | 501 |
| Fast avg lag | 5393 us | 6 us |
| Fast max lag | 21733 us | 2378 us |
| Fast misses | 406 | 1 |
| Successful local sends | 5 | 7 |
Tradeoff summary:
Real sample window from the direct AP seismic project:
BASELINE_SEISMIC window_ms=5009 sample_runs=476 fast_avg_lag_us=5393 fast_max_lag_us=21733 fast_miss=406 queue_max=1 sent_ok=5 sent_fail=0 captures=5 clients=1
ZEROKERNEL_SEISMIC window_ms=5000 sample_runs=501 fast_avg_lag_us=6 fast_max_lag_us=2378 fast_miss=1 queue_max=3 sent_ok=7 sent_fail=0 captures=7 clients=1
Representative baseline vs ZeroKernel shape from the seismic firmware:
Baseline-style direct loop:
void loop() {
const unsigned long nowUs = micros();
trackSampleTiming(nowUs);
++sampleRuns;
float ax = 0.0f;
float ay = 0.0f;
float az = 1.0f;
readAccel(ax, ay, az);
updateMotionModel(ax, ay, az);
if (shouldSend && canCapture) {
capturePacket(true);
} else if (heartbeatDue() && hasDirectClient()) {
capturePacket(false);
}
if (txCount > 0) {
flushQueueOnce();
}
delay(LOOP_DELAY_MS);
}ZeroKernel rewrite:
void sampleSensorTask() {
trackSampleTiming(micros());
++sampleRuns;
float ax = 0.0f;
float ay = 0.0f;
float az = 1.0f;
readAccel(ax, ay, az);
updateMotionModel(ax, ay, az);
if (shouldSend && canCapture) {
capturePacket(true);
}
}
void setup() {
ZeroKernel.begin(zerokernel::adapters::arduinoMillisClock);
ZeroKernel.addTask("Sample", sampleSensorTask, LOOP_DELAY_MS, 4);
ZeroKernel.addTask("Flush", queueFlushTask, 120, 3);
ZeroKernel.addTask("Heartbeat", heartbeatTask, 25, 2);
ZeroKernel.addTask(buzzerTaskConfig);
ZeroKernel.addTask(tempTask);
ZeroKernel.addTask(statusTask);
ZeroKernel.setTaskPriority("Sample", zerokernel::Kernel::kPriorityCritical);
ZeroKernel.setTaskPriority("Flush", zerokernel::Kernel::kPriorityLow);
}
void loop() {
ZeroKernel.tick();
}That rewrite is the practical difference: the same node behavior is split into bounded, phase-aligned tasks instead of one blocking loop that mixes sensing, transport, alarms, and status work together.
The richer ESP32 telemetry workload is also now phase-aligned after the runtime scheduling fix:
This matters because the fix is global to periodic task scheduling. It is not a demo-only patch; it improves sensor, telemetry, heartbeat, and transport polling loops across supported targets.
Add the local library path in platformio.ini:
[env:your_board]
platform = espressif8266
board = d1_mini
framework = arduino
lib_deps =
symlink:///absolute/path/to/ZeroKernelOr vendor the repository inside your project and point lib_extra_dirs to it.
#include <ZeroKernel.h>ZeroKernel.begin(millis);For desktop or custom targets, pass your own clock source:
unsigned long boardClock() {
return millis();
}
ZeroKernel.begin(boardClock);void sampleSensors() {
// Non-blocking work only.
}
void flushTelemetry() {
// Keep this short and cooperative.
}
ZeroKernel.addTask("Sensors", sampleSensors, 100, 5);
ZeroKernel.addTask("Telemetry", flushTelemetry, 500, 10);void loop() {
ZeroKernel.tick();
}String route:
ZeroKernel.publishDeferred("telemetry.temperature", 42);Lean key route:
const zerokernel::Kernel::TopicKey temperatureKey =
zerokernel::Kernel::makeTopicKey("telemetry.temperature");
ZeroKernel.publishDeferredFast(temperatureKey, 42);zerokernel::Kernel::WatchdogPolicy policy = {250, 2, true};
ZeroKernel.setWatchdogPolicy(policy);
ZeroKernel.setTaskHeartbeatTimeout("Sensors", 300);
ZeroKernel.heartbeatTask("Sensors");const zerokernel::Kernel::KernelStats stats = ZeroKernel.getStats();
const zerokernel::Kernel::TimingReport timing = ZeroKernel.getTimingReport();
if (ZeroKernel.isSafeMode()) {
ZeroKernel.exitSafeMode();
}If diagnostics are enabled:
ZeroKernel.dumpStats(printLine);
ZeroKernel.dumpTasks(printLine);
ZeroKernel.dumpTrace(printLine);zerokernel::Kernel::TaskConfig wifiTask = {
"WiFiNode",
pollWifi,
100,
0,
0,
zerokernel::Kernel::kPriorityHigh,
true,
{},
zerokernel::Kernel::kCapNetwork | zerokernel::Kernel::kCapTelemetry};
ZeroKernel.addTask(wifiTask);
ZeroKernel.disableCapabilities(zerokernel::Kernel::kCapNetwork);
// WiFiNode will stay registered but will not be scheduled until the capability is re-enabled.#include <ZeroKernel.h>
void readSensor() {
// Non-blocking work only.
}
void setup() {
ZeroKernel.begin(millis);
ZeroKernel.addTask("SensorReader", readSensor, 500, 10);
}
void loop() {
ZeroKernel.tick();
}Recommended realistic network workload:
examples/RealProjectNode: a portable node-style workload that simulates sensor sampling, WiFi link maintenance, HTTP delivery, MQTT delivery, queue pressure, and realistic intermittent transport failures. Latest ESP32 hardware reference: REAL_PROJECT_NODE window_ms=10010 sample_runs=100 fast_avg_lag_us=0 fast_max_lag_us=0 fast_miss=0 link_up=1 wifi_attempts=2 reconnects=1 http_ok=33 http_fail=5 http_rate=86 mqtt_ok=32 mqtt_fail=4 mqtt_rate=88 http_queue=0 mqtt_queue=1
examples/ESP32TelemetryNode: a richer ESP32 node example with WiFi maintenance, capability-gated diagnostics, heartbeat events, and periodic runtime summaries.
examples/ESP32TelemetryBaseline: a manual-loop baseline for the same ESP32 telemetry workload so timing overhead can be compared fairly.
examples/FaultInjectionDemo: a fault-focused demo that injects overruns, exposes watchdog signals, enters safe mode, and then returns to normal operation.
examples/FaultInjectionBaseline: a manual-loop baseline for the same fault-focused workload.
Quick runners:
ZeroKernel already includes local and hardware validation:
Main scripts:
The runtime can be tuned at compile time through ZeroKernelConfig.h and project-level macros.
Key profiles:
Important lean-build switches:
ZEROKERNEL_ENABLE_CAPABILITIES stays enabled in full profiles and is compiled out in POWER_SAVE and MINIMAL_RUNTIME, so lean targets do not pay extra static RAM for capability state.
ZEROKERNEL_PROFILE_NETWORK_NODE biases the runtime toward WiFi/BLE/MQTT-style firmware: key-first routing, bounded command/work queues, stronger drain budgets, and leaner metadata by default. ZEROKERNEL_PROFILE_LEAN_NET pushes harder on that same direction for module-heavy nodes: smaller queue defaults, stripped diagnostics, topic-key routing, and tighter runtime state for optional network helpers.
For small builds, the goal is to preserve the public API while collapsing runtime cost toward key-based routing and stripped diagnostics.
ZeroKernel is built around explicit runtime constraints:
ZeroKernel is structured to work well as an open-core infrastructure project:
The repository is now set up as a serious infrastructure codebase, not an Arduino toy project.
ZeroKernel/
src/
core/
diagnostics/
internal/
adapters/
examples/
tests/
benchmarks/
docs/
scripts/
Key files:
| Back | FazBrowse Home | New Git URL |