Very simple cooperative round-robin task scheduler. See examples.
Revision 5:1dfc64077059, committed 2021-04-15
- Comitter:
- pkunnals
- Date:
- Thu Apr 15 01:07:06 2021 +0000
- Parent:
- 4:49652acb6806
- Commit message:
- Nothing changed
Changed in this revision
diff -r 49652acb6806 -r 1dfc64077059 ChangeLog.h --- a/ChangeLog.h Fri Mar 04 13:55:15 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -/* - -1.3 04/Mar/2011 - Added even more documentation. - -1.2 04/Mar/2011 - Added extra documentation. - -1.1 04/Mar/2011 - When calling a task pass a pointer to the SimpleTask holding the pointer. - Missed this as STcallback allowed for passing a null value. That was fixed. - -1.0 04/Mar/2011 - Initial release. - -*/
diff -r 49652acb6806 -r 1dfc64077059 Examples/example1.h --- a/Examples/example1.h Fri Mar 04 13:55:15 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - Copyright (c) 2011 Andy Kirkham - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - - @file example1.h - @purpose Simple round-robin cooperative scheduler example - @date Mar 2011 - @author Andy Kirkham -*/ - -/* This example shows how to call tasks defined as C functions. */ - -#include "mbed.h" -#include "SimpleScheduler.h" - -DigitalOut led1(LED1); -DigitalOut led2(LED2); -DigitalOut led3(LED3); -DigitalOut led4(LED4); - -void f1(SimpleTask *task) { led1 = !led1; } -void f2(SimpleTask *task) { led2 = !led2; } -void f3(SimpleTask *task) { led3 = !led3; } -void f4(SimpleTask *task) { led4 = !led4; } - -SimpleScheduler *scheduler; - -int main() { - - scheduler = new SimpleScheduler; - - scheduler - ->addTask( new SimpleTask(0, f1) ) - ->addTask( new SimpleTask(200, f2) ) - ->addTask( new SimpleTask(300, f3) ) - ->addTask( new SimpleTask(0.4, f4) ) - ; - - scheduler->run(); -}
diff -r 49652acb6806 -r 1dfc64077059 Examples/example2.h --- a/Examples/example2.h Fri Mar 04 13:55:15 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - Copyright (c) 2011 Andy Kirkham - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - - @file example2.h - @purpose Simple round-robin cooperative scheduler example - @date Mar 2011 - @author Andy Kirkham -*/ - -/* This example shows how to call tasks defined as C++ class methods. */ - -#include "mbed.h" -#include "SimpleScheduler.h" - -// Task class example. -class Foo { -protected: - DigitalOut *_do; -public: - Foo(DigitalOut *d) { _do = d; } - void func(SimpleTask *task) { *_do = !*_do; } -}; - -DigitalOut led1(LED1); -DigitalOut led2(LED2); -DigitalOut led3(LED3); -DigitalOut led4(LED4); - -Foo foo1(&led1); -Foo foo2(&led2); -Foo foo3(&led3); -Foo foo4(&led4); - -SimpleScheduler *scheduler; - -int main() { - - scheduler = new SimpleScheduler; - - scheduler - ->addTask( new SimpleTask(0, &foo1, &Foo::func) ) - ->addTask( new SimpleTask(200, &foo2, &Foo::func) ) - ->addTask( new SimpleTask(300, &foo3, &Foo::func) ) - ->addTask( new SimpleTask(0.4, &foo4, &Foo::func) ) - ; - - scheduler->run(); -}
diff -r 49652acb6806 -r 1dfc64077059 Examples/example3.h --- a/Examples/example3.h Fri Mar 04 13:55:15 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -/* - Copyright (c) 2011 Andy Kirkham - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - - @file example3.h - @purpose Simple round-robin cooperative scheduler example - @date Mar 2011 - @author Andy Kirkham -*/ - -/* - SimpleScheduler is a cooperative scheduler. What that means is YOU, the - programmer MUST cooperate with it. SimpleScheduler will call your task - functions based on the schedule you provide. However, it's not a guarenteed - scheduled time. It's on a "best effort". However, no tasks are called until - the currently executing task completes. What that means is your task function - must return before another task can be called. - - Your tasks therefore should execute as fast as possible and return as soon as - they can. But when Mbed's wait API is used you stall your entire system. This - example shows how you can wait() in a task without actually waiting at all. In - order to do this we use the "Ton" (Timer ON) library. You will need to import - this library into your project to use this example:- - - http://mbed.org/users/AjK/libraries/Ton/latest - - What follows is basically example1. However, we are going to flash LED1 by - "waiting" 1second in the task. - -*/ - -#include "mbed.h" -#include "SimpleScheduler.h" -#include "Ton.h" - -Ton t1(1000); // Timer ON delay of one second. - -DigitalOut led1(LED1); -DigitalOut led2(LED2); -DigitalOut led3(LED3); -DigitalOut led4(LED4); - -void f1(SimpleTask *task) { - // wait(1); - if (!t1.isRunning()) { - t1 = Ton::On; - // Code that should execute once before the wait() goes here. - // ... - } - if (t1) { - // This code will be executed once the timer times out. - led1 = !led1; - t1.reset(); - } -} -void f2(SimpleTask *task) { led2 = !led2; } -void f3(SimpleTask *task) { led3 = !led3; } -void f4(SimpleTask *task) { led4 = !led4; } - -SimpleScheduler *scheduler; - -int main() { - - scheduler = new SimpleScheduler; - - scheduler - ->addTask( new SimpleTask(0, f1) ) - ->addTask( new SimpleTask(200, f2) ) - ->addTask( new SimpleTask(300, f3) ) - ->addTask( new SimpleTask(0.4, f4) ) - ; - - scheduler->run(); -} -
diff -r 49652acb6806 -r 1dfc64077059 Examples/example4.h --- a/Examples/example4.h Fri Mar 04 13:55:15 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +0,0 @@ -/* - Copyright (c) 2011 Andy Kirkham - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - - @file example4.h - @purpose Simple round-robin cooperative scheduler example - @date Mar 2011 - @author Andy Kirkham -*/ - -/* - This example uses the network stack to setup the time. Note, when I tested - this I had two things in place. If you want to run this example then you too - will need:- - - 1. Your Mbed with an Ethernet jack socket. I used a Cool Components Workshop - board: http://www.coolcomponents.co.uk/catalog/product_info.php?products_id=528 - 2. You will need to import a network stack into your project. The one I used was - this one: http://mbed.org/users/segundo/libraries/NetServices/ljhqix - - What this example shows is the usual "flash some LEDs tasks" and an example of how - to setup the time on the Mbed via the attached ethernet/Internet network. I used - setting the time as a network example but you could do HTTP requests, etc. - - The purpose of this example is to show how to use the network stack to do a NON-BLOCKING - network call. SimpleScheduler is a coopertive scheduler and that means you should not - wait around in task functions. You should complete your tasks as fast as possible so - that other scheduled tasks are not blocked from running. However, making network calls - generally take some time to complete so are considered "slow" (compared the clock freq - of the LPC1768 micro that is!). So to avoid stalling out waiting for a reply our tasks - must use NON-BLOCKING calls. This is what this example is for, to demostrate how to - make a non-blocking network stack call. -*/ - -#include "mbed.h" -#include "SimpleScheduler.h" -#include "EthernetNetIf.h" -#include "HTTPClient.h" -#include "NTPClient.h" - -// Setup a serial port to print the time to. -Serial pc(USBTX, USBRX); - -// The usual suspects. -DigitalOut led1(LED1); -DigitalOut led2(LED2); -DigitalOut led3(LED3); -DigitalOut led4(LED4); - -// A scheduler. -SimpleScheduler *scheduler; - -// Setup the network statck. -EthernetNetIf eth; -EthernetErr ethErr; -NTPClient ntp; -NTPResult result; - -// Declare the host we are going to ask the time. -Host server(IpAddr(), 123, "0.de.pool.ntp.org"); - -// Scheduler task functions. -void f2(SimpleTask *task) { led2 = !led2; } -void f3(SimpleTask *task) { led3 = !led3; } -void f4(SimpleTask *task) { led4 = !led4; } -void netPoll(SimpleTask *task) { Net::poll(); } - -bool clockAccurate; - -// Scheduler task function. -void showTime(SimpleTask *task) { - time_t theTime = time(NULL); - char *s = ctime(&theTime); - for(char *p = s; *p != '\0'; p++) if (*p == '\n') { *p = '\0'; break; } // rtrim \n - pc.printf("Time is now (UTC): %s", s); - if (!clockAccurate) { - pc.printf(" (maybe inaccurate)"); - } - pc.printf("\n"); - if (result != NTP_OK) { - pc.printf(" NTP status: "); - switch(result) { - case NTP_PROCESSING: pc.printf("NTP_PROCESSING.\n"); break; - case NTP_PRTCL: pc.printf("NTP_PRTCL protocol error.\n"); break; - case NTP_TIMEOUT: pc.printf("NTP_TIMEOUT.\n"); break; - case NTP_DNS : pc.printf("NTP_DNS.\n"); break; - } - } -} - -// Network stack callbacks. -void getTimeCallback(NTPResult i) { - result = i; - led1 = !led1; - clockAccurate = i == NTP_OK ? true : false; -} - -// Scheduler task function. -void setTime(SimpleTask *task) { - if (!ethErr) { - result = NTP_PROCESSING; - ntp.setTime(server, getTimeCallback); - } -} - -int main() { - pc.baud(115200); - pc.printf("Example4 starting up.\n"); - - clockAccurate = false; - - ethErr = eth.setup(); - if (ethErr) { - pc.printf("Error %d in setup.\n", ethErr); - } - else { - result = NTP_PROCESSING; - ntp.setTime(server, getTimeCallback); - } - - scheduler = new SimpleScheduler; - - scheduler - ->addTask( new SimpleTask(200, f2) ) - ->addTask( new SimpleTask(300, f3) ) - ->addTask( new SimpleTask(0.4, f4) ) - ; - - // Only add these tasks if Ethernet setup is ok. - // Notice we add netPoll() with a time of zero. - // Zero means "call as often as possible". The - // network stack needs to be polled on a regular - // basis. As often as possible in fact. The other - // two tasks are "just print the time to serial - // once every 5seconds" and the other is "update - // the clock from remote host once an hour". - // Remember, integers are milliseconds but real - // numbers are seconds). - if (!ethErr) { - scheduler - ->addTask( new SimpleTask(0, netPoll) ) - ->addTask( new SimpleTask(5.0, showTime) ) - ->addTask( new SimpleTask(3600.0, setTime) ) - ; - } - - scheduler->run(); -} - - -