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 all 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
7 changes: 5 additions & 2 deletions cores/esp8266/Esp.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,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
54 changes: 37 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 @@ -178,6 +179,7 @@ class timeoutTemplate
return _timeout != alwaysExpired;
}

// Resets, will trigger after this new timeout.
IRAM_ATTR // called from ISR
void reset(const timeType newUserTimeout)
{
Expand All @@ -186,12 +188,30 @@ class timeoutTemplate
_neverExpires = (newUserTimeout < 0) || (newUserTimeout > timeMax());
}

// Resets, will trigger after the timeout previously set.
IRAM_ATTR // called from ISR
void reset()
{
_start = TimePolicyT::time();
}

// Resets to just expired so that on next poll the check will immediately trigger for the user,
// also change timeout (after next immediate trigger).
IRAM_ATTR // called from ISR
void resetAndSetExpired (const timeType newUserTimeout)
devyte marked this conversation as resolved.
Show resolved Hide resolved
{
reset(newUserTimeout);
_start -= _timeout;
}

// Resets to just expired so that on next poll the check will immediately trigger for the user.
IRAM_ATTR // called from ISR
void resetAndSetExpired ()
{
reset();
_start -= _timeout;
}

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

static constexpr timeType timeMax()
{
return TimePolicyT::timeMax;
Expand Down Expand Up @@ -235,14 +255,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 +279,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
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