Explorar o código

Merge branch 'testing'

Anatoli Arkhipenko %!s(int64=4) %!d(string=hai) anos
pai
achega
0959becb57
Modificáronse 6 ficheiros con 69 adicións e 13 borrados
  1. 3 2
      README.md
  2. 3 0
      keywords.txt
  3. 1 1
      library.json
  4. 1 1
      library.properties
  5. 41 6
      src/TaskScheduler.h
  6. 20 3
      src/TaskSchedulerDeclarations.h

+ 3 - 2
README.md

@@ -1,6 +1,6 @@
 # Task Scheduler
 # Task Scheduler
 ### Cooperative multitasking for Arduino, ESPx, STM32 and other microcontrollers
 ### Cooperative multitasking for Arduino, ESPx, STM32 and other microcontrollers
-#### Version 3.2.2: 2020-12-14 [Latest updates](https://github.com/arkhipenko/TaskScheduler/wiki/Latest-Updates)
+#### Version 3.3.0: 2021-05-12 [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)[![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)
 [![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)
 
 
@@ -28,7 +28,7 @@ _“Everybody who learns concurrency and thinks they understand it, ends up find
 7. Support for task IDs and Control Points for error handling and watchdog timer
 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)
 8. Support for Local Task Storage pointer (allowing use of same callback code for multiple tasks)
 9. Support for layered task prioritization
 9. Support for layered task prioritization
-10. Support for `std::functions` (tested on `ESPx` only)
+10. Support for `std::functions` (tested on `ESPx` and `STM32` only)
 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
@@ -46,6 +46,7 @@ Scheduling overhead: between `15` and `18` microseconds per scheduling pass (Ard
 * Teensy (tested on Teensy 3.5)
 * Teensy (tested on Teensy 3.5)
 * STM32F1 (tested on Mini USB STM32F103RCBT6 ARM Cortex-M3 leaflabs Leaf maple mini module F)
 * STM32F1 (tested on Mini USB STM32F103RCBT6 ARM Cortex-M3 leaflabs Leaf maple mini module F)
 * MSP430 and MSP432 boards
 * MSP430 and MSP432 boards
+* Raspberry Pi (requires external `Arduino.h` and `millis()` implementation)
 
 
 
 
 
 

+ 3 - 0
keywords.txt

@@ -126,6 +126,9 @@ TaskOnEnable	LITERAL1
 TASK_SCHEDULE	LITERAL1
 TASK_SCHEDULE	LITERAL1
 TASK_SCHEDULE_NC	LITERAL1
 TASK_SCHEDULE_NC	LITERAL1
 TASK_INTERVAL	LITERAL1
 TASK_INTERVAL	LITERAL1
+TASK_SR_OK	LITERAL1
+TASK_SR_ERROR	LITERAL1
+TASK_SR_TIMEOUT	LITERAL1
 
 
 #######################################
 #######################################
 
 

+ 1 - 1
library.json

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

+ 1 - 1
library.properties

@@ -1,5 +1,5 @@
 name=TaskScheduler
 name=TaskScheduler
-version=3.2.2
+version=3.3.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.

+ 41 - 6
src/TaskScheduler.h

@@ -189,6 +189,14 @@
 //                          processing in the onDisable method.
 //                          processing in the onDisable method.
 //                 feature: Task.cancelled() method - indicates that task was disabled with a cancel() method.
 //                 feature: Task.cancelled() method - indicates that task was disabled with a cancel() method.
 //
 //
+// v3.2.3:
+//    2021-01-01 - feature: discontinued use of 'register' keyword. Depricated in C++ 11 
+//                 feature: add STM32 as a platform supporting _TASK_STD_FUNCTION. (PR #105)
+//
+// v3.3.0:
+//    2021-05-11 - feature: Timeout() methods for StatusRequest objects 
+
+
 
 
 #include <Arduino.h>
 #include <Arduino.h>
 
 
@@ -244,7 +252,7 @@ extern "C" {
 #endif  // _TASK_SLEEP_ON_IDLE_RUN
 #endif  // _TASK_SLEEP_ON_IDLE_RUN
 
 
 
 
-#if !defined (ARDUINO_ARCH_ESP8266) && !defined (ARDUINO_ARCH_ESP32)
+#if !defined (ARDUINO_ARCH_ESP8266) && !defined (ARDUINO_ARCH_ESP32) && !defined (ARDUINO_ARCH_STM32)
 #ifdef _TASK_STD_FUNCTION
 #ifdef _TASK_STD_FUNCTION
     #error Support for std::function only for ESP8266 or ESP32 architecture
     #error Support for std::function only for ESP8266 or ESP32 architecture
 #undef _TASK_STD_FUNCTION
 #undef _TASK_STD_FUNCTION
@@ -327,7 +335,14 @@ StatusRequest::StatusRequest()
     iStatus = 0;
     iStatus = 0;
 }
 }
 
 
-void StatusRequest::setWaiting(unsigned int aCount) { iCount = aCount; iStatus = 0; }
+void StatusRequest::setWaiting(unsigned int aCount) { 
+  iCount = aCount; 
+  iStatus = 0; 
+#ifdef _TASK_TIMEOUT
+  iStarttime = _TASK_TIME_FUNCTION();
+#endif  //  #ifdef _TASK_TIMEOUT
+}
+
 bool StatusRequest::pending() { return (iCount != 0); }
 bool StatusRequest::pending() { return (iCount != 0); }
 bool StatusRequest::completed() { return (iCount == 0); }
 bool StatusRequest::completed() { return (iCount == 0); }
 int StatusRequest::getStatus() { return iStatus; }
 int StatusRequest::getStatus() { return iStatus; }
@@ -380,6 +395,19 @@ bool Task::waitForDelayed(StatusRequest* aStatusRequest, unsigned long aInterval
     }
     }
     return false;
     return false;
 }
 }
+
+#ifdef _TASK_TIMEOUT
+void StatusRequest::resetTimeout() {
+    iStarttime = _TASK_TIME_FUNCTION();
+}
+
+long StatusRequest::untilTimeout() {
+    if ( iTimeout ) {
+        return ( (long) (iStarttime + iTimeout) - (long) _TASK_TIME_FUNCTION() );
+    }
+    return -1;
+}
+#endif  // _TASK_TIMEOUT
 #endif  // _TASK_STATUS_REQUEST
 #endif  // _TASK_STATUS_REQUEST
 
 
 bool Task::isEnabled() { return iStatus.enabled; }
 bool Task::isEnabled() { return iStatus.enabled; }
@@ -667,6 +695,7 @@ bool Task::disable() {
 void Task::abort() {
 void Task::abort() {
     iStatus.enabled = false;
     iStatus.enabled = false;
     iStatus.inonenable = false;
     iStatus.inonenable = false;
+    iStatus.canceled = true;
 }
 }
 
 
 
 
@@ -978,7 +1007,7 @@ void  Scheduler::setSleepMethod( SleepCallback aCallback ) {
 
 
 bool Scheduler::execute() {
 bool Scheduler::execute() {
     bool     idleRun = true;
     bool     idleRun = true;
-    register unsigned long m, i;  // millis, interval;
+    unsigned long m, i;  // millis, interval;
 
 
 #ifdef _TASK_SLEEP_ON_IDLE_RUN
 #ifdef _TASK_SLEEP_ON_IDLE_RUN
     unsigned long tFinish;
     unsigned long tFinish;
@@ -986,8 +1015,8 @@ bool Scheduler::execute() {
 #endif  // _TASK_SLEEP_ON_IDLE_RUN
 #endif  // _TASK_SLEEP_ON_IDLE_RUN
 
 
 #ifdef _TASK_TIMECRITICAL
 #ifdef _TASK_TIMECRITICAL
-    register unsigned long tPassStart;
-    register unsigned long tTaskStart, tTaskFinish;
+    unsigned long tPassStart;
+    unsigned long tTaskStart, tTaskFinish;
 
 
 #ifdef _TASK_SLEEP_ON_IDLE_RUN
 #ifdef _TASK_SLEEP_ON_IDLE_RUN
     unsigned long tIdleStart = 0;
     unsigned long tIdleStart = 0;
@@ -1048,6 +1077,12 @@ bool Scheduler::execute() {
     // Otherwise, continue with execution as usual.  Tasks waiting to StatusRequest need to be rescheduled according to
     // Otherwise, continue with execution as usual.  Tasks waiting to StatusRequest need to be rescheduled according to
     // how they were placed into waiting state (waitFor or waitForDelayed)
     // how they were placed into waiting state (waitFor or waitForDelayed)
                 if ( iCurrent->iStatus.waiting ) {
                 if ( iCurrent->iStatus.waiting ) {
+#ifdef _TASK_TIMEOUT
+                    StatusRequest *sr = iCurrent->iStatusRequest;
+                    if ( sr->iTimeout && (m - sr->iStarttime > sr->iTimeout) ) {
+                      sr->signalComplete(TASK_SR_TIMEOUT);
+                    }
+#endif // _TASK_TIMEOUT
                     if ( (iCurrent->iStatusRequest)->pending() ) break;
                     if ( (iCurrent->iStatusRequest)->pending() ) break;
                     if (iCurrent->iStatus.waiting == _TASK_SR_NODELAY) {
                     if (iCurrent->iStatus.waiting == _TASK_SR_NODELAY) {
                         iCurrent->iPreviousMillis = m - (iCurrent->iDelay = i);
                         iCurrent->iPreviousMillis = m - (iCurrent->iDelay = i);
@@ -1074,7 +1109,7 @@ bool Scheduler::execute() {
                     {
                     {
                         long ov = (long) ( iCurrent->iPreviousMillis + i - m );
                         long ov = (long) ( iCurrent->iPreviousMillis + i - m );
                         if ( ov < 0 ) {
                         if ( ov < 0 ) {
-                            long ii = i == 0 ? 1 : i;
+                            long ii = i ? i : 1;
                             iCurrent->iPreviousMillis += ((m - iCurrent->iPreviousMillis) / ii) * ii;
                             iCurrent->iPreviousMillis += ((m - iCurrent->iPreviousMillis) / ii) * ii;
                         }
                         }
                     }
                     }

+ 20 - 3
src/TaskSchedulerDeclarations.h

@@ -77,10 +77,17 @@ class Scheduler;
 
 
 #ifdef _TASK_STATUS_REQUEST
 #ifdef _TASK_STATUS_REQUEST
 
 
+#define TASK_SR_OK          0
+#define TASK_SR_ERROR       (-1)
+#define TASK_SR_TIMEOUT     (-99)
+ 
 #define _TASK_SR_NODELAY    1
 #define _TASK_SR_NODELAY    1
 #define _TASK_SR_DELAY      2
 #define _TASK_SR_DELAY      2
 
 
+class Scheduler;
+
 class StatusRequest {
 class StatusRequest {
+  friend class Scheduler;
   public:
   public:
     INLINE StatusRequest();
     INLINE StatusRequest();
     INLINE void setWaiting(unsigned int aCount = 1);
     INLINE void setWaiting(unsigned int aCount = 1);
@@ -90,10 +97,22 @@ class StatusRequest {
     INLINE bool completed();
     INLINE bool completed();
     INLINE int getStatus();
     INLINE int getStatus();
     INLINE int getCount();
     INLINE int getCount();
+    
+#ifdef _TASK_TIMEOUT
+    INLINE void setTimeout(unsigned long aTimeout) { iTimeout = aTimeout; };
+    INLINE unsigned long getTimeout() { return iTimeout; };
+    INLINE void resetTimeout();
+    INLINE long untilTimeout();
+#endif
 
 
   _TASK_SCOPE:
   _TASK_SCOPE:
     unsigned int  iCount;          // number of statuses to wait for. waiting for more that 65000 events seems unreasonable: unsigned int should be sufficient
     unsigned int  iCount;          // number of statuses to wait for. waiting for more that 65000 events seems unreasonable: unsigned int should be sufficient
     int           iStatus;         // status of the last completed request. negative = error;  zero = OK; positive = OK with a specific status
     int           iStatus;         // status of the last completed request. negative = error;  zero = OK; positive = OK with a specific status
+
+#ifdef _TASK_TIMEOUT
+    unsigned long            iTimeout;               // Task overall timeout
+    unsigned long            iStarttime;             // millis at task start time
+#endif // _TASK_TIMEOUT
 };
 };
 #endif  // _TASK_STATUS_REQUEST
 #endif  // _TASK_STATUS_REQUEST
 
 
@@ -125,13 +144,11 @@ typedef struct  {
 #endif
 #endif
 
 
 #ifdef _TASK_TIMEOUT
 #ifdef _TASK_TIMEOUT
-    bool  timeout    : 1;           // indication if task is waiting on the status request
+    bool  timeout    : 1;           // indication if task timed out
 #endif
 #endif
 
 
 } __task_status;
 } __task_status;
 
 
-class Scheduler;
-
 
 
 class Task {
 class Task {
   friend class Scheduler;
   friend class Scheduler;