From f43c43c321c587d5117ef68fac41a7f6a44759d2 Mon Sep 17 00:00:00 2001 From: devyte Date: Tue, 2 Oct 2018 00:07:15 -0300 Subject: [PATCH 1/8] PolledTimeout Class for wrapping millis() loops --- cores/esp8266/PolledTimeout.h | 68 +++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 cores/esp8266/PolledTimeout.h diff --git a/cores/esp8266/PolledTimeout.h b/cores/esp8266/PolledTimeout.h new file mode 100644 index 0000000000..164b398998 --- /dev/null +++ b/cores/esp8266/PolledTimeout.h @@ -0,0 +1,68 @@ +#ifndef __POLLEDTIMING_H__ +#define __POLLEDTIMING_H__ + +namespace esp8266 +{ + +template +class polledTimeout +{ +public: + using timeType = unsigned int; + + polledTimeout(timeType timeout) + : _timeout(timeout), _start(millis()) + {} + + bool expired() + { + if(PeriodicT) + return expiredRetrigger(); + return expiredOneShot(); + } + + operator bool() + { + return expired(); + } + + bool reset() + { + _start = millis(); + } + +protected: + bool checkExpired(timeType t) const + { + return (t - _start) >= _timeout; + } + + bool expiredRetrigger() + { + timeType current = millis(); + if(checkExpired(current)) + { + unsigned int n = (current - _start) / _timeout; //how many _timeouts periods have elapsed, will usually be 1 (current - _start >= _timeout) + _start += n * _timeout; + return true; + } + return false; + } + + bool expiredOneShot() const + { + return checkExpired(millis()); + } + + timeType _timeout; + timeType _start; +}; + + +using polledTimeoutOneShot = polledTimeout; +using polledTimeoutPeriodic = polledTimeout; + + +}//esp8266 + +#endif From 5d0ca403cc76d2eb9162faeecd5b70ecc5535be5 Mon Sep 17 00:00:00 2001 From: devyte Date: Sun, 25 Nov 2018 10:46:55 -0300 Subject: [PATCH 2/8] Add yield policies, improve reset, add host tests --- cores/esp8266/PolledTimeout.h | 64 +++++++++- tests/host/Makefile | 3 +- tests/host/core/test_PolledTimeout.cpp | 163 +++++++++++++++++++++++++ 3 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 tests/host/core/test_PolledTimeout.cpp diff --git a/cores/esp8266/PolledTimeout.h b/cores/esp8266/PolledTimeout.h index 164b398998..4c96ed8301 100644 --- a/cores/esp8266/PolledTimeout.h +++ b/cores/esp8266/PolledTimeout.h @@ -1,14 +1,56 @@ #ifndef __POLLEDTIMING_H__ #define __POLLEDTIMING_H__ + +/* + PolledTimeout.h - Encapsulation of a polled Timeout + + Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + namespace esp8266 { -template +namespace polledTimeoutPolicy +{ + +struct DoNothing +{ + static void execute() {} +}; + +struct YieldOrSkip +{ + static void execute() {delay(0);} +}; + + +} + + + +template class polledTimeout { public: - using timeType = unsigned int; + using timeType = decltype(millis()); polledTimeout(timeType timeout) : _timeout(timeout), _start(millis()) @@ -16,7 +58,8 @@ class polledTimeout bool expired() { - if(PeriodicT) + YieldPolicy::execute(); //in case of DoNothing gets optimized away + if(PeriodicT) //in case of false gets optimized away return expiredRetrigger(); return expiredOneShot(); } @@ -26,9 +69,15 @@ class polledTimeout return expired(); } - bool reset() + void reset(timeType newTimeout) + { + _timeout = newTimeout; + reset(); + } + + void reset() { - _start = millis(); + _start = millis(); } protected: @@ -62,6 +111,11 @@ class polledTimeout using polledTimeoutOneShot = polledTimeout; using polledTimeoutPeriodic = polledTimeout; +/* A timeout that auto-yields when in CONT can be built as follows: + * using polledTimeoutOneShotYield = polledTimeout; + * + * Other policies can be implemented by the user, and the polledTimeout types built as needed as shown above, without modifying this file. + */ }//esp8266 diff --git a/tests/host/Makefile b/tests/host/Makefile index 667fc15336..c83c55fde3 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -107,7 +107,8 @@ TEST_CPP_FILES := \ fs/test_fs.cpp \ core/test_pgmspace.cpp \ core/test_md5builder.cpp \ - core/test_string.cpp + core/test_string.cpp \ + core/test_PolledTimeout.cpp PREINCLUDES := \ -include common/mock.h \ diff --git a/tests/host/core/test_PolledTimeout.cpp b/tests/host/core/test_PolledTimeout.cpp new file mode 100644 index 0000000000..489ca37a92 --- /dev/null +++ b/tests/host/core/test_PolledTimeout.cpp @@ -0,0 +1,163 @@ +#include +#include "PolledTimeout.h" + + +TEST_CASE("OneShot Timeout 3000ms", "[polledTimeout]") +{ + using esp8266::polledTimeoutOneShot; + using timeType = polledTimeoutOneShot::timeType; + timeType before, after; + polledTimeoutOneShot timeout(3000); + + Serial.println("OneShot Timeout 3000ms"); + + + Serial.print("before while 1\n"); + before = millis(); + while(!timeout.expired()) + yield(); + after = millis(); + Serial.print("after while 1\n"); + Serial.printf("delta = %lu\n", (after-before)); + + REQUIRE((after-before) == 3000); + + Serial.print("reset\n"); + timeout.reset(); + + before = millis(); + Serial.print("before while 2\n"); + while(!timeout) + yield(); + after = millis(); + Serial.print("after while 2\n"); + Serial.printf("delta = %lu\n", (after-before)); + + REQUIRE((after-before) == 3000); +} + +TEST_CASE("OneShot Timeout 3000ms reset to 1000ms", "[polledTimeout]") +{ + using esp8266::polledTimeoutOneShot; + using timeType = polledTimeoutOneShot::timeType; + timeType before, after; + polledTimeoutOneShot timeout(3000); + + Serial.println("OneShot Timeout 3000ms"); + + + Serial.print("before while 1\n"); + before = millis(); + while(!timeout.expired()) + yield(); + after = millis(); + Serial.print("after while 1\n"); + Serial.printf("delta = %lu\n", (after-before)); + + REQUIRE((after-before) == 3000); + + Serial.print("reset\n"); + timeout.reset(1000); + + before = millis(); + Serial.print("before while 2\n"); + while(!timeout) + yield(); + after = millis(); + Serial.print("after while 2\n"); + Serial.printf("delta = %lu\n", (after-before)); + + REQUIRE((after-before) == 1000); +} + +TEST_CASE("Periodic Timeout 1T 3000ms", "[polledTimeout]") +{ + using esp8266::polledTimeoutPeriodic; + using timeType = polledTimeoutPeriodic::timeType; + timeType before, after; + polledTimeoutPeriodic timeout(3000); + + Serial.println("Periodic Timeout 1T 3000ms"); + + Serial.print("before while 1\n"); + before = millis(); + while(!timeout) + yield(); + after = millis(); + Serial.print("after while 1\n"); + Serial.printf("delta = %lu\n", (after-before)); + + REQUIRE((after-before) == 3000); + + Serial.print("no reset needed\n"); + + before = millis(); + Serial.print("before while 2\n"); + while(!timeout) + yield(); + after = millis(); + Serial.print("after while 2\n"); + Serial.printf("delta = %lu\n", (after-before)); + + REQUIRE((after-before) == 3000); +} + +TEST_CASE("Periodic Timeout 10T 1000ms", "[polledTimeout]") +{ + using esp8266::polledTimeoutPeriodic; + using timeType = polledTimeoutPeriodic::timeType; + timeType before, after; + polledTimeoutPeriodic timeout(1000); + + Serial.println("Periodic 10T Timeout 1000ms"); + + int counter = 10; + before = millis(); + while(1) + { + if(timeout) + { + Serial.print("*"); + if(!--counter) + break; + yield(); + } + } + after = millis(); + Serial.printf("\ndelta = %lu\n", (after-before)); + REQUIRE((after-before) == 10000); +} + +TEST_CASE("OneShot Timeout 3000ms reset to 1000ms custom yield", "[polledTimeout]") +{ + using YieldOrSkipPolicy = esp8266::polledTimeoutPolicy::YieldOrSkip; + using polledTimeoutOneShotYield = esp8266::polledTimeout; + using timeType = polledTimeoutOneShotYield::timeType; + timeType before, after; + polledTimeoutOneShotYield timeout(3000); + + Serial.println("OneShot Timeout 3000ms"); + + + Serial.print("before while 1\n"); + before = millis(); + while(!timeout.expired()); + after = millis(); + Serial.print("after while 1\n"); + Serial.printf("delta = %lu\n", (after-before)); + + REQUIRE((after-before) == 3000); + + Serial.print("reset\n"); + timeout.reset(1000); + + before = millis(); + Serial.print("before while 2\n"); + while(!timeout); + after = millis(); + Serial.print("after while 2\n"); + Serial.printf("delta = %lu\n", (after-before)); + + REQUIRE((after-before) == 1000); +} + From 126abe1359b3a938c2a03a8aeb098f5f871593e8 Mon Sep 17 00:00:00 2001 From: devyte Date: Sun, 25 Nov 2018 19:41:47 -0300 Subject: [PATCH 3/8] Fix copyright, comments --- cores/esp8266/PolledTimeout.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cores/esp8266/PolledTimeout.h b/cores/esp8266/PolledTimeout.h index 4c96ed8301..78b6062bc7 100644 --- a/cores/esp8266/PolledTimeout.h +++ b/cores/esp8266/PolledTimeout.h @@ -5,7 +5,7 @@ /* PolledTimeout.h - Encapsulation of a polled Timeout - Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. + Copyright (c) 2018 Daniel Salazar. All rights reserved. This file is part of the esp8266 core for Arduino environment. This library is free software; you can redistribute it and/or @@ -46,7 +46,7 @@ struct YieldOrSkip -template +template class polledTimeout { public: @@ -58,8 +58,8 @@ class polledTimeout bool expired() { - YieldPolicy::execute(); //in case of DoNothing gets optimized away - if(PeriodicT) //in case of false gets optimized away + YieldPolicy::execute(); //in case of DoNothing: gets optimized away + if(PeriodicT) //in case of false: gets optimized away return expiredRetrigger(); return expiredOneShot(); } @@ -91,7 +91,7 @@ class polledTimeout timeType current = millis(); if(checkExpired(current)) { - unsigned int n = (current - _start) / _timeout; //how many _timeouts periods have elapsed, will usually be 1 (current - _start >= _timeout) + unsigned long n = (current - _start) / _timeout; //how many _timeouts periods have elapsed, will usually be 1 (current - _start >= _timeout) _start += n * _timeout; return true; } @@ -111,7 +111,7 @@ class polledTimeout using polledTimeoutOneShot = polledTimeout; using polledTimeoutPeriodic = polledTimeout; -/* A timeout that auto-yields when in CONT can be built as follows: +/* A 1-shot timeout that auto-yields when in CONT can be built as follows: * using polledTimeoutOneShotYield = polledTimeout; * * Other policies can be implemented by the user, and the polledTimeout types built as needed as shown above, without modifying this file. From bdf922343904163baeb25e392c70588d4aacf5b3 Mon Sep 17 00:00:00 2001 From: devyte Date: Sun, 25 Nov 2018 22:47:52 -0300 Subject: [PATCH 4/8] adjust host tests for better time precision --- tests/host/core/test_PolledTimeout.cpp | 94 ++++++++++++++++---------- 1 file changed, 57 insertions(+), 37 deletions(-) diff --git a/tests/host/core/test_PolledTimeout.cpp b/tests/host/core/test_PolledTimeout.cpp index 489ca37a92..104dd3af4d 100644 --- a/tests/host/core/test_PolledTimeout.cpp +++ b/tests/host/core/test_PolledTimeout.cpp @@ -6,112 +6,125 @@ TEST_CASE("OneShot Timeout 3000ms", "[polledTimeout]") { using esp8266::polledTimeoutOneShot; using timeType = polledTimeoutOneShot::timeType; - timeType before, after; - polledTimeoutOneShot timeout(3000); + timeType before, after, delta; Serial.println("OneShot Timeout 3000ms"); - Serial.print("before while 1\n"); + polledTimeoutOneShot timeout(3000); before = millis(); while(!timeout.expired()) yield(); after = millis(); Serial.print("after while 1\n"); - Serial.printf("delta = %lu\n", (after-before)); - REQUIRE((after-before) == 3000); + delta = after - before; + Serial.printf("delta = %lu\n", delta); + + REQUIRE(delta == 3000); + Serial.print("reset\n"); - timeout.reset(); - before = millis(); Serial.print("before while 2\n"); + timeout.reset(); + before = millis(); while(!timeout) yield(); after = millis(); Serial.print("after while 2\n"); - Serial.printf("delta = %lu\n", (after-before)); - REQUIRE((after-before) == 3000); + delta = after - before; + Serial.printf("delta = %lu\n", delta); + + REQUIRE(delta == 3000); } TEST_CASE("OneShot Timeout 3000ms reset to 1000ms", "[polledTimeout]") { using esp8266::polledTimeoutOneShot; using timeType = polledTimeoutOneShot::timeType; - timeType before, after; - polledTimeoutOneShot timeout(3000); + timeType before, after, delta; Serial.println("OneShot Timeout 3000ms"); - Serial.print("before while 1\n"); + polledTimeoutOneShot timeout(3000); before = millis(); while(!timeout.expired()) yield(); after = millis(); Serial.print("after while 1\n"); - Serial.printf("delta = %lu\n", (after-before)); - REQUIRE((after-before) == 3000); + delta = after - before; + Serial.printf("delta = %lu\n", delta); + + REQUIRE(delta == 3000); + Serial.print("reset\n"); - timeout.reset(1000); - before = millis(); Serial.print("before while 2\n"); + timeout.reset(1000); + before = millis(); while(!timeout) yield(); after = millis(); Serial.print("after while 2\n"); - Serial.printf("delta = %lu\n", (after-before)); - REQUIRE((after-before) == 1000); + delta = after - before; + Serial.printf("delta = %lu\n", delta); + + REQUIRE(delta == 1000); } TEST_CASE("Periodic Timeout 1T 3000ms", "[polledTimeout]") { using esp8266::polledTimeoutPeriodic; using timeType = polledTimeoutPeriodic::timeType; - timeType before, after; - polledTimeoutPeriodic timeout(3000); + timeType before, after, delta; Serial.println("Periodic Timeout 1T 3000ms"); Serial.print("before while 1\n"); + polledTimeoutPeriodic timeout(3000); before = millis(); while(!timeout) yield(); after = millis(); Serial.print("after while 1\n"); - Serial.printf("delta = %lu\n", (after-before)); - REQUIRE((after-before) == 3000); + delta = after - before; + Serial.printf("delta = %lu\n", delta); + + REQUIRE(delta == 3000); Serial.print("no reset needed\n"); - before = millis(); Serial.print("before while 2\n"); + before = millis(); while(!timeout) yield(); after = millis(); Serial.print("after while 2\n"); - Serial.printf("delta = %lu\n", (after-before)); + + delta = after - before; + Serial.printf("delta = %lu\n", delta); - REQUIRE((after-before) == 3000); + REQUIRE(delta == 3000); } TEST_CASE("Periodic Timeout 10T 1000ms", "[polledTimeout]") { using esp8266::polledTimeoutPeriodic; using timeType = polledTimeoutPeriodic::timeType; - timeType before, after; - polledTimeoutPeriodic timeout(1000); + timeType before, after, delta; Serial.println("Periodic 10T Timeout 1000ms"); int counter = 10; + + polledTimeoutPeriodic timeout(1000); before = millis(); while(1) { @@ -124,8 +137,10 @@ TEST_CASE("Periodic Timeout 10T 1000ms", "[polledTimeout]") } } after = millis(); - Serial.printf("\ndelta = %lu\n", (after-before)); - REQUIRE((after-before) == 10000); + + delta = after - before; + Serial.printf("\ndelta = %lu\n", delta); + REQUIRE(delta == 10000); } TEST_CASE("OneShot Timeout 3000ms reset to 1000ms custom yield", "[polledTimeout]") @@ -133,31 +148,36 @@ TEST_CASE("OneShot Timeout 3000ms reset to 1000ms custom yield", "[polledTimeout using YieldOrSkipPolicy = esp8266::polledTimeoutPolicy::YieldOrSkip; using polledTimeoutOneShotYield = esp8266::polledTimeout; using timeType = polledTimeoutOneShotYield::timeType; - timeType before, after; - polledTimeoutOneShotYield timeout(3000); + timeType before, after, delta; Serial.println("OneShot Timeout 3000ms"); Serial.print("before while 1\n"); + polledTimeoutOneShotYield timeout(3000); before = millis(); while(!timeout.expired()); after = millis(); Serial.print("after while 1\n"); - Serial.printf("delta = %lu\n", (after-before)); + + delta = after - before; + Serial.printf("delta = %lu\n", delta); + + REQUIRE(delta == 3000); - REQUIRE((after-before) == 3000); Serial.print("reset\n"); - timeout.reset(1000); - before = millis(); Serial.print("before while 2\n"); + timeout.reset(1000); + before = millis(); while(!timeout); after = millis(); Serial.print("after while 2\n"); - Serial.printf("delta = %lu\n", (after-before)); + + delta = after - before; + Serial.printf("delta = %lu\n", delta); - REQUIRE((after-before) == 1000); + REQUIRE(delta == 1000); } From 54a187d21423c1285b3429bec96bd51e078590ff Mon Sep 17 00:00:00 2001 From: devyte Date: Sun, 25 Nov 2018 23:47:27 -0300 Subject: [PATCH 5/8] add fuzzyness to timing tests for CI jitter --- tests/host/core/test_PolledTimeout.cpp | 42 +++++++++++--------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/tests/host/core/test_PolledTimeout.cpp b/tests/host/core/test_PolledTimeout.cpp index 104dd3af4d..8a265e1c21 100644 --- a/tests/host/core/test_PolledTimeout.cpp +++ b/tests/host/core/test_PolledTimeout.cpp @@ -1,6 +1,14 @@ #include #include "PolledTimeout.h" +//This won't work for +template +inline bool +fuzzycomp(argT a, argT b) +{ + const argT epsilon = 10; + return (std::max(a,b) - std::min(a,b) <= epsilon); +} TEST_CASE("OneShot Timeout 3000ms", "[polledTimeout]") { @@ -10,34 +18,30 @@ TEST_CASE("OneShot Timeout 3000ms", "[polledTimeout]") Serial.println("OneShot Timeout 3000ms"); - Serial.print("before while 1\n"); polledTimeoutOneShot timeout(3000); before = millis(); while(!timeout.expired()) yield(); after = millis(); - Serial.print("after while 1\n"); delta = after - before; Serial.printf("delta = %lu\n", delta); - REQUIRE(delta == 3000); + REQUIRE(fuzzycomp(delta, (timeType)3000)); Serial.print("reset\n"); - Serial.print("before while 2\n"); timeout.reset(); before = millis(); while(!timeout) yield(); after = millis(); - Serial.print("after while 2\n"); delta = after - before; Serial.printf("delta = %lu\n", delta); - REQUIRE(delta == 3000); + REQUIRE(fuzzycomp(delta, (timeType)3000)); } TEST_CASE("OneShot Timeout 3000ms reset to 1000ms", "[polledTimeout]") @@ -48,34 +52,30 @@ TEST_CASE("OneShot Timeout 3000ms reset to 1000ms", "[polledTimeout]") Serial.println("OneShot Timeout 3000ms"); - Serial.print("before while 1\n"); polledTimeoutOneShot timeout(3000); before = millis(); while(!timeout.expired()) yield(); after = millis(); - Serial.print("after while 1\n"); delta = after - before; Serial.printf("delta = %lu\n", delta); - REQUIRE(delta == 3000); + REQUIRE(fuzzycomp(delta, (timeType)3000)); Serial.print("reset\n"); - Serial.print("before while 2\n"); timeout.reset(1000); before = millis(); while(!timeout) yield(); after = millis(); - Serial.print("after while 2\n"); delta = after - before; Serial.printf("delta = %lu\n", delta); - REQUIRE(delta == 1000); + REQUIRE(fuzzycomp(delta, (timeType)1000)); } TEST_CASE("Periodic Timeout 1T 3000ms", "[polledTimeout]") @@ -86,32 +86,28 @@ TEST_CASE("Periodic Timeout 1T 3000ms", "[polledTimeout]") Serial.println("Periodic Timeout 1T 3000ms"); - Serial.print("before while 1\n"); polledTimeoutPeriodic timeout(3000); before = millis(); while(!timeout) yield(); after = millis(); - Serial.print("after while 1\n"); delta = after - before; Serial.printf("delta = %lu\n", delta); - REQUIRE(delta == 3000); + REQUIRE(fuzzycomp(delta, (timeType)3000)); Serial.print("no reset needed\n"); - Serial.print("before while 2\n"); before = millis(); while(!timeout) yield(); after = millis(); - Serial.print("after while 2\n"); delta = after - before; Serial.printf("delta = %lu\n", delta); - REQUIRE(delta == 3000); + REQUIRE(fuzzycomp(delta, (timeType)3000)); } TEST_CASE("Periodic Timeout 10T 1000ms", "[polledTimeout]") @@ -140,7 +136,7 @@ TEST_CASE("Periodic Timeout 10T 1000ms", "[polledTimeout]") delta = after - before; Serial.printf("\ndelta = %lu\n", delta); - REQUIRE(delta == 10000); + REQUIRE(fuzzycomp(delta, (timeType)10000)); } TEST_CASE("OneShot Timeout 3000ms reset to 1000ms custom yield", "[polledTimeout]") @@ -153,31 +149,27 @@ TEST_CASE("OneShot Timeout 3000ms reset to 1000ms custom yield", "[polledTimeout Serial.println("OneShot Timeout 3000ms"); - Serial.print("before while 1\n"); polledTimeoutOneShotYield timeout(3000); before = millis(); while(!timeout.expired()); after = millis(); - Serial.print("after while 1\n"); delta = after - before; Serial.printf("delta = %lu\n", delta); - REQUIRE(delta == 3000); + REQUIRE(fuzzycomp(delta, (timeType)3000)); Serial.print("reset\n"); - Serial.print("before while 2\n"); timeout.reset(1000); before = millis(); while(!timeout); after = millis(); - Serial.print("after while 2\n"); delta = after - before; Serial.printf("delta = %lu\n", delta); - REQUIRE(delta == 1000); + REQUIRE(fuzzycomp(delta, (timeType)1000)); } From c15c76c5dbba7a714329ea73d3e81a3136077450 Mon Sep 17 00:00:00 2001 From: devyte Date: Mon, 26 Nov 2018 01:27:57 -0300 Subject: [PATCH 6/8] add blink example with polledTimeout --- .../BlinkPolledTimeout/BlinkPolledTimeout.ino | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino diff --git a/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino b/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino new file mode 100644 index 0000000000..35e2ecb9a6 --- /dev/null +++ b/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino @@ -0,0 +1,60 @@ +/* + ESP8266 Blink by Daniel Salazar + Copyright 2018 + + Blink the blue LED on the ESP module using polledTimeout class + This example code is in the public domain + + Note that this sketch uses LED_BUILTIN to find the pin with the internal LED +*/ + +#include + +void ledOn() { + digitalWrite(LED_BUILTIN, LOW); // Turn the LED on (Note that LOW is the voltage level +} + +void ledOff() { + digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off by making the voltage HIGH +} + +void ledToggle() { + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // Change the state of the LED +} + + + +esp8266::polledTimeoutPeriodic halfPeriod(500); //use fully qualified type and avoid importing all ::esp8266 namespace to the global namespace + +// the setup function runs only once at start +void setup() { + pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output + + using esp8266::polledTimeoutOneShot; //import the type to the local namespace + + //STEP1; turn the led ON + ledOn(); + + //STEP2: wait for ON timeout + polledTimeoutOneShot timeoutOn(2000); + while(!timeoutOn) + yield(); + + //STEP3: turn the led OFF + ledOff(); + + //STEP4: wait for OFF timeout to assure the led is kept off for this time before exiting setup + polledTimeoutOneShot timeoutOff(2000); + while(!timeoutOff) + yield(); + + //Done with STEPs, do other stuff + halfPeriod.reset(); //halfPeriod is global, so it gets inited on sketch start. Clear it here to make it ready for loop, where it's actually used. +} + + +// the loop function runs over and over again forever +void loop() { + if(halfPeriod) + ledToggle(); +} From 9ca90bbb3fd87881abf01db8a965c25927f0ad79 Mon Sep 17 00:00:00 2001 From: devyte Date: Mon, 26 Nov 2018 02:11:30 -0300 Subject: [PATCH 7/8] improve namespace and type naming, add copyright, comments --- cores/esp8266/PolledTimeout.h | 28 +++++++------ .../BlinkPolledTimeout/BlinkPolledTimeout.ino | 40 ++++++++++++++----- tests/host/core/test_PolledTimeout.cpp | 32 +++++++-------- 3 files changed, 61 insertions(+), 39 deletions(-) diff --git a/cores/esp8266/PolledTimeout.h b/cores/esp8266/PolledTimeout.h index 78b6062bc7..7b54577bc9 100644 --- a/cores/esp8266/PolledTimeout.h +++ b/cores/esp8266/PolledTimeout.h @@ -28,7 +28,11 @@ namespace esp8266 { -namespace polledTimeoutPolicy + +namespace polledTimeout +{ + +namespace YieldPolicy { struct DoNothing @@ -41,24 +45,22 @@ struct YieldOrSkip static void execute() {delay(0);} }; +} //YieldPolicy -} - - -template -class polledTimeout +template +class timeoutTemplate { public: using timeType = decltype(millis()); - polledTimeout(timeType timeout) + timeoutTemplate(timeType timeout) : _timeout(timeout), _start(millis()) {} bool expired() { - YieldPolicy::execute(); //in case of DoNothing: gets optimized away + YieldPolicyT::execute(); //in case of DoNothing: gets optimized away if(PeriodicT) //in case of false: gets optimized away return expiredRetrigger(); return expiredOneShot(); @@ -107,14 +109,16 @@ class polledTimeout timeType _start; }; +using oneShot = polledTimeout::timeoutTemplate; +using periodic = polledTimeout::timeoutTemplate; + +} //polledTimeout -using polledTimeoutOneShot = polledTimeout; -using polledTimeoutPeriodic = polledTimeout; /* A 1-shot timeout that auto-yields when in CONT can be built as follows: - * using polledTimeoutOneShotYield = polledTimeout; + * using oneShotYield = esp8266::polledTimeout::timeoutTemplate; * - * Other policies can be implemented by the user, and the polledTimeout types built as needed as shown above, without modifying this file. + * Other policies can be implemented by the user, e.g.: simple yield that panics in SYS, and the polledTimeout types built as needed as shown above, without modifying this file. */ }//esp8266 diff --git a/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino b/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino index 35e2ecb9a6..6ac0815400 100644 --- a/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino +++ b/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino @@ -1,13 +1,28 @@ /* - ESP8266 Blink by Daniel Salazar - Copyright 2018 + ESP8266 Blink with polledTimeout by Daniel Salazar + + Copyright (c) 2018 Daniel Salazar. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Blink the blue LED on the ESP module using polledTimeout class - This example code is in the public domain Note that this sketch uses LED_BUILTIN to find the pin with the internal LED */ + #include void ledOn() { @@ -24,29 +39,31 @@ void ledToggle() { -esp8266::polledTimeoutPeriodic halfPeriod(500); //use fully qualified type and avoid importing all ::esp8266 namespace to the global namespace +esp8266::polledTimeout::periodic halfPeriod(500); //use fully qualified type and avoid importing all ::esp8266 namespace to the global namespace // the setup function runs only once at start void setup() { pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output - using esp8266::polledTimeoutOneShot; //import the type to the local namespace + using esp8266::polledTimeout::oneShot; //import the type to the local namespace //STEP1; turn the led ON ledOn(); //STEP2: wait for ON timeout - polledTimeoutOneShot timeoutOn(2000); - while(!timeoutOn) + oneShot timeoutOn(2000); + while(!timeoutOn) { yield(); + } //STEP3: turn the led OFF ledOff(); //STEP4: wait for OFF timeout to assure the led is kept off for this time before exiting setup - polledTimeoutOneShot timeoutOff(2000); - while(!timeoutOff) + oneShot timeoutOff(2000); + while(!timeoutOff) { yield(); + } //Done with STEPs, do other stuff halfPeriod.reset(); //halfPeriod is global, so it gets inited on sketch start. Clear it here to make it ready for loop, where it's actually used. @@ -55,6 +72,7 @@ void setup() { // the loop function runs over and over again forever void loop() { - if(halfPeriod) + if(halfPeriod) { ledToggle(); + } } diff --git a/tests/host/core/test_PolledTimeout.cpp b/tests/host/core/test_PolledTimeout.cpp index 8a265e1c21..7746072ecb 100644 --- a/tests/host/core/test_PolledTimeout.cpp +++ b/tests/host/core/test_PolledTimeout.cpp @@ -12,13 +12,13 @@ fuzzycomp(argT a, argT b) TEST_CASE("OneShot Timeout 3000ms", "[polledTimeout]") { - using esp8266::polledTimeoutOneShot; - using timeType = polledTimeoutOneShot::timeType; + using esp8266::polledTimeout::oneShot; + using timeType = oneShot::timeType; timeType before, after, delta; Serial.println("OneShot Timeout 3000ms"); - polledTimeoutOneShot timeout(3000); + oneShot timeout(3000); before = millis(); while(!timeout.expired()) yield(); @@ -46,13 +46,13 @@ TEST_CASE("OneShot Timeout 3000ms", "[polledTimeout]") TEST_CASE("OneShot Timeout 3000ms reset to 1000ms", "[polledTimeout]") { - using esp8266::polledTimeoutOneShot; - using timeType = polledTimeoutOneShot::timeType; + using esp8266::polledTimeout::oneShot; + using timeType = oneShot::timeType; timeType before, after, delta; Serial.println("OneShot Timeout 3000ms"); - polledTimeoutOneShot timeout(3000); + oneShot timeout(3000); before = millis(); while(!timeout.expired()) yield(); @@ -80,13 +80,13 @@ TEST_CASE("OneShot Timeout 3000ms reset to 1000ms", "[polledTimeout]") TEST_CASE("Periodic Timeout 1T 3000ms", "[polledTimeout]") { - using esp8266::polledTimeoutPeriodic; - using timeType = polledTimeoutPeriodic::timeType; + using esp8266::polledTimeout::periodic; + using timeType = periodic::timeType; timeType before, after, delta; Serial.println("Periodic Timeout 1T 3000ms"); - polledTimeoutPeriodic timeout(3000); + periodic timeout(3000); before = millis(); while(!timeout) yield(); @@ -112,15 +112,15 @@ TEST_CASE("Periodic Timeout 1T 3000ms", "[polledTimeout]") TEST_CASE("Periodic Timeout 10T 1000ms", "[polledTimeout]") { - using esp8266::polledTimeoutPeriodic; - using timeType = polledTimeoutPeriodic::timeType; + using esp8266::polledTimeout::periodic; + using timeType = periodic::timeType; timeType before, after, delta; Serial.println("Periodic 10T Timeout 1000ms"); int counter = 10; - polledTimeoutPeriodic timeout(1000); + periodic timeout(1000); before = millis(); while(1) { @@ -141,15 +141,15 @@ TEST_CASE("Periodic Timeout 10T 1000ms", "[polledTimeout]") TEST_CASE("OneShot Timeout 3000ms reset to 1000ms custom yield", "[polledTimeout]") { - using YieldOrSkipPolicy = esp8266::polledTimeoutPolicy::YieldOrSkip; - using polledTimeoutOneShotYield = esp8266::polledTimeout; - using timeType = polledTimeoutOneShotYield::timeType; + using YieldOrSkipPolicy = esp8266::polledTimeout::YieldPolicy::YieldOrSkip; + using oneShotYield = esp8266::polledTimeout::timeoutTemplate; + using timeType = oneShotYield::timeType; timeType before, after, delta; Serial.println("OneShot Timeout 3000ms"); - polledTimeoutOneShotYield timeout(3000); + oneShotYield timeout(3000); before = millis(); while(!timeout.expired()); after = millis(); From e09e8c81444fffe9e3f4ba5368733621d0f982c8 Mon Sep 17 00:00:00 2001 From: devyte Date: Mon, 26 Nov 2018 02:39:56 -0300 Subject: [PATCH 8/8] fix astyle --- .../examples/BlinkPolledTimeout/BlinkPolledTimeout.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino b/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino index 6ac0815400..12aca929f2 100644 --- a/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino +++ b/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino @@ -52,7 +52,7 @@ void setup() { //STEP2: wait for ON timeout oneShot timeoutOn(2000); - while(!timeoutOn) { + while (!timeoutOn) { yield(); } @@ -61,7 +61,7 @@ void setup() { //STEP4: wait for OFF timeout to assure the led is kept off for this time before exiting setup oneShot timeoutOff(2000); - while(!timeoutOff) { + while (!timeoutOff) { yield(); } @@ -72,7 +72,7 @@ void setup() { // the loop function runs over and over again forever void loop() { - if(halfPeriod) { + if (halfPeriod) { ledToggle(); } }