Explorar el Código

Merge branch 'testing'

Anatoli Arkhipenko hace 5 años
padre
commit
89c5d60916

+ 3 - 2
README.md

@@ -1,8 +1,8 @@
 # Task Scheduler
 # Task Scheduler
 ### Cooperative multitasking for Arduino, ESPx, STM32 and other microcontrollers
 ### Cooperative multitasking for Arduino, ESPx, STM32 and other microcontrollers
-#### Version 3.1.6: 2020-05-12 [Latest updates](https://github.com/arkhipenko/TaskScheduler/wiki/Latest-Updates)
+#### Version 3.2.0: 2020-08-16 [Latest updates](https://github.com/arkhipenko/TaskScheduler/wiki/Latest-Updates)
 
 
-[![arduino-library-badge](https://www.ardu-badge.com/badge/TaskScheduler.svg?)](https://www.ardu-badge.com/TaskScheduler)
+[![arduino-library-badge](https://www.ardu-badge.com/badge/TaskScheduler.svg?)](https://www.ardu-badge.com/TaskScheduler)[![xscode](https://img.shields.io/badge/Available%20on-xs%3Acode-blue?style=?style=plastic&logo=appveyor&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRF////////VXz1bAAAAAJ0Uk5T/wDltzBKAAAAlUlEQVR42uzXSwqAMAwE0Mn9L+3Ggtgkk35QwcnSJo9S+yGwM9DCooCbgn4YrJ4CIPUcQF7/XSBbx2TEz4sAZ2q1RAECBAiYBlCtvwN+KiYAlG7UDGj59MViT9hOwEqAhYCtAsUZvL6I6W8c2wcbd+LIWSCHSTeSAAECngN4xxIDSK9f4B9t377Wd7H5Nt7/Xz8eAgwAvesLRjYYPuUAAAAASUVORK5CYII=)](https://xscode.com/arkhipenko/TaskScheduler)
 
 
 ### OVERVIEW:
 ### OVERVIEW:
 A lightweight implementation of cooperative multitasking (task scheduling) supporting:
 A lightweight implementation of cooperative multitasking (task scheduling) supporting:
@@ -19,6 +19,7 @@ A lightweight implementation of cooperative multitasking (task scheduling) suppo
 11. Overall task timeout
 11. Overall task timeout
 12. Static and dynamic callback method binding
 12. Static and dynamic callback method binding
 13. CPU load / idle statistics for time critical applications
 13. CPU load / idle statistics for time critical applications
+14. Scheduling options with priotity for original schedule (with and without catchup) and interval
 
 
 Scheduling overhead: between `15` and `18` microseconds per scheduling pass (Arduino UNO rev 3 @ `16MHz` clock, single scheduler w/o prioritization)
 Scheduling overhead: between `15` and `18` microseconds per scheduling pass (Arduino UNO rev 3 @ `16MHz` clock, single scheduler w/o prioritization)
 
 

+ 181 - 0
examples/Scheduler_example26_SCHEDULING_OPTIONS/Scheduler_example26_SCHEDULING_OPTIONS.ino

@@ -0,0 +1,181 @@
+/*
+    Example of scheduling options:
+
+    t1 - is a default option with priority given to schedule, i.e., scheduler tries
+         maintain original schedule and performs task "catch up" to ensure the number
+         of iterations that were supposed to happen do happen.
+
+    t2 - is an option with priority given to schedule, but without "catch up"
+         the scheduler will try to maintain original schedule, but next task invocation
+         is always scheduled to happen in the future 
+
+    t3 - is a option with priority given to interval. Task are scheduled always in the
+         future from the point of their current invocation start using task's interval.
+
+
+*/
+// ==== DEFINES ===================================================================================
+
+// ==== Debug and Test options ==================
+#define _DEBUG_
+//#define _TEST_
+
+//===== Debugging macros ========================
+#ifdef _DEBUG_
+#define SerialD Serial
+#define _PM(a) SerialD.print(millis()); SerialD.print(": "); SerialD.println(a)
+#define _PP(a) SerialD.print(a)
+#define _PL(a) SerialD.println(a)
+#define _PX(a) SerialD.println(a, HEX)
+#else
+#define _PM(a)
+#define _PP(a)
+#define _PL(a)
+#define _PX(a)
+#endif
+
+
+
+
+// ==== INCLUDES ==================================================================================
+
+// ==== Uncomment desired compile options =================================
+// #define _TASK_TIMECRITICAL         // Enable monitoring scheduling overruns
+// #define _TASK_SLEEP_ON_IDLE_RUN    // Enable 1 ms SLEEP_IDLE powerdowns between tasks if no callback methods were invoked during the pass
+// #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_PRIORITY             // Support for layered scheduling priority
+// #define _TASK_MICRO_RES            // Support for microsecond resolution
+// #define _TASK_STD_FUNCTION         // Support for std::function (ESP8266 and ESP32 ONLY)
+// #define _TASK_DEBUG                // Make all methods and variables public for debug purposes
+// #define _TASK_INLINE               // Make all methods "inline" - needed to support some multi-tab, multi-file implementations
+// #define _TASK_TIMEOUT              // Support for overall task timeout
+// #define _TASK_OO_CALLBACKS         // Support for dynamic callback method binding
+// #define _TASK_DEFINE_MILLIS        // Force forward declaration of millis() and micros() "C" style
+// #define _TASK_EXPOSE_CHAIN         // Methods to access tasks in the task chain
+#define _TASK_SCHEDULING_OPTIONS    // Support for multiple scheduling options
+#include <TaskScheduler.h>
+
+
+
+// ==== GLOBALS ===================================================================================
+// ==== Scheduler ==============================
+Scheduler ts;
+
+void t1CB();
+void t2CB();
+void t3CB();
+
+// ==== Scheduling defines (cheat sheet) =====================
+/*
+  TASK_MILLISECOND
+  TASK_SECOND
+  TASK_MINUTE
+  TASK_HOUR
+  TASK_IMMEDIATE
+  TASK_FOREVER
+  TASK_ONCE
+  TASK_NOTIMEOUT
+
+  TASK_SCHEDULE     - schedule is a priority, with "catch up" (default)
+  TASK_SCHEDULE_NC  - schedule is a priority, without "catch up"
+  TASK_INTERVAL     - interval is a priority, without "catch up"
+*/
+
+// ==== Task definitions ========================
+Task t1_schedule    (100 * TASK_MILLISECOND, 10, &t1CB, &ts);
+Task t2_schedule_nc (100 * TASK_MILLISECOND, 10, &t2CB, &ts);
+Task t3_interval    (100 * TASK_MILLISECOND, 10, &t3CB, &ts);
+
+
+
+// ==== CODE ======================================================================================
+
+/**************************************************************************/
+/*!
+    @brief    Standard Arduino SETUP method - initialize sketch
+    @param    none
+    @returns  none
+*/
+/**************************************************************************/
+void setup() {
+  // put your setup code here, to run once:
+#if defined(_DEBUG_) || defined(_TEST_)
+  Serial.begin(115200);
+  delay(1000);
+  _PL("Scheduling Options: setup()");
+#endif
+
+  t2_schedule_nc.setSchedulingOption(TASK_SCHEDULE_NC);
+  t3_interval.setSchedulingOption(TASK_INTERVAL);
+
+
+  _PM("t1 start time");
+  t1_schedule.enable();
+  delay(10);
+  
+  _PM("t2 start time");
+  t2_schedule_nc.enable();
+  delay(10);
+
+  _PM("t3 start time");
+  t3_interval.enable();
+
+  delay(333);
+  _PM("333 ms delay ended");
+}
+
+
+/**************************************************************************/
+/*!
+    @brief    Standard Arduino LOOP method - using with TaskScheduler there
+              should be nothing here but ts.execute()
+    @param    none
+    @returns  none
+*/
+/**************************************************************************/
+void loop() {
+  ts.execute();
+}
+
+
+/**************************************************************************/
+/*!
+    @brief    Callback method of task1 - explain
+    @param    none
+    @returns  none
+*/
+/**************************************************************************/
+void t1CB() {
+  _PM("t1CB()");
+  //  task code
+  delay(10);
+}
+
+
+/**************************************************************************/
+/*!
+    @brief    Callback method of task2 - explain
+    @param    none
+    @returns  none
+*/
+/**************************************************************************/
+void t2CB() {
+  _PM("t2CB()");
+  //  task code
+  delay(10);
+}
+
+/**************************************************************************/
+/*!
+    @brief    Callback method of task3 - explain
+    @param    none
+    @returns  none
+*/
+/**************************************************************************/
+void t3CB() {
+  _PM("t3CB()");
+  //  task code
+  delay(10);
+}

+ 94 - 27
examples/Scheduler_template/Scheduler_template.ino

@@ -1,41 +1,71 @@
-// #define _TASK_TIMECRITICAL      // Enable monitoring scheduling overruns
-// #define _TASK_SLEEP_ON_IDLE_RUN // Enable 1 ms SLEEP_IDLE powerdowns between tasks if no callback methods were invoked during the pass
-// #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_PRIORITY          // Support for layered scheduling priority
-// #define _TASK_MICRO_RES         // Support for microsecond resolution
-// #define _TASK_STD_FUNCTION      // Support for std::function (ESP8266 and ESP32 ONLY)
-// #define _TASK_DEBUG             // Make all methods and variables public for debug purposes
-// #define _TASK_INLINE            // Make all methods "inline" - needed to support some multi-tab, multi-file implementations
-// #define _TASK_TIMEOUT           // Support for overall task timeout
-// #define _TASK_OO_CALLBACKS      // Support for dynamic callback method binding
-// #define _TASK_DEFINE_MILLIS     // Force forward declaration of millis() and micros() "C" style
-// #define _TASK_EXPOSE_CHAIN      // Methods to access tasks in the task chain
-
-#include <TaskScheduler.h>
+/*
+    Your code description here
+    (c) you, 20XX
+    All rights reserved.
+
+    Functionality: 
+    
+    Version log:
+    
+    20XX-MM-DD:
+        v1.0.0  - Initial release
+        
+*/
+// ==== DEFINES ===================================================================================
 
 
-// Debug and Test options
+// ==== Debug and Test options ==================
 #define _DEBUG_
 #define _DEBUG_
 //#define _TEST_
 //#define _TEST_
 
 
+//===== Debugging macros ========================
 #ifdef _DEBUG_
 #ifdef _DEBUG_
-#define _PP(a) Serial.print(a);
-#define _PL(a) Serial.println(a);
+#define SerialD Serial
+#define _PM(a) SerialD.print(millis()); SerialD.print(": "); SerialD.println(a)
+#define _PP(a) SerialD.print(a)
+#define _PL(a) SerialD.println(a)
+#define _PX(a) SerialD.println(a, HEX)
 #else
 #else
+#define _PM(a)
 #define _PP(a)
 #define _PP(a)
 #define _PL(a)
 #define _PL(a)
+#define _PX(a)
 #endif
 #endif
 
 
 
 
-// Scheduler
+
+
+// ==== INCLUDES ==================================================================================
+
+// ==== Uncomment desired compile options =================================
+// #define _TASK_SLEEP_ON_IDLE_RUN  // Enable 1 ms SLEEP_IDLE powerdowns between tasks if no callback methods were invoked during the pass
+// #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_PRIORITY           // Support for layered scheduling priority
+// #define _TASK_MICRO_RES          // Support for microsecond resolution
+// #define _TASK_STD_FUNCTION       // Support for std::function (ESP8266 and ESP32 ONLY)
+// #define _TASK_DEBUG              // Make all methods and variables public for debug purposes
+// #define _TASK_INLINE             // Make all methods "inline" - needed to support some multi-tab, multi-file implementations
+// #define _TASK_TIMEOUT            // Support for overall task timeout
+// #define _TASK_OO_CALLBACKS       // Support for dynamic callback method binding
+// #define _TASK_DEFINE_MILLIS      // Force forward declaration of millis() and micros() "C" style
+// #define _TASK_EXPOSE_CHAIN       // Methods to access tasks in the task chain
+// #define _TASK_SCHEDULING_OPTIONS // Support for multiple scheduling options
+
+#include <TaskScheduler.h>
+
+
+
+// ==== GLOBALS ===================================================================================
+// ==== Scheduler ==============================
 Scheduler ts;
 Scheduler ts;
 
 
 void task1Callback();
 void task1Callback();
 void task2Callback();
 void task2Callback();
 
 
+// ==== Scheduling defines (cheat sheet) =====================
 /*
 /*
-  Scheduling defines:
   TASK_MILLISECOND
   TASK_MILLISECOND
   TASK_SECOND
   TASK_SECOND
   TASK_MINUTE
   TASK_MINUTE
@@ -44,12 +74,27 @@ void task2Callback();
   TASK_FOREVER
   TASK_FOREVER
   TASK_ONCE
   TASK_ONCE
   TASK_NOTIMEOUT
   TASK_NOTIMEOUT
+  
+  TASK_SCHEDULE     - schedule is a priority, with "catch up" (default)
+  TASK_SCHEDULE_NC  - schedule is a priority, without "catch up"
+  TASK_INTERVAL     - interval is a priority, without "catch up"
 */
 */
 
 
+// ==== Task definitions ========================
 Task t1 (100 * TASK_MILLISECOND, TASK_FOREVER, &task1Callback, &ts, true);
 Task t1 (100 * TASK_MILLISECOND, TASK_FOREVER, &task1Callback, &ts, true);
 Task t2 (TASK_IMMEDIATE, 100, &task2Callback, &ts, true);
 Task t2 (TASK_IMMEDIATE, 100, &task2Callback, &ts, true);
 
 
 
 
+
+// ==== CODE ======================================================================================
+
+/**************************************************************************/
+/*!
+    @brief    Standard Arduino SETUP method - initialize sketch
+    @param    none
+    @returns  none
+*/
+/**************************************************************************/
 void setup() {
 void setup() {
   // put your setup code here, to run once:
   // put your setup code here, to run once:
 #if defined(_DEBUG_) || defined(_TEST_)
 #if defined(_DEBUG_) || defined(_TEST_)
@@ -59,21 +104,43 @@ void setup() {
 #endif
 #endif
 }
 }
 
 
+
+/**************************************************************************/
+/*!
+    @brief    Standard Arduino LOOP method - using with TaskScheduler there 
+              should be nothing here but ts.execute()
+    @param    none
+    @returns  none
+*/
+/**************************************************************************/
 void loop() {
 void loop() {
   ts.execute();
   ts.execute();
 }
 }
 
 
 
 
+/**************************************************************************/
+/*!
+    @brief    Callback method of task1 - explain
+    @param    none
+    @returns  none
+*/
+/**************************************************************************/
 void task1Callback() {
 void task1Callback() {
-_PP(millis());
-_PL(": task1Callback()");
-
+_PM("task1Callback()");
+//  task code
 }
 }
 
 
-void task2Callback() {
-_PP(millis());
-_PL(": task2Callb()");
 
 
+/**************************************************************************/
+/*!
+    @brief    Callback method of task2 - explain
+    @param    none
+    @returns  none
+*/
+/**************************************************************************/
+void task2Callback() {
+_PM("task2Callback()");
+//  task code
 }
 }
 
 
 
 

+ 6 - 1
keywords.txt

@@ -49,6 +49,7 @@ getNextTask	KEYWORD2
 getOverrun	KEYWORD2
 getOverrun	KEYWORD2
 getPreviousTask	KEYWORD2
 getPreviousTask	KEYWORD2
 getRunCounter	KEYWORD2
 getRunCounter	KEYWORD2
+getSchedulingOption	KEYWORD2
 getStartDelay	KEYWORD2
 getStartDelay	KEYWORD2
 getStatus	KEYWORD2
 getStatus	KEYWORD2
 getStatusRequest	KEYWORD2
 getStatusRequest	KEYWORD2
@@ -74,6 +75,7 @@ setIterations	KEYWORD2
 setLtsPointer	KEYWORD2
 setLtsPointer	KEYWORD2
 setOnDisable	KEYWORD2
 setOnDisable	KEYWORD2
 setOnEnable	KEYWORD2
 setOnEnable	KEYWORD2
+setSchedulingOption	KEYWORD2
 setSleepMethod	KEYWORD2
 setSleepMethod	KEYWORD2
 setTimeout	KEYWORD2
 setTimeout	KEYWORD2
 setWaiting	KEYWORD2
 setWaiting	KEYWORD2
@@ -105,6 +107,7 @@ _TASK_TIMEOUT	LITERAL1
 _TASK_WDT_IDS	LITERAL1
 _TASK_WDT_IDS	LITERAL1
 _TASK_EXPOSE_CHAIN	LITERAL1
 _TASK_EXPOSE_CHAIN	LITERAL1
 _TASK_DEFINE_MILLIS	LITERAL1
 _TASK_DEFINE_MILLIS	LITERAL1
+_TASK_SCHEDULING_OPTIONS	LITERAL1
 SleepCallback	LITERAL1
 SleepCallback	LITERAL1
 TASK_FOREVER	LITERAL1
 TASK_FOREVER	LITERAL1
 TASK_HOUR	LITERAL1
 TASK_HOUR	LITERAL1
@@ -117,7 +120,9 @@ TASK_SECOND	LITERAL1
 TaskCallback	LITERAL1
 TaskCallback	LITERAL1
 TaskOnDisable	LITERAL1
 TaskOnDisable	LITERAL1
 TaskOnEnable	LITERAL1
 TaskOnEnable	LITERAL1
-
+TASK_SCHEDULE	LITERAL1
+TASK_SCHEDULE_NC	LITERAL1
+TASK_INTERVAL	LITERAL1
 
 
 #######################################
 #######################################
 
 

+ 1 - 1
library.json

@@ -16,7 +16,7 @@
       "maintainer": true
       "maintainer": true
     }
     }
   ],
   ],
-  "version": "3.1.6",
+  "version": "3.2.0",
   "frameworks": "arduino",
   "frameworks": "arduino",
   "platforms": "*"
   "platforms": "*"
 }
 }

+ 1 - 1
library.properties

@@ -1,5 +1,5 @@
 name=TaskScheduler
 name=TaskScheduler
-version=3.1.6
+version=3.2.0
 author=Anatoli Arkhipenko <arkhipenko@hotmail.com>
 author=Anatoli Arkhipenko <arkhipenko@hotmail.com>
 maintainer=Anatoli Arkhipenko <arkhipenko@hotmail.com>
 maintainer=Anatoli Arkhipenko <arkhipenko@hotmail.com>
 sentence=Cooperative multitasking for Arduino, ESPx, STM32 and other microcontrollers.
 sentence=Cooperative multitasking for Arduino, ESPx, STM32 and other microcontrollers.

+ 45 - 9
src/TaskScheduler.h

@@ -173,6 +173,12 @@
 //
 //
 // v3.1.6:
 // v3.1.6:
 //    2020-05-12 - bug fix: deleteTask and addTask should check task ownership first (Issue #97)
 //    2020-05-12 - bug fix: deleteTask and addTask should check task ownership first (Issue #97)
+//
+// v3.1.7:
+//    2020-07-07 - warning fix: unused parameter 'aRecursive' (Issue #99)
+//
+// v3.2.0:
+//    2020-08-16 - feature: scheduling options
 
 
 
 
 #include <Arduino.h>
 #include <Arduino.h>
@@ -401,6 +407,10 @@ void Task::reset() {
     iScheduler = NULL;
     iScheduler = NULL;
     iRunCounter = 0;
     iRunCounter = 0;
 
 
+#ifdef _TASK_SCHEDULING_OPTIONS
+    iOption = TASK_SCHEDULE;
+#endif  // _TASK_SCHEDULING_OPTIONS
+
 #ifdef _TASK_TIMECRITICAL
 #ifdef _TASK_TIMECRITICAL
     iOverrun = 0;
     iOverrun = 0;
     iStartDelay = 0;
     iStartDelay = 0;
@@ -786,7 +796,11 @@ void Scheduler::deleteTask(Task& aTask) {
  * task remaining active is an error processing task
  * task remaining active is an error processing task
  * @param aRecursive - if true, tasks of the higher priority chains are disabled as well recursively
  * @param aRecursive - if true, tasks of the higher priority chains are disabled as well recursively
  */
  */
+#ifdef _TASK_PRIORITY
 void Scheduler::disableAll(bool aRecursive) {
 void Scheduler::disableAll(bool aRecursive) {
+#else
+void Scheduler::disableAll() {
+#endif
     Task    *current = iFirst;
     Task    *current = iFirst;
     while (current) {
     while (current) {
         current->disable();
         current->disable();
@@ -802,7 +816,11 @@ void Scheduler::disableAll(bool aRecursive) {
 /** Enables all the tasks in the execution chain
 /** Enables all the tasks in the execution chain
  * @param aRecursive - if true, tasks of the higher priority chains are enabled as well recursively
  * @param aRecursive - if true, tasks of the higher priority chains are enabled as well recursively
  */
  */
- void Scheduler::enableAll(bool aRecursive) {
+#ifdef _TASK_PRIORITY
+void Scheduler::enableAll(bool aRecursive) {
+#else
+void Scheduler::enableAll() {
+#endif    
     Task    *current = iFirst;
     Task    *current = iFirst;
     while (current) {
     while (current) {
         current->enable();
         current->enable();
@@ -835,19 +853,15 @@ void Scheduler::setHighPriorityScheduler(Scheduler* aScheduler) {
 #ifdef _TASK_SLEEP_ON_IDLE_RUN
 #ifdef _TASK_SLEEP_ON_IDLE_RUN
 void Scheduler::allowSleep(bool aState) {
 void Scheduler::allowSleep(bool aState) {
     iAllowSleep = aState;
     iAllowSleep = aState;
-
-#ifdef ARDUINO_ARCH_ESP8266
-    wifi_set_sleep_type( iAllowSleep ? LIGHT_SLEEP_T : NONE_SLEEP_T );
-#endif  // ARDUINO_ARCH_ESP8266
-
-#ifdef ARDUINO_ARCH_ESP32
-    // TO-DO; find a suitable replacement for ESP32 if possible.
-#endif  // ARDUINO_ARCH_ESP32
 }
 }
 #endif  // _TASK_SLEEP_ON_IDLE_RUN
 #endif  // _TASK_SLEEP_ON_IDLE_RUN
 
 
 
 
+#ifdef _TASK_PRIORITY
 void Scheduler::startNow( bool aRecursive ) {
 void Scheduler::startNow( bool aRecursive ) {
+#else
+void Scheduler::startNow() {
+#endif
     unsigned long t = _TASK_TIME_FUNCTION();
     unsigned long t = _TASK_TIME_FUNCTION();
 
 
     iCurrent = iFirst;
     iCurrent = iFirst;
@@ -1011,7 +1025,29 @@ bool Scheduler::execute() {
 
 
                 if ( iCurrent->iIterations > 0 ) iCurrent->iIterations--;  // do not decrement (-1) being a signal of never-ending task
                 if ( iCurrent->iIterations > 0 ) iCurrent->iIterations--;  // do not decrement (-1) being a signal of never-ending task
                 iCurrent->iRunCounter++;
                 iCurrent->iRunCounter++;
+#ifdef _TASK_SCHEDULING_OPTIONS
+                switch (iCurrent->iOption) {
+                  case TASK_INTERVAL:
+                    iCurrent->iPreviousMillis = m;
+                    break;
+                    
+                  case TASK_SCHEDULE_NC:
+                    iCurrent->iPreviousMillis += iCurrent->iDelay; 
+                    {
+                        long ov = (long) ( iCurrent->iPreviousMillis + i - m );
+                        if ( ov < 0 ) {
+                            long ii = i == 0 ? 1 : i;
+                            iCurrent->iPreviousMillis += ((m - iCurrent->iPreviousMillis) / ii) * ii;
+                        }
+                    }
+                    break;
+                    
+                  default:
+                    iCurrent->iPreviousMillis += iCurrent->iDelay;
+                }
+#else
                 iCurrent->iPreviousMillis += iCurrent->iDelay;
                 iCurrent->iPreviousMillis += iCurrent->iDelay;
+#endif  // _TASK_SCHEDULING_OPTIONS
 
 
 #ifdef _TASK_TIMECRITICAL
 #ifdef _TASK_TIMECRITICAL
     // Updated_previous+current interval should put us into the future, so iOverrun should be positive or zero.
     // Updated_previous+current interval should put us into the future, so iOverrun should be positive or zero.

+ 35 - 15
src/TaskSchedulerDeclarations.h

@@ -11,23 +11,28 @@
 // The following "defines" control library functionality at compile time,
 // The following "defines" control library functionality at compile time,
 // and should be used in the main sketch depending on the functionality required
 // and should be used in the main sketch depending on the functionality required
 //
 //
-// #define _TASK_TIMECRITICAL      // Enable monitoring scheduling overruns
-// #define _TASK_SLEEP_ON_IDLE_RUN // Enable 1 ms SLEEP_IDLE powerdowns between runs if no callback methods were invoked during the pass
-// #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_PRIORITY          // Support for layered scheduling priority
-// #define _TASK_MICRO_RES         // Support for microsecond resolution
-// #define _TASK_STD_FUNCTION      // Support for std::function (ESP8266 ONLY)
-// #define _TASK_DEBUG             // Make all methods and variables public for debug purposes
-// #define _TASK_INLINE            // Make all methods "inline" - needed to support some multi-tab, multi-file implementations
-// #define _TASK_TIMEOUT           // Support for overall task timeout
-// #define _TASK_OO_CALLBACKS      // Support for callbacks via inheritance
-// #define _TASK_DEFINE_MILLIS     // Force forward declaration of millis() and micros() "C" style
-// #define _TASK_EXPOSE_CHAIN      // Methods to access tasks in the task chain
+// #define _TASK_TIMECRITICAL           // Enable monitoring scheduling overruns
+// #define _TASK_SLEEP_ON_IDLE_RUN      // Enable 1 ms SLEEP_IDLE powerdowns between runs if no callback methods were invoked during the pass
+// #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_PRIORITY               // Support for layered scheduling priority
+// #define _TASK_MICRO_RES              // Support for microsecond resolution
+// #define _TASK_STD_FUNCTION           // Support for std::function (ESP8266 ONLY)
+// #define _TASK_DEBUG                  // Make all methods and variables public for debug purposes
+// #define _TASK_INLINE                 // Make all methods "inline" - needed to support some multi-tab, multi-file implementations
+// #define _TASK_TIMEOUT                // Support for overall task timeout
+// #define _TASK_OO_CALLBACKS           // Support for callbacks via inheritance
+// #define _TASK_DEFINE_MILLIS          // Force forward declaration of millis() and micros() "C" style
+// #define _TASK_EXPOSE_CHAIN           // Methods to access tasks in the task chain
+// #define _TASK_SCHEDULING_OPTIONS     // Support for multiple scheduling options
 
 
 class Scheduler;
 class Scheduler;
 
 
+#define TASK_SCHEDULE       0   // default
+#define TASK_SCHEDULE_NC    1   // schedule + no catch-ups (always in the future)
+#define TASK_INTERVAL       2   // interval (always in the future)
+
 #ifdef _TASK_DEBUG
 #ifdef _TASK_DEBUG
     #define _TASK_SCOPE  public
     #define _TASK_SCOPE  public
 #else
 #else
@@ -170,6 +175,11 @@ class Task {
     INLINE bool disable();
     INLINE bool disable();
     INLINE bool isEnabled();
     INLINE bool isEnabled();
 
 
+#ifdef _TASK_SCHEDULING_OPTIONS
+    INLINE unsigned int getSchedulingOption() { return iOption; }
+    INLINE void setSchedulingOption(unsigned int aOption) {  iOption = aOption; }
+#endif  //_TASK_SCHEDULING_OPTIONS
+
 #ifdef _TASK_OO_CALLBACKS
 #ifdef _TASK_OO_CALLBACKS
     INLINE void set(unsigned long aInterval, long aIterations);
     INLINE void set(unsigned long aInterval, long aIterations);
 #else
 #else
@@ -234,6 +244,10 @@ class Task {
     volatile unsigned long    iDelay;                // actual delay until next execution (usually equal iInterval)
     volatile unsigned long    iDelay;                // actual delay until next execution (usually equal iInterval)
     volatile unsigned long    iPreviousMillis;       // previous invocation time (millis).  Next invocation = iPreviousMillis + iInterval.  Delayed tasks will "catch up"
     volatile unsigned long    iPreviousMillis;       // previous invocation time (millis).  Next invocation = iPreviousMillis + iInterval.  Delayed tasks will "catch up"
 
 
+#ifdef _TASK_SCHEDULING_OPTIONS
+    unsigned int              iOption;               // scheduling option
+#endif  // _TASK_SCHEDULING_OPTIONS
+
 #ifdef _TASK_TIMECRITICAL
 #ifdef _TASK_TIMECRITICAL
     volatile long             iOverrun;              // negative if task is "catching up" to it's schedule (next invocation time is already in the past)
     volatile long             iOverrun;              // negative if task is "catching up" to it's schedule (next invocation time is already in the past)
     volatile long             iStartDelay;           // actual execution of the task's callback method was delayed by this number of millis
     volatile long             iStartDelay;           // actual execution of the task's callback method was delayed by this number of millis
@@ -280,10 +294,16 @@ class Scheduler {
     INLINE void init();
     INLINE void init();
     INLINE void addTask(Task& aTask);
     INLINE void addTask(Task& aTask);
     INLINE void deleteTask(Task& aTask);
     INLINE void deleteTask(Task& aTask);
+#ifdef _TASK_PRIORITY
     INLINE void disableAll(bool aRecursive = true);
     INLINE void disableAll(bool aRecursive = true);
     INLINE void enableAll(bool aRecursive = true);
     INLINE void enableAll(bool aRecursive = true);
-    INLINE bool execute();                              // Returns true if none of the tasks' callback methods was invoked (true = idle run)
     INLINE void startNow(bool aRecursive = true);       // reset ALL active tasks to immediate execution NOW.
     INLINE void startNow(bool aRecursive = true);       // reset ALL active tasks to immediate execution NOW.
+#else
+    INLINE void disableAll();
+    INLINE void enableAll();
+    INLINE void startNow();                             // reset ALL active tasks to immediate execution NOW.
+#endif
+    INLINE bool execute();                              // Returns true if none of the tasks' callback methods was invoked (true = idle run)
     INLINE Task& currentTask() ;                        // DEPRICATED
     INLINE Task& currentTask() ;                        // DEPRICATED
     INLINE Task* getCurrentTask() ;                     // Returns pointer to the currently active task
     INLINE Task* getCurrentTask() ;                     // Returns pointer to the currently active task
     INLINE long timeUntilNextIteration(Task& aTask);    // return number of ms until next iteration of a given Task
     INLINE long timeUntilNextIteration(Task& aTask);    // return number of ms until next iteration of a given Task

+ 0 - 72
src/TaskSchedulerSleepMethods.h

@@ -21,78 +21,6 @@ void SleepMethod( unsigned long aDuration ) {
 }
 }
 // ARDUINO_ARCH_AVR
 // ARDUINO_ARCH_AVR
 
 
-
-#elif defined( CORE_TEENSY )
-void SleepMethod( unsigned long aDuration ) {
-  asm("wfi");
-}
-//CORE_TEENSY
-
-
-#elif defined( ARDUINO_ARCH_ESP8266 )
-
-#ifndef _TASK_ESP8266_DLY_THRESHOLD
-#define _TASK_ESP8266_DLY_THRESHOLD 200L
-#endif
-extern "C" {
-#include "user_interface.h"
-}
-
-void SleepMethod( unsigned long aDuration ) {
-// to do: find suitable sleep function for esp8266
-      if ( aDuration < _TASK_ESP8266_DLY_THRESHOLD) delay(1);   // ESP8266 implementation of delay() uses timers and yield
-}
-// ARDUINO_ARCH_ESP8266
-
-
-#elif defined( ARDUINO_ARCH_ESP32 )
-
-#include <esp_sleep.h>
-
-#ifndef _TASK_ESP32_DLY_THRESHOLD
-#define _TASK_ESP32_DLY_THRESHOLD 200L
-#endif
-extern unsigned long tStart, tFinish;
-const unsigned long tRem = 1000-_TASK_ESP32_DLY_THRESHOLD;
-
-void SleepMethod( unsigned long aDuration ) {
-    if ( aDuration < tRem ) {
-        esp_sleep_enable_timer_wakeup((uint64_t) (1000 - aDuration));
-        esp_light_sleep_start();
-    }
-}
-// ARDUINO_ARCH_ESP32
-
-
-#elif defined( ARDUINO_ARCH_STM32F1 )
-
-#include <libmaple/pwr.h>
-#include <libmaple/scb.h>
-
-void SleepMethod( unsigned long aDuration ) {
-	  // Now go into stop mode, wake up on interrupt.
-	  // Systick interrupt will run every 1 milliseconds.
-	  asm("    wfi");
-}
-// ARDUINO_ARCH_STM32
-
-
-#elif defined( ENERGIA_ARCH_MSP432 )
-
-void SleepMethod( unsigned long aDuration ) {
-    delay(1);
-}
-// ENERGIA_ARCH_MSP432
-
-
-#elif defined( ENERGIA_ARCH_MSP430 )
-
-void SleepMethod( unsigned long aDuration ) {
-    sleep(1);
-}
-// ENERGIA_ARCH_MSP430
-
-
 #else
 #else
 void SleepMethod( unsigned long aDuration ) {
 void SleepMethod( unsigned long aDuration ) {
 }
 }