Skip to content

MikiEEE/SmallOS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

107 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

smallOS

smallOS is a lightweight cooperative runtime for priority-oriented task management.

It is designed around three ideas:

  • write tasks with modern async / await syntax
  • keep scheduling policy owned by smallOS, not asyncio
  • stay portable enough to run on desktop Python today and MicroPython boards later

Status

The project is currently experimental but usable. The runtime core supports:

  • priority-based cooperative scheduling
  • task spawning, join, and join_all
  • signal-based wakeups
  • time-based sleeping
  • readiness-based socket/I/O waiting
  • generic TCP/TLS kernel hooks for higher-level protocols
  • smallOS-native HTTP, Redis, MQTT, SSE, and WebSocket helper clients

Why smallOS?

Python's asyncio gives great syntax, but it also brings its own scheduler and event-loop policy. smallOS keeps the syntax while swapping in a custom runtime, so tasks can be scheduled with project-specific priority rules and a smaller portability surface.

That makes it a good fit for:

  • robotics or device-control projects
  • embedded experiments on MicroPython boards
  • custom runtimes where task priority matters
  • learning how coroutine scheduling works under the hood

Project Layout

Installation

Desktop development:

python3 -m venv .venv
source .venv/bin/activate
pip install -e .

Run the test suite:

python3 -m unittest discover -s tests -v

Quick Start

Minimal desktop runtime:

from SmallPackage.Kernel import Unix
from SmallPackage.SmallConfig import SmallOSConfig
from SmallPackage.SmallOS import SmallOS
from SmallPackage.SmallTask import SmallTask


async def hello(task):
    task.OS.print("hello from smallOS\n")
    await task.sleep(0.1)
    return "done"


config = SmallOSConfig.from_json_file("smallos.config.json")
runtime = SmallOS(config=config).setKernel(Unix())
runtime.fork([SmallTask(2, hello, name="hello")])
runtime.startOS()

Configuration

The runtime now uses a first-class config object backed by smallos.config.json.

Current config fields:

  • task_capacity: maximum tracked tasks / PID slots
  • priority_levels: number of ready-queue categories
  • io_buffer_length: buffered app output length when the terminal view is hidden
  • eternal_watchers: keep the runtime alive when only watcher tasks remain
  • client_defaults: shared defaults for cooperative clients and streams

Example:

{
  "task_capacity": 1024,
  "priority_levels": 10,
  "io_buffer_length": 1024,
  "eternal_watchers": false,
  "client_defaults": {
    "stream": {
      "max_buffer_size": 16777216
    },
    "http": {
      "max_response_size": 16777216
    },
    "redis": {
      "max_response_size": 16777216,
      "max_nesting_depth": 32
    },
    "mqtt": {
      "keepalive": 60,
      "max_packet_size": 262144,
      "max_queued_messages": 1024
    }
  }
}

The config loader also accepts the aliases oslist_length and num_categories so older notes and experiments can map cleanly onto the current runtime.

Client constructors still accept explicit overrides, but when you create them inside a task they now inherit these defaults from task.OS.config unless you pass a value directly.

Kernels and Board Profiles

Desktop kernel:

  • Unix

MicroPython kernels:

  • MicroPythonKernel
  • ESP32
  • PicoW / RaspberryPiPicoW
  • ESP8266 compatibility profile

You can either pick a board profile explicitly or let the runtime choose a built-in profile from the firmware machine string:

from SmallPackage.Kernel import ESP32, PicoW, build_micropython_kernel

kernel = ESP32(hostname="smallos-esp32")
kernel = PicoW(country="US", hostname="smallos-pico")
kernel = build_micropython_kernel()

Demos

The new demos live in demos:

The original root demo remains available in demo.py as a compatibility wrapper around demos/runtime_demo.py.

Runtime Model

smallOS is intentionally small in scope:

  • tasks are async def coroutines wrapped in SmallTask
  • task code awaits smallOS-owned awaitables such as task.sleep(...), task.wait_signal(...), task.wait_readable(...), and task.join(...)
  • the scheduler steps coroutines directly and decides when each task becomes runnable again
  • kernels provide timing, output, and readiness-based transport primitives

This means arbitrary asyncio libraries are not drop-in compatible with the runtime, but it also means scheduling policy and portability stay under your control.

Running on MicroPython

For MicroPython targets, the intended flow is:

  1. choose ESP32, PicoW, or build_micropython_kernel()
  2. optionally connect Wi-Fi through the kernel helper
  3. build SmallOS(config=...)
  4. fork tasks and start the runtime

The kernel layer is deliberately generic. Protocol clients such as HTTPS, Redis, MQTT, RabbitMQ/AMQP, and Kafka should be built on top of the shared TCP/TLS socket surface rather than requiring protocol-specific kernel methods.

Clients

The current setup now includes first-party smallOS-native helpers for HTTP, Redis, and MQTT, so users can stay inside the smallOS scheduler instead of dropping down to raw sockets or depending on asyncio-owned clients.

Available helpers:

  • SmallHTTPClient
  • SmallRedisClient
  • SmallMQTTClient

Current scope:

  • HTTP: request/response helper with query params, JSON bodies, TLS, and chunked/content-length response parsing
  • Redis: RESP command execution plus helpers like ping, get, set, delete, publish, and subscribe
  • MQTT: MQTT 3.1.1 connect/disconnect, publish at QoS 0/1/2, subscribe at QoS 0/1/2, and inbound message receive with PUBACK/PUBREC/PUBREL/PUBCOMP handling as required by the protocol
  • Both clients: optional username/password auth and TLS transport setup, with Unix support for custom CA and client certificate paths through tls_ca_file, tls_cert_file, and tls_key_file

For detailed examples, constructor options, response helpers, and transport notes, see SmallPackage/clients/README.md.

Contributing

Contributions, issues, experiments, and board-port notes are welcome. Good areas for contribution include:

  • new MicroPython port validation
  • higher-level protocol clients built on the transport layer
  • shell and debugging tools
  • more board demos and deployment examples
  • additional scheduler tests and edge-case coverage

License

This project is licensed under the MIT License. See LICENSE.

About

Lightweight Robotics Concurrent Task Management Prototype

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages