Skip to content

blah188/LionTask

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LionTask

A tiny cooperative (run-to-completion) task scheduler for ESP8266 and classic AVR. You pump it from loop(); each task runs to completion on the main context — there is no preemption and no per-task stack, so a task that blocks blocks everything.

#include <LionTask.h>

class Blink : public LionTimerTask {
public:
    Blink() : LionTimerTask(F("Blink"), 500) {}   // run every 500 ms
protected:
    void TaskInnerBody() override { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); }
};

Blink blink;

void setup() { Serial.begin(115200); LionTask::Setup(); }
void loop()  { LionTask::Loop(); }

On ESP32 use real FreeRTOS tasks via leva/LionRtosTask instead — a cooperative scheduler is pointless where you have an RTOS.

⚠️ Contract — read this first

  • Identity by pointer. Each task registers itself (this) into a shared static list in its constructor and removes itself in its destructor.
  • Non-copyable. Copy ctor / assignment are = deleted — create each task once, as a global/static or via new, and never copy it.
  • Lifetime. A heap task may delete this from its own body (that is exactly what a one-shot LionSimpleTask does); a stack/global task must outlive the last LionTask::Loop()/Yield() call that can reach it.
  • Cooperation. Keep each task body short. Critical tasks additionally run during Yield()/Delay(), so keep those especially short.
  • Scheduling. By default one regular task runs per Loop() call (round-robin fairness); critical tasks all run every Loop() and every Yield().
  • Not reentrant / not thread-safe. Create and pump tasks from one context.
  • LionSimpleTask (lambda task) and GetDebugDump() (returns String) are ESP-only — both are compiled out on classic AVR (no <functional>, and String churn fragments the tiny AVR heap). Subclass a Lion*Task and use DebugDump() there instead.

Install

PlatformIO (platformio.ini):

lib_deps = leva/LionTask

This pulls in its only dependency, leva/LionArray, automatically.

Arduino IDE: Library Manager → search "LionTask", or drop this folder into your libraries/ directory (also install LionArray).

Usage

Subclass a periodic task

#include <LionTask.h>

class Heartbeat : public LionTimerTask {
public:
    Heartbeat() : LionTimerTask(F("HB"), 1000) {}   // every 1000 ms
protected:
    void TaskInnerBody() override { Serial.println(F("tick")); }
};

Heartbeat hb;

void setup() { Serial.begin(115200); LionTask::Setup(); }
void loop()  { LionTask::Loop(); }

Task base classes, smallest delay storage first:

Class Delay type Range
LionTimerTask uint32_t up to ~49 days (ms)
LionShortTimerTask uint16_t up to ~65 s (ms)
LionCrudeTimerTask uint8_t 1–255 s (whole seconds)
LionCriticalTask uint16_t also runs during Yield()

Run a lambda without subclassing (ESP only)

// periodic
LionSimpleTask::ExecuteEachMs([]() { Serial.println(F("ping")); }, 10000, F("Ping"));

// one-shot, after a delay (the task frees itself afterwards)
LionSimpleTask::Execute([]() { Serial.println(F("once")); }, 2000, F("Once"));

API summary

class LionTask (base — static control surface)

Member Description
static void Setup() One-time banner / init. Call from setup().
static void Loop() Pump the scheduler. Call as often as possible from loop().
static void Yield() Run due critical tasks only (use inside long work).
static void Delay(uint32_t ms) Busy-wait ms while still running critical tasks.
static int TaskNumber() Number of regular tasks.
static void DebugDump() Print every task's next-run time to Serial.
static String GetDebugDump() Same as a String (ESP only).
const char *Name() This task's (truncated) name.
void ExecuteNow() Schedule this task to run on the next Loop().

Task shapes (subclass and override TaskInnerBody())

LionTimerTask, LionShortTimerTask, LionCrudeTimerTask, LionCriticalTask — constructed with (name, delay) where name is a const __FlashStringHelper* (F("...")) or String.

class LionSimpleTask (ESP only)

Member Description
static void Execute(callable, ms, name) Run callable once, ms after creation, then self-delete.
static void ExecuteEachMs(callable, ms, name) Run callable every ms forever.

callable is any std::function<void()> — lambda, function pointer or functor.

License

0BSD — see LICENSE.

About

Tiny cooperative (run-to-completion) task scheduler for ESP8266 and AVR

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages