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 );
Diff: RoundRobin.cpp
- 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; +}