Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avoid circular #include dependence for PolledTimeout #7356

Merged
merged 19 commits into from
Aug 15, 2020
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions cores/esp8266/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,6 @@ void analogWriteFreq(uint32_t freq);
void analogWriteResolution(int res);
void analogWriteRange(uint32_t range);

unsigned long millis(void);
unsigned long micros(void);
uint64_t micros64(void);
void delay(unsigned long);
void delayMicroseconds(unsigned int us);
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout);

Expand Down
14 changes: 12 additions & 2 deletions cores/esp8266/Esp.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
#include <Arduino.h>
#include "spi_vendors.h"

#if EXPERIMENTAL_POLLEDTIMEOUT_GLOBAL
// proposal: brings PolledTimeout at the same level as `millis()`
// use global define EXPERIMENTAL_POLLEDTIMEOUT_GLOBAL=1 to enable
#include <PolledTimeout.h>
using namespace esp8266::polledTimeout;
devyte marked this conversation as resolved.
Show resolved Hide resolved
#endif

/**
* AVR macros for WDT managment
*/
Expand Down Expand Up @@ -124,10 +131,13 @@ class EspClass {
#if defined(F_CPU) || defined(CORE_MOCK)
constexpr uint8_t getCpuFreqMHz() const
{
return clockCyclesPerMicrosecond();
return esp_get_cpu_freq_mhz();
}
#else
uint8_t getCpuFreqMHz();
uint8_t getCpuFreqMHz() const
{
return esp_get_cpu_freq_mhz();
}
#endif

uint32_t getFlashChipId();
Expand Down
47 changes: 30 additions & 17 deletions cores/esp8266/PolledTimeout.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

/*
PolledTimeout.h - Encapsulation of a polled Timeout

Copyright (c) 2018 Daniel Salazar. All rights reserved.
This file is part of the esp8266 core for Arduino environment.

Expand All @@ -23,9 +23,10 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <limits>

#include <Arduino.h>
#include <c_types.h> // IRAM_ATTR
#include <limits> // std::numeric_limits
#include <type_traits> // std::is_unsigned
#include <core_esp8266_features.h>
devyte marked this conversation as resolved.
Show resolved Hide resolved

namespace esp8266
{
Expand Down Expand Up @@ -70,13 +71,13 @@ struct TimeSourceMillis

struct TimeSourceCycles
{
// time policy based on ESP.getCycleCount()
// time policy based on esp_get_cycle_count()
devyte marked this conversation as resolved.
Show resolved Hide resolved
// this particular time measurement is intended to be called very often
// (every loop, every yield)

using timeType = decltype(ESP.getCycleCount());
static timeType time() {return ESP.getCycleCount();}
static constexpr timeType ticksPerSecond = ESP.getCpuFreqMHz() * 1000000UL; // 80'000'000 or 160'000'000 Hz
using timeType = decltype(esp_get_cycle_count());
static timeType time() {return esp_get_cycle_count();}
static constexpr timeType ticksPerSecond = esp_get_cpu_freq_mhz() * 1000000UL; // 80'000'000 or 160'000'000 Hz
static constexpr timeType ticksPerSecondMax = 160000000; // 160MHz
};

Expand Down Expand Up @@ -161,13 +162,13 @@ class timeoutTemplate
return expiredRetrigger();
return expiredOneShot();
}

IRAM_ATTR // fast
operator bool()
{
return expired();
return expired();
}

bool canExpire () const
{
return !_neverExpires;
Expand All @@ -192,6 +193,18 @@ class timeoutTemplate
_start = TimePolicyT::time();
}

void resetAndSetExpired (const timeType newUserTimeout)
devyte marked this conversation as resolved.
Show resolved Hide resolved
{
reset(newUserTimeout);
_start -= _timeout;
}

void resetAndSetExpired ()
{
reset();
_start -= _timeout;
}

void resetToNeverExpires ()
{
_timeout = alwaysExpired + 1; // because canWait() has precedence
Expand All @@ -202,7 +215,7 @@ class timeoutTemplate
{
return TimePolicyT::toUserUnit(_timeout);
}

static constexpr timeType timeMax()
{
return TimePolicyT::timeMax;
Expand Down Expand Up @@ -235,14 +248,14 @@ class timeoutTemplate
}
return false;
}

IRAM_ATTR // fast
bool expiredOneShot() const
{
// returns "always expired" or "has expired"
return !canWait() || checkExpired(TimePolicyT::time());
}

timeType _timeout;
timeType _start;
bool _neverExpires;
Expand All @@ -259,14 +272,14 @@ using periodic = polledTimeout::timeoutTemplate<true> /*__attribute__((deprecate
using oneShotMs = polledTimeout::timeoutTemplate<false>;
using periodicMs = polledTimeout::timeoutTemplate<true>;

// Time policy based on ESP.getCycleCount(), and intended to be called very often:
// Time policy based on esp_get_cycle_count(), and intended to be called very often:
// "Fast" versions sacrifices time range for improved precision and reduced execution time (by 86%)
// (cpu cycles for ::expired(): 372 (millis()) vs 52 (ESP.getCycleCount()))
// (cpu cycles for ::expired(): 372 (millis()) vs 52 (esp_get_cycle_count()))
// timeMax() values:
// Ms: max is 26843 ms (26.8 s)
// Us: max is 26843545 us (26.8 s)
// Ns: max is 1073741823 ns ( 1.07 s)
// (time policy based on ESP.getCycleCount() is intended to be called very often)
// (time policy based on esp_get_cycle_count() is intended to be called very often)

using oneShotFastMs = polledTimeout::timeoutTemplate<false, YieldPolicy::DoNothing, TimePolicy::TimeFastMillis>;
using periodicFastMs = polledTimeout::timeoutTemplate<true, YieldPolicy::DoNothing, TimePolicy::TimeFastMillis>;
Expand Down
23 changes: 23 additions & 0 deletions cores/esp8266/core_esp8266_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,29 @@ extern "C" {
#endif

void precache(void *f, uint32_t bytes);
unsigned long millis(void);
unsigned long micros(void);
uint64_t micros64(void);
void delay(unsigned long);
void delayMicroseconds(unsigned int us);

#if defined(F_CPU) || defined(CORE_MOCK)
#ifdef __cplusplus
constexpr
#else
inline
#endif
int esp_get_cpu_freq_mhz()
{
return F_CPU / 1000000L;
}
#else
inline int esp_get_cpu_freq_mhz()
{
return system_get_cpu_freq();
}
#endif
devyte marked this conversation as resolved.
Show resolved Hide resolved


#ifdef __cplusplus
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
Note that this sketch uses LED_BUILTIN to find the pin with the internal LED
*/


#include <PolledTimeout.h>

void ledOn() {
Expand All @@ -38,7 +37,7 @@ void ledToggle() {
}


esp8266::polledTimeout::periodicFastUs halfPeriod(500000); //use fully qualified type and avoid importing all ::esp8266 namespace to the global namespace
esp8266::polledTimeout::periodicFastUs halfPeriod(500000);

// the setup function runs only once at start
void setup() {
Expand All @@ -59,13 +58,11 @@ void setup() {

pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output

using esp8266::polledTimeout::oneShotMs; //import the type to the local namespace

//STEP1; turn the led ON
ledOn();

//STEP2: wait for ON timeout
oneShotMs timeoutOn(2000);
esp8266::polledTimeout::oneShotMs timeoutOn(2000);
devyte marked this conversation as resolved.
Show resolved Hide resolved
while (!timeoutOn) {
yield();
}
Expand All @@ -74,7 +71,7 @@ void setup() {
ledOff();

//STEP4: wait for OFF timeout to assure the led is kept off for this time before exiting setup
oneShotMs timeoutOff(2000);
esp8266::polledTimeout::oneShotMs timeoutOff(2000);
while (!timeoutOff) {
yield();
}
Expand Down
7 changes: 6 additions & 1 deletion tests/host/common/MockEsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ uint32_t EspClass::getFlashChipSize(void)

String EspClass::getFullVersion ()
{
return "host-emulation";
return "emulation-on-host";
}

uint32_t EspClass::getFreeContStack()
Expand All @@ -221,6 +221,11 @@ void EspClass::resetFreeContStack()
}

uint32_t EspClass::getCycleCount()
{
return esp_get_cycle_count();
}

uint32_t esp_get_cycle_count()
{
timeval t;
gettimeofday(&t, NULL);
Expand Down
47 changes: 26 additions & 21 deletions tests/host/common/mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,29 @@

#define CORE_MOCK 1

//

#define ARDUINO 267
#define ESP8266 1
#define A0 0
#define LED_BUILTIN 0
#define F_CPU 80000000
#define LWIP_OPEN_SRC
#define TCP_MSS 536
#define LWIP_FEATURES 1

//

#define D0 0
#define D1 1
#define D2 3
#define D3 3
#define D4 4
#define D5 5
#define D6 6
#define D7 7
#define D8 8

// include host's STL before any other include file
// because core definition like max() is in the way

Expand Down Expand Up @@ -61,28 +84,10 @@ typedef uint32_t uint32;

//

#define ARDUINO 267
#define ESP8266 1
#define A0 0
#define LED_BUILTIN 0
#define F_CPU 80000000
#define LWIP_OPEN_SRC
#define TCP_MSS 536
#define LWIP_FEATURES 1

//

#define D0 0
#define D1 1
#define D2 3
#define D3 3
#define D4 4
#define D5 5
#define D6 6
#define D7 7
#define D8 8
#include <c_types.h>
#include <core_esp8266_features.h>

//
uint32_t esp_get_cycle_count();

#include <Arduino.h>

Expand Down