I am somewhat curious about the RTOS-like scheduler. Can you provide the relevant code so I can take a look?
Sure. It's not actually that powerful -- but it was sufficient for this robot. There's not even preemption.
Anyway, the relevant code follows. First, the Task class:
typedef void (*TaskCallback)(TaskManager &);
class Task {
private:
long m_countdown, m_period;
TaskCallback m_callback;
friend class TaskManager;
long decrementCountdownBy(long by) {
return m_countdown -= by;
}
void inline resetCountdown(void) {
m_countdown = m_period;
}
void inline run(TaskManager &tm) {
m_callback(tm);
}
public:
Task(TaskCallback callback, long period) :
m_callback(callback), m_countdown(period), m_period(period) {
}
};
Each task will be an instance of this class. Like so, for a blinking LED example with 1000ms interval:
void task1(TaskManager &tm)
{
static ledStatus = false;
digitalWrite(13, ledStatus^=1);
}
Task tasks[] = { Task(task1, 1000); };
You'll also need the scheduler itself; relevant parts of the code follows:
class TaskManager {
private:
Task *m_tasks;
unsigned int m_nTasks;
unsigned long m_lastTime;
void sleep(void) {
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_enable();
sleep_mode();
sleep_disable();
}
public:
TaskManager(Task *tasks, int n_tasks) :
m_tasks(tasks), m_nTasks(n_tasks), m_lastTime(0L) {
}
void inline loop() {
Task *task;
unsigned int n_task;
unsigned long elapsedTime = millis() - m_lastTime;
for (n_task = m_nTasks; n_task > 0; n_task--) {
task = &m_tasks[n_task];
if (task->decrementCountdownBy(elapsedTime) <= 0) {
task->run(*this);
task->resetCountdown();
}
}
m_lastTime = millis();
sleep();
}
};
So, if you call the loop() method of the task manager, all tasks will be executed roughly at the frequency you told them to execute:
TaskManger tm(tasks, 1);
void loop()
{
tm.loop();
}
As there is no preemption, you should be aware that a task won't be stopped in middle-air. Also, there is no guarantee that the task execution periods will be respected. It is crude, but sufficient for most things people use Arduinos for