Simple round-robin scheduler for mbed

Overview

This library provides simple round-robin scheduling based on the mbed-os.

Why would you want to use this?

  • Tasks are not run from within interrupt sub-routines (as they are using Tickers)
  • Ordering/priority of tasks is deterministic (rate monotonic)

It's not rocket science, just a handy wrapper around the RTOS functions.

Example

#define BASE_RATE 0.1f
#define TASK1_MULTIPLIER 1
#define TASK2_MULTIPLIER 2
....
    RoundRobin::instance()->SetBaseRate( BASE_RATE );
    RoundRobin::instance()->addTask( TASK1_MULTIPLIER, lcdRefresh );
    RoundRobin::instance()->addTask( TASK2_MULTIPLIER, watchButtons );
Revision:
0:a8c603b939a7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RoundRobin.cpp	Sat Jul 29 11:53:34 2017 +0000
@@ -0,0 +1,69 @@
+/* Copyright 2017 John Bailey
+ 
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "RoundRobin.hpp"
+
+RoundRobin* RoundRobin::p_instance = NULL;
+std::multimap<unsigned,RoundRobin::TaskEntry> RoundRobin::p_taskList;
+
+RoundRobin* RoundRobin::instance( void )
+{
+    if (!p_instance)
+    {
+        p_instance = new RoundRobin();
+    }
+    return p_instance;
+}
+
+RoundRobin::RoundRobin()
+{
+    thread = new Thread(osPriorityLow);
+    thread->start(callback(&eventQueue, &EventQueue::dispatch_forever));
+}
+
+void RoundRobin::SetBaseRate( const float p_rate )
+{
+    ticker.attach( eventQueue.event( &EventTrigger ), p_rate );
+}
+
+RoundRobin::~RoundRobin()
+{
+    delete( thread );
+}
+
+void RoundRobin::EventTrigger( void )
+{
+    for( std::multimap<unsigned,TaskEntry>::iterator i = p_taskList.begin();
+         i != p_taskList.end();
+         i++ )
+    {
+        i->second.tick();
+        i->second.triggerIfNeeded(i->first);
+    }
+}
+
+bool RoundRobin::addTask( unsigned p_multiplier, void (*p_fn)(void) )
+{
+    bool success = false;
+    if( p_multiplier > 0 )
+    {
+        TaskEntry newTask ( p_fn );
+
+        p_taskList.insert( std::pair<unsigned,TaskEntry>(p_multiplier, newTask ));
+    
+        success = true;
+    }
+    return success;
+}