Bladeren bron

v3.6.2 - nRF52 Adafruit workaround using namespace

Anatoli Arkhipenko 3 jaren geleden
bovenliggende
commit
72e68028e6

+ 2 - 1
README.md

@@ -1,6 +1,6 @@
 # Task Scheduler
 ### Cooperative multitasking for Arduino, ESPx, STM32 and other microcontrollers
-#### Version 3.6.1: 2022-06-28 [Latest updates](https://github.com/arkhipenko/TaskScheduler/wiki/Latest-Updates)
+#### Version 3.6.2: 2022-10-04 [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)
 
@@ -47,6 +47,7 @@ Scheduling overhead: between `15` and `18` microseconds per scheduling pass (Ard
 * ESP32
 * Teensy (tested on Teensy 3.5)
 * nRF52 (tested on nRF52832)
+* nRF52 Adafruit Core (tested on nRF52840 with v3.6.2 workround)
 * STM32 (tested on Mini USB STM32F103RCBT6 ARM Cortex-M3 leaflabs Leaf maple mini module F)
 * MSP430 and MSP432 boards
 * Raspberry Pi (requires external `Arduino.h` and `millis()` implementation)

+ 293 - 0
examples/Scheduler_example00_Blink_Adafruit/Scheduler_example00_Blink_Adafruit.ino

@@ -0,0 +1,293 @@
+/*
+   Every example set must have a LED blink example
+   For this one the idea is to have as many ways to blink the LED
+   as I can think of. So, here we go.
+
+   Tested on:
+   - Bluefruit nRF52840
+*/
+
+
+// #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
+#include <TScheduler.hpp>
+
+// Debug and Test options
+//#define _DEBUG_
+//#define _TEST_
+
+#ifdef _DEBUG_
+#define _PP(a) Serial.print(a);
+#define _PL(a) Serial.println(a);
+#else
+#define _PP(a)
+#define _PL(a)
+#endif
+
+// LED_BUILTIN  13
+#if defined( ARDUINO_ARCH_ESP32 )
+#define LED_BUILTIN  23 // esp32 dev2 kit does not have LED
+#endif
+
+// Scheduler
+TS::Scheduler ts;
+
+/*
+   Approach 1: LED is driven by the boolean variable; false = OFF, true = ON
+*/
+#define PERIOD1 500
+#define DURATION 10000
+void blink1CB();
+Task tBlink1 ( PERIOD1 * TASK_MILLISECOND, DURATION / PERIOD1, &blink1CB, &ts, true );
+
+/*
+   Approac 2: two callback methods: one turns ON, another turns OFF
+*/
+#define PERIOD2 400
+void blink2CB_ON();
+void blink2CB_OFF();
+Task tBlink2 ( PERIOD2 * TASK_MILLISECOND, DURATION / PERIOD2, &blink2CB_ON, &ts, false );
+
+/*
+   Approach 3: Use RunCounter
+*/
+#define PERIOD3 300
+void blink3CB();
+Task tBlink3 (PERIOD3 * TASK_MILLISECOND, DURATION / PERIOD3, &blink3CB, &ts, false);
+
+/*
+   Approach 4: Use status request objects to pass control from one task to the other
+*/
+#define PERIOD4 200
+bool blink41OE();
+void blink41();
+void blink42();
+void blink42OD();
+Task tBlink4On  ( PERIOD4 * TASK_MILLISECOND, TASK_ONCE, blink41, &ts, false, &blink41OE );
+Task tBlink4Off ( PERIOD4 * TASK_MILLISECOND, TASK_ONCE, blink42, &ts, false, NULL, &blink42OD );
+
+
+/*
+   Approach 5: Two interleaving tasks
+*/
+#define PERIOD5 600
+bool blink51OE();
+void blink51();
+void blink52();
+void blink52OD();
+Task tBlink5On  ( 600 * TASK_MILLISECOND, DURATION / PERIOD5, &blink51, &ts, false, &blink51OE );
+Task tBlink5Off ( 600 * TASK_MILLISECOND, DURATION / PERIOD5, &blink52, &ts, false, NULL, &blink52OD );
+
+
+/*
+   Approach 6: RunCounter-based with random intervals
+*/
+#define PERIOD6 300
+void blink6CB();
+bool blink6OE();
+void blink6OD();
+Task tBlink6 ( PERIOD6 * TASK_MILLISECOND, DURATION / PERIOD6, &blink6CB, &ts, false, &blink6OE, &blink6OD );
+
+void setup() {
+  // put your setup code here, to run once:
+#if defined(_DEBUG_) || defined(_TEST_)
+  Serial.begin(115200);
+  delay(TASK_SECOND);
+  _PL("TaskScheduler Blink example");
+  _PL("Blinking for 10 seconds using various techniques\n");
+  delay(2 * TASK_SECOND);
+#endif
+  pinMode(LED_BUILTIN, OUTPUT);
+}
+
+void loop() {
+  ts.execute();
+}
+
+inline void LEDOn() {
+  digitalWrite( LED_BUILTIN, HIGH );
+}
+
+inline void LEDOff() {
+  digitalWrite( LED_BUILTIN, LOW );
+}
+
+// === 1 =======================================
+bool LED_state = false;
+void blink1CB() {
+  if ( tBlink1.isFirstIteration() ) {
+    _PP(millis());
+    _PL(": Blink1 - simple flag driven");
+    LED_state = false;
+  }
+
+  if ( LED_state ) {
+    LEDOff();
+    LED_state = false;
+  }
+  else {
+    LEDOn();
+    LED_state = true;
+  }
+
+  if ( tBlink1.isLastIteration() ) {
+    tBlink2.restartDelayed( 2 * TASK_SECOND );
+    LEDOff();
+  }
+}
+
+
+// === 2 ======================================
+void blink2CB_ON() {
+  if ( tBlink2.isFirstIteration() ) {
+    _PP(millis());
+    _PL(": Blink2 - 2 callback methods");
+  }
+
+  LEDOn();
+  tBlink2.setCallback( &blink2CB_OFF );
+
+  if ( tBlink2.isLastIteration() ) {
+    tBlink3.restartDelayed( 2 * TASK_SECOND );
+    LEDOff();
+  }
+}
+
+
+void blink2CB_OFF() {
+
+  LEDOff();
+  tBlink2.setCallback( &blink2CB_ON );
+
+  if ( tBlink2.isLastIteration() ) {
+    tBlink3.restartDelayed( 2 * TASK_SECOND );
+    LEDOff();
+  }
+}
+
+
+// === 3 =====================================
+void blink3CB() {
+  if ( tBlink3.isFirstIteration() ) {
+    _PP(millis());
+    _PL(": Blink3 - Run Counter driven");
+  }
+
+  if ( tBlink3.getRunCounter() & 1 ) {
+    LEDOn();
+  }
+  else {
+    LEDOff();
+  }
+
+  if ( tBlink3.isLastIteration() ) {
+    tBlink4On.setOnEnable( &blink41OE );
+    tBlink4On.restartDelayed( 2 * TASK_SECOND );
+    LEDOff();
+  }
+}
+
+
+// === 4 =============================================
+int counter = 0;
+bool blink41OE() {
+  _PP(millis());
+  _PL(": Blink4 - Internal status request based");
+  counter = 0;
+  tBlink4On.setOnEnable( NULL );
+  return true;
+}
+
+void blink41() {
+  //  _PP(millis());
+  //  _PL(": blink41");
+  LEDOn();
+  StatusRequest* r = tBlink4On.getInternalStatusRequest();
+  tBlink4Off.waitForDelayed( r );
+  counter++;
+}
+
+void blink42() {
+  //  _PP(millis());
+  //  _PL(": blink42");
+  LEDOff();
+  StatusRequest* r = tBlink4Off.getInternalStatusRequest();
+  tBlink4On.waitForDelayed( r );
+  counter++;
+}
+
+
+void blink42OD() {
+  if ( counter >= DURATION / PERIOD4 ) {
+    tBlink4On.disable();
+    tBlink4Off.disable();
+
+    tBlink5On.setOnEnable( &blink51OE );
+    tBlink5On.restartDelayed( 2 * TASK_SECOND );
+    tBlink5Off.restartDelayed( 2 * TASK_SECOND + PERIOD5 / 2 );
+    LEDOff();
+  }
+}
+
+
+// === 5 ==========================================
+bool blink51OE() {
+  _PP(millis());
+  _PL(": Blink5 - Two interleaving tasks");
+  tBlink5On.setOnEnable( NULL );
+  return true;
+}
+void blink51() {
+  //  _PP(millis());
+  //  _PL(": blink51");
+  LEDOn();
+}
+void blink52() {
+  //  _PP(millis());
+  //  _PL(": blink52");
+  LEDOff();
+}
+void blink52OD() {
+  tBlink6.restartDelayed( 2 * TASK_SECOND );
+  LEDOff();
+}
+
+
+// === 6 ============================================
+long interval6 = 0;
+bool blink6OE() {
+  _PP(millis());
+  _PP(": Blink6 - RunCounter + Random ON interval = ");
+  interval6 = random( 100, 901 );
+  tBlink6.setInterval( interval6 );
+  _PL( interval6 );
+  tBlink6.delay( 2 * TASK_SECOND );
+
+  return true;
+}
+
+void blink6CB() {
+  if ( tBlink6.getRunCounter() & 1 ) {
+    LEDOn();
+    tBlink6.setInterval( interval6 );
+  }
+  else {
+    LEDOff();
+    tBlink6.setInterval( TASK_SECOND - interval6 );
+  }
+}
+
+void blink6OD() {
+  tBlink1.restartDelayed( 2 * TASK_SECOND );
+  LEDOff();
+}

+ 1 - 0
keywords.txt

@@ -9,6 +9,7 @@
 Scheduler	KEYWORD1
 StatusRequest	KEYWORD1
 Task	KEYWORD1
+TS	KEYWORD1
 
 #######################################
 # Methods and Functions (KEYWORD2)

+ 1 - 1
library.json

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

+ 1 - 1
library.properties

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

+ 22 - 0
src/TScheduler.hpp

@@ -0,0 +1,22 @@
+// Cooperative multitasking library for Arduino
+// Copyright (c) 2015-2019 Anatoli Arkhipenko
+
+/*
+    This is a namespace wrapper to avoid collision with frameworks having their
+    own class named Scheduler (i.e. nordicnrf52)
+    include it instead of <TaskScheduler.h> into your sketch and use Class name wrapper - 'TaskScheduler'
+    i.e. 
+    TaskScheduler ts;
+*/
+
+#pragma once
+#include <Arduino.h>
+
+namespace TS{
+#include "TaskScheduler.h"
+}
+
+using TaskScheduler = TS::Scheduler;
+using SleepCallback = TS::SleepCallback;
+using Task = TS::Task;
+using StatusRequest = TS::StatusRequest;

+ 22 - 0
src/TSchedulerDeclarations.hpp

@@ -0,0 +1,22 @@
+// Cooperative multitasking library for Arduino
+// Copyright (c) 2015-2019 Anatoli Arkhipenko
+
+/*
+    This is a namespace wrapper to avoid collision with frameworks having their
+    own class named Scheduler (i.e. nordicnrf52)
+    include it instead of <TaskSchedulerDeclarations.h> into your sketch and
+    use Class name wrapper - 'TaskScheduler'
+    i.e. 
+    TaskScheduler ts;
+*/
+
+#pragma once
+
+namespace TS{
+#include "TaskSchedulerDeclarations.h"
+}
+
+using TaskScheduler = TS::Scheduler;
+using SleepCallback = TS::SleepCallback;
+using Task = TS::Task;
+using StatusRequest = TS::StatusRequest;

+ 12 - 3
src/TaskScheduler.h

@@ -212,6 +212,11 @@ v3.6.0:
 v3.6.1:
    2022-06-28 - bug: Internal Status Request of the canceled and aborted tasks complete with respective error code
               - feature: TASK_SR_ABORT code causes Tasks waiting on this Status Request to be aborted as well
+              
+v3.6.2:
+   2022-10-04 - feature: added TScheduler.hpp and TSchedulerDeclarations.hpp - a workaround for conflicting declarations (e.g., nRF52840 using Adafruit Core).
+                using namespace TS (credit: https://github.com/vortigont)
+   
 
 */
 
@@ -644,6 +649,10 @@ bool Task::enable() {
 
         iRunCounter = 0;
         iStatus.canceled = false;
+        
+#ifdef _TASK_STATUS_REQUEST
+        iMyStatusRequest.setWaiting();
+#endif // _TASK_STATUS_REQUEST]
 
 #ifdef _TASK_OO_CALLBACKS
         if ( !iStatus.inonenable ) {
@@ -674,11 +683,11 @@ bool Task::enable() {
         resetTimeout();
 #endif // _TASK_TIMEOUT
 
-        if ( iStatus.enabled ) {
 #ifdef _TASK_STATUS_REQUEST
-            iMyStatusRequest.setWaiting();
-#endif // _TASK_STATUS_REQUEST
+        if ( !iStatus.enabled ) {
+            iMyStatusRequest.signalComplete();
         }
+#endif // _TASK_STATUS_REQUEST
 
 #ifdef _TASK_THREAD_SAFE
         iMutex--;

+ 0 - 3
src/TaskSchedulerDeclarations.h

@@ -80,7 +80,6 @@ class Scheduler;
 
 #endif  // _TASK_MICRO_RES
 
-
 #ifdef _TASK_STATUS_REQUEST
 
 #define TASK_SR_OK          0
@@ -92,8 +91,6 @@ class Scheduler;
 #define _TASK_SR_NODELAY    1
 #define _TASK_SR_DELAY      2
 
-class Scheduler;
-
 class StatusRequest {
   friend class Scheduler;
   public: