aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatoli Arkhipenko <arkhipenko@hotmail.com>2015-12-17 16:19:01 -0500
committerAnatoli Arkhipenko <arkhipenko@hotmail.com>2015-12-17 16:27:13 -0500
commitff9be9377117960d03f44e493afb2e280f9b86ab (patch)
tree5a3a1684d70411e45e2710ff5a5ac5b291ae5d2e
parentea4d2f858cf8da39258976f3c15c982c8127c3f5 (diff)
v1.9.1 bug fixes, automatic millis rollover, update to time critical
* _TASK_ROLLOVER_FIX is deprecated (not necessary) * bug fixes: automatic millis rollover support for delay methods * new method for _TASK_TIMECRITICAL option: getStartDelay()
-rw-r--r--README24
-rw-r--r--examples/Scheduler_example1/Scheduler_example1.ino (renamed from examples/Scheduler_example/Scheduler_example.ino)0
-rw-r--r--examples/Scheduler_example10_Benchmark/Scheduler_example10_Benchmark.ino93
-rw-r--r--examples/Scheduler_example9_TimeCritical/Scheduler_example9_TimeCritical.ino57
-rw-r--r--extras/TaskScheduler.docbin205312 -> 206848 bytes
-rw-r--r--extras/TaskScheduler.html48
-rw-r--r--keywords.txt1
-rw-r--r--src/TaskScheduler.h1
8 files changed, 202 insertions, 22 deletions
diff --git a/README b/README
index b167733..258958c 100644
--- a/README
+++ b/README
@@ -1,20 +1,24 @@
Task Scheduler – cooperative multitasking for Arduino microcontrollers
-Version 1.9.1: 2015-11-28
+Version 1.9.1: 2015-12-17
OVERVIEW:
-A lightweight implementation of cooperative multitasking (task scheduling) supporting:
-1. Periodic task execution (with dynamic execution period in milliseconds)
-2. Number of iterations (n times)
-3. Execution of tasks in predefined sequence
-4. Dynamic change of task execution parameters (frequency, number of iterations, callback function)
-5. Power saving via entering IDLE sleep mode between tasks are scheduled to run
-6. Support for task invocation via Status Request object
-7. Support for task IDs and Control Points for error handling and watchdog timer
-8. Support for Local Task Storage pointer (allowing use of same callback code for multiple tasks)
+ A lightweight implementation of cooperative multitasking (task scheduling) supporting:
+ 1. Periodic task execution (with dynamic execution period in milliseconds)
+ 2. Number of iterations (n times)
+ 3. Execution of tasks in predefined sequence
+ 4. Dynamic change of task execution parameters (frequency, number of iterations, callback function)
+ 5. Power saving via entering IDLE sleep mode between tasks are scheduled to run
+ 6. Support for task invocation via Status Request object
+ 7. Support for task IDs and Control Points for error handling and watchdog timer
+ 8. Support for Local Task Storage pointer (allowing use of same callback code for multiple tasks)
+
+Scheduling overhead: between 15 and 18 microseconds per scheduling pass (check the banchmark example).
Changelog:
v1.9.1:
2015-11-28 - _TASK_ROLLOVER_FIX is deprecated (not necessary)
+ 2015-12-16 - bug fixes: automatic millis rollover support for delay methods
+ 2015-12-17 - new method for _TASK_TIMECRITICAL option: getStartDelay()
v1.9.0:
2015-11-24 - packed three byte-long status variables into one byte-long bit array structure data type - saving 2 bytes per each task instance
diff --git a/examples/Scheduler_example/Scheduler_example.ino b/examples/Scheduler_example1/Scheduler_example1.ino
index 2175e57..2175e57 100644
--- a/examples/Scheduler_example/Scheduler_example.ino
+++ b/examples/Scheduler_example1/Scheduler_example1.ino
diff --git a/examples/Scheduler_example10_Benchmark/Scheduler_example10_Benchmark.ino b/examples/Scheduler_example10_Benchmark/Scheduler_example10_Benchmark.ino
new file mode 100644
index 0000000..221b676
--- /dev/null
+++ b/examples/Scheduler_example10_Benchmark/Scheduler_example10_Benchmark.ino
@@ -0,0 +1,93 @@
+
+/**
+ * This is a test to benchmark TaskScheduler execution.
+ *
+ * This test executes 1,000,000 cycles of a task with empty callback method
+ * Compiled with different options, you can assess the impact of each on the size of the Task object
+ * and the execution overhead of the main execution pass route.
+ *
+ * Sample execution times (in milliseconds per 1M iterations) are provided below.
+ * The test board is Arduino UNO 16MHz processor.
+ *
+
+
+TaskScheduler 1.9.0:
+No modifiers
+Duration=15656
+
+with SLEEP
+Duration=16285
+
+with status request:
+Duration=16600
+
+with rollover fix:
+Duration=18109
+
+
+TaskScheduler 1.8.5:
+Duration=15719
+
+with SLEEP
+Duration=16348
+
+with status request:
+Duration=18360
+
+with rollover fix:
+Duration=18423
+
+ */
+
+
+//#define _TASK_TIMECRITICAL // Enable monitoring scheduling overruns
+#define _TASK_STATUS_REQUEST // Compile with support for StatusRequest functionality - triggering tasks on status change events in addition to time only
+//#define _TASK_WDT_IDS // Compile with support for wdt control points and task ids
+//#define _TASK_LTS_POINTER // Compile with support for local task storage pointer
+#define _TASK_ROLLOVER_FIX // Compensate for millis() rollover once every 47 days
+#define _TASK_SLEEP_ON_IDLE_RUN
+#include <TaskScheduler.h>
+
+Scheduler ts;
+
+// Callback methods prototypes
+bool tOn(); void tOff();
+void callback();
+
+// Tasks
+Task t(TASK_IMMEDIATE, 1000000, &callback, &ts, false, &tOn, &tOff);
+
+unsigned long c1, c2;
+
+bool tOn() {
+ c1 = millis();
+ c2 = 0;
+
+ return true;
+}
+
+void tOff() {
+ c2 = millis();
+ Serial.println("done.");
+ Serial.print("Tstart =");Serial.println(c1);
+ Serial.print("Tfinish=");Serial.println(c2);
+ Serial.print("Duration=");Serial.println(c2-c1);
+}
+
+void setup() {
+ // put your setup code here, to run once:
+ Serial.begin(115200);
+ Serial.print("Start...");
+
+ t.enable();
+}
+
+void callback() {
+
+}
+
+
+void loop() {
+ // put your main code here, to run repeatedly:
+ ts.execute();
+}
diff --git a/examples/Scheduler_example9_TimeCritical/Scheduler_example9_TimeCritical.ino b/examples/Scheduler_example9_TimeCritical/Scheduler_example9_TimeCritical.ino
new file mode 100644
index 0000000..b330d6f
--- /dev/null
+++ b/examples/Scheduler_example9_TimeCritical/Scheduler_example9_TimeCritical.ino
@@ -0,0 +1,57 @@
+/**
+ * TaskScheduler Test
+ * Illustration of use of Time Critical Information
+ *
+ * Task1 runs every 1 second indefinitely
+ * On each run it reports how delayed the invokation of the callback method was,
+ * and what was the scheduling overun.
+ * Each run task 1 is dealyed randomly for up to 2 seconds, thus simulating scheduling overrun
+ */
+
+ #define _TASK_TIMECRITICAL
+ #define _TASK_SLEEP_ON_IDLE_RUN
+#include <TaskScheduler.h>
+
+// Callback methods prototypes
+void t1Callback();
+
+
+//Tasks
+Task t1(1000, -1, &t1Callback);
+
+Scheduler runner;
+
+
+void t1Callback() {
+ Serial.print(millis());
+ Serial.print(": overrun = ");
+ Serial.print(t1.getOverrun());
+ Serial.print(", start delayed by ");
+ Serial.println(t1.getStartDelay());
+
+ int i = random(2000);
+ Serial.print("Delaying for "); Serial.println(i);
+ delay(i);
+}
+
+void setup () {
+ Serial.begin(115200);
+ Serial.println("Scheduler TimeCritical TEST");
+
+ runner.init();
+ Serial.println("Initialized scheduler");
+
+ runner.addTask(t1);
+ Serial.println("added t1. Waiting for 5 seconds.");
+
+ delay(5000);
+
+ t1.enable();
+
+ Serial.println("Enabled t1");
+}
+
+
+void loop () {
+ runner.execute();
+}
diff --git a/extras/TaskScheduler.doc b/extras/TaskScheduler.doc
index a6e1933..5c1ed8d 100644
--- a/extras/TaskScheduler.doc
+++ b/extras/TaskScheduler.doc
Binary files differ
diff --git a/extras/TaskScheduler.html b/extras/TaskScheduler.html
index 1631975..d78f5f2 100644
--- a/extras/TaskScheduler.html
+++ b/extras/TaskScheduler.html
@@ -15,7 +15,7 @@
<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in; direction: ltr; color: #000000; widows: 0; orphans: 0 }
- P.western { font-family: "Liberation Serif", "MS PMincho", serif; font-size: 12pt; so-language: en-US }
+ P.western { font-family: "Liberation Serif", "Times New Roman", serif; font-size: 12pt; so-language: en-US }
P.cjk { font-family: "WenQuanYi Micro Hei", "MS Mincho"; font-size: 12pt; so-language: zh-CN }
P.ctl { font-family: "Lohit Hindi", "MS Mincho"; font-size: 12pt; so-language: hi-IN }
A:link { color: #0000ff }
@@ -28,7 +28,7 @@ Scheduler</B></FONT></P>
<P CLASS="western" STYLE="margin-bottom: 0in"><B>cooperative
multitasking for Arduino microcontrollers</B></P>
<P CLASS="western" STYLE="margin-bottom: 0in; border-top: none; border-bottom: 1px solid #000000; border-left: none; border-right: none; padding-top: 0in; padding-bottom: 0.01in; padding-left: 0in; padding-right: 0in">
-<FONT SIZE=2 STYLE="font-size: 11pt"><B>Version 1.9.1: 2015-11-28</B></FONT></P>
+<FONT SIZE=2 STYLE="font-size: 11pt"><B>Version 1.9.1: 2015-12-17</B></FONT></P>
<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
</P>
<P CLASS="western" STYLE="margin-bottom: 0in"><B>OVERVIEW</B>:</P>
@@ -58,6 +58,10 @@ supporting:</P>
</OL>
<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
</P>
+<P CLASS="western" STYLE="margin-bottom: 0in">Scheduling overhead:
+between 15 and 18 microseconds per scheduling pass.</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
<P CLASS="western" STYLE="margin-bottom: 0in"><B>TASK</B>:</P>
<P CLASS="western" STYLE="margin-bottom: 0in">“Task” is a
container concept that links together:</P>
@@ -200,10 +204,19 @@ defined before the library header file in the body of arduino sketch.</P>
<P CLASS="western" STYLE="margin-bottom: 0in">...will compile the
library with time critical tracking option enabled.</P>
<P CLASS="western" STYLE="margin-bottom: 0in">Time critical option
-keeps track where next execution time of the task falls, and makes it
-available via API through <B>Task::getOverrun()</B> method. If
-<B>getOverrun </B>returns a negative value, this Task’s next
-execution time point is <I>already</I> in the past, and task is
+keeps track when current execution took place relative to when it was
+scheduled, and where next execution time of the task falls. Two
+methods provide this information.
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B>Task::getStartDelay()
+</B><SPAN STYLE="font-weight: normal">method: return number of
+milliseconds between current system time (millis) and point in time
+when the task was scheduled to start. A value of 0 (zero) indicates
+that task started right on time per schedule. </SPAN>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B>Task::getOverrun()</B>
+method: If <B>getOverrun </B>returns a negative value, this Task’s
+next execution time point is <I>already</I> in the past, and task is
behind schedule. This most probably means that either task’s
callback method's runtime is too long, or the execution interval is
too short (and therefore schedule is too aggressive).</P>
@@ -780,8 +793,8 @@ do last part of the stuff</FONT></FONT></P>
</P>
<P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">This
will execute all parts of the callback function in three successive
-steps, sheduled immediately, but allowing other tasks in the cahin to
-run. Notince that task is scheduled to run immediately, and 1 second
+steps, sheduled immediately, but allowing other tasks in the chain to
+run. Notice that task is scheduled to run immediately, and 1 second
period is achieved by delaying the task for 1000 millis at the last
step.
</P>
@@ -1022,6 +1035,16 @@ getIterations() </B>
<P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
</P>
<P CLASS="western" STYLE="margin-bottom: 0in"><B>long getOverrun()</B></P>
+<P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in; font-weight: normal">
+If library is compiled with <FONT FACE="Courier New, monospace">_TASK_TIMECRITICAL</FONT>
+enabled, you can assess how much later the callback method was
+invoked against when it was scheduled to be invoked. The return value
+of <B>getOverrun() </B>method provides this information in
+milliseconds.
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
+</P>
+<P CLASS="western" STYLE="margin-bottom: 0in"><B>long getOverrun()</B></P>
<P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">If
library is compiled with <FONT FACE="Courier New, monospace">_TASK_TIMECRITICAL</FONT>
enabled, tasks are monitored for “long running” scenario. A “long
@@ -1031,8 +1054,9 @@ other tasks where they don't run on a scheduled interval, but rather
“catch up” and are behind. When task scheduler sets the next
execution target time, it adds Task's execution interval to the
previously scheduled execution time:</P>
-<P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"> <B>next
-execution time = previous execution time + task execution interval</B></P>
+<P CLASS="western" ALIGN=CENTER STYLE="margin-left: 0.49in; margin-bottom: 0in">
+<B>next execution time = current execution scheduled time + task
+execution interval</B></P>
<P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in"><BR>
</P>
<P CLASS="western" STYLE="margin-left: 0.49in; margin-bottom: 0in">If
@@ -2794,7 +2818,7 @@ time examples of TaskScheduler are available here:</FONT></FONT></P>
<P CLASS="western" STYLE="margin-bottom: 0in"><BR>
</P>
<DIV TYPE=FOOTER>
- <P STYLE="margin-top: 0.35in; margin-bottom: 0in"> <SDFIELD TYPE=PAGE SUBTYPE=RANDOM FORMAT=ARABIC>4</SDFIELD></P>
+ <P STYLE="margin-top: 0.35in; margin-bottom: 0in"> <SDFIELD TYPE=PAGE SUBTYPE=RANDOM FORMAT=ARABIC>31</SDFIELD></P>
</DIV>
</BODY>
-</HTML>
+</HTML> \ No newline at end of file
diff --git a/keywords.txt b/keywords.txt
index 5332e33..df63872 100644
--- a/keywords.txt
+++ b/keywords.txt
@@ -43,6 +43,7 @@ setOnEnable KEYWORD2
setOnDisable KEYWORD2
disableOnLastIteration KEYWORD2
getOverrun KEYWORD2
+getStartDelay KEYWORD2
isFirstIteration KEYWORD2
isLastIteration KEYWORD2
setWaiting KEYWORD2
diff --git a/src/TaskScheduler.h b/src/TaskScheduler.h
index aa0a05a..ab5ac11 100644
--- a/src/TaskScheduler.h
+++ b/src/TaskScheduler.h
@@ -71,6 +71,7 @@
//
// v1.9.1:
// 2015-11-28 - _TASK_ROLLOVER_FIX is deprecated (not necessary)
+// 2015-12-16 - bug fixes: automatic millis rollover support for delay methods
// 2015-12-17 - new method for _TASK_TIMECRITICAL option: getStartDelay()