1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

avoid circular #include dependence for PolledTimeout (#7356)

* move features to features.h

* fix std:: dependencies

* fix emulation on host

* api explanation
This commit is contained in:
david gauchard 2020-08-15 21:24:35 +02:00 committed by GitHub
parent 01edc0e51f
commit e0fedc577b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 97 additions and 46 deletions

View File

@ -177,11 +177,6 @@ void analogWriteFreq(uint32_t freq);
void analogWriteResolution(int res); void analogWriteResolution(int res);
void analogWriteRange(uint32_t range); 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 pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout); unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout);

View File

@ -124,10 +124,13 @@ class EspClass {
#if defined(F_CPU) || defined(CORE_MOCK) #if defined(F_CPU) || defined(CORE_MOCK)
constexpr uint8_t getCpuFreqMHz() const constexpr uint8_t getCpuFreqMHz() const
{ {
return clockCyclesPerMicrosecond(); return esp_get_cpu_freq_mhz();
} }
#else #else
uint8_t getCpuFreqMHz(); uint8_t getCpuFreqMHz() const
{
return esp_get_cpu_freq_mhz();
}
#endif #endif
uint32_t getFlashChipId(); uint32_t getFlashChipId();

View File

@ -4,7 +4,7 @@
/* /*
PolledTimeout.h - Encapsulation of a polled Timeout PolledTimeout.h - Encapsulation of a polled Timeout
Copyright (c) 2018 Daniel Salazar. All rights reserved. Copyright (c) 2018 Daniel Salazar. All rights reserved.
This file is part of the esp8266 core for Arduino environment. This file is part of the esp8266 core for Arduino environment.
@ -23,9 +23,10 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <limits> #include <c_types.h> // IRAM_ATTR
#include <limits> // std::numeric_limits
#include <Arduino.h> #include <type_traits> // std::is_unsigned
#include <core_esp8266_features.h>
namespace esp8266 namespace esp8266
{ {
@ -70,13 +71,13 @@ struct TimeSourceMillis
struct TimeSourceCycles struct TimeSourceCycles
{ {
// time policy based on ESP.getCycleCount() // time policy based on esp_get_cycle_count()
// this particular time measurement is intended to be called very often // this particular time measurement is intended to be called very often
// (every loop, every yield) // (every loop, every yield)
using timeType = decltype(ESP.getCycleCount()); using timeType = decltype(esp_get_cycle_count());
static timeType time() {return ESP.getCycleCount();} static timeType time() {return esp_get_cycle_count();}
static constexpr timeType ticksPerSecond = ESP.getCpuFreqMHz() * 1000000UL; // 80'000'000 or 160'000'000 Hz static constexpr timeType ticksPerSecond = esp_get_cpu_freq_mhz() * 1000000UL; // 80'000'000 or 160'000'000 Hz
static constexpr timeType ticksPerSecondMax = 160000000; // 160MHz static constexpr timeType ticksPerSecondMax = 160000000; // 160MHz
}; };
@ -161,13 +162,13 @@ public:
return expiredRetrigger(); return expiredRetrigger();
return expiredOneShot(); return expiredOneShot();
} }
IRAM_ATTR // fast IRAM_ATTR // fast
operator bool() operator bool()
{ {
return expired(); return expired();
} }
bool canExpire () const bool canExpire () const
{ {
return !_neverExpires; return !_neverExpires;
@ -178,6 +179,7 @@ public:
return _timeout != alwaysExpired; return _timeout != alwaysExpired;
} }
// Resets, will trigger after this new timeout.
IRAM_ATTR // called from ISR IRAM_ATTR // called from ISR
void reset(const timeType newUserTimeout) void reset(const timeType newUserTimeout)
{ {
@ -186,12 +188,30 @@ public:
_neverExpires = (newUserTimeout < 0) || (newUserTimeout > timeMax()); _neverExpires = (newUserTimeout < 0) || (newUserTimeout > timeMax());
} }
// Resets, will trigger after the timeout previously set.
IRAM_ATTR // called from ISR IRAM_ATTR // called from ISR
void reset() void reset()
{ {
_start = TimePolicyT::time(); _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)
{
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 () void resetToNeverExpires ()
{ {
_timeout = alwaysExpired + 1; // because canWait() has precedence _timeout = alwaysExpired + 1; // because canWait() has precedence
@ -202,7 +222,7 @@ public:
{ {
return TimePolicyT::toUserUnit(_timeout); return TimePolicyT::toUserUnit(_timeout);
} }
static constexpr timeType timeMax() static constexpr timeType timeMax()
{ {
return TimePolicyT::timeMax; return TimePolicyT::timeMax;
@ -235,14 +255,14 @@ protected:
} }
return false; return false;
} }
IRAM_ATTR // fast IRAM_ATTR // fast
bool expiredOneShot() const bool expiredOneShot() const
{ {
// returns "always expired" or "has expired" // returns "always expired" or "has expired"
return !canWait() || checkExpired(TimePolicyT::time()); return !canWait() || checkExpired(TimePolicyT::time());
} }
timeType _timeout; timeType _timeout;
timeType _start; timeType _start;
bool _neverExpires; bool _neverExpires;
@ -259,14 +279,14 @@ using periodic = polledTimeout::timeoutTemplate<true> /*__attribute__((deprecate
using oneShotMs = polledTimeout::timeoutTemplate<false>; using oneShotMs = polledTimeout::timeoutTemplate<false>;
using periodicMs = polledTimeout::timeoutTemplate<true>; 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%) // "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: // timeMax() values:
// Ms: max is 26843 ms (26.8 s) // Ms: max is 26843 ms (26.8 s)
// Us: max is 26843545 us (26.8 s) // Us: max is 26843545 us (26.8 s)
// Ns: max is 1073741823 ns ( 1.07 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 oneShotFastMs = polledTimeout::timeoutTemplate<false, YieldPolicy::DoNothing, TimePolicy::TimeFastMillis>;
using periodicFastMs = polledTimeout::timeoutTemplate<true, YieldPolicy::DoNothing, TimePolicy::TimeFastMillis>; using periodicFastMs = polledTimeout::timeoutTemplate<true, YieldPolicy::DoNothing, TimePolicy::TimeFastMillis>;

View File

@ -123,6 +123,29 @@ extern "C" {
#endif #endif
void precache(void *f, uint32_t bytes); 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
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -208,7 +208,7 @@ uint32_t EspClass::getFlashChipSize(void)
String EspClass::getFullVersion () String EspClass::getFullVersion ()
{ {
return "host-emulation"; return "emulation-on-host";
} }
uint32_t EspClass::getFreeContStack() uint32_t EspClass::getFreeContStack()
@ -221,6 +221,11 @@ void EspClass::resetFreeContStack()
} }
uint32_t EspClass::getCycleCount() uint32_t EspClass::getCycleCount()
{
return esp_get_cycle_count();
}
uint32_t esp_get_cycle_count()
{ {
timeval t; timeval t;
gettimeofday(&t, NULL); gettimeofday(&t, NULL);

View File

@ -31,6 +31,29 @@
#define CORE_MOCK 1 #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 // include host's STL before any other include file
// because core definition like max() is in the way // because core definition like max() is in the way
@ -61,28 +84,10 @@ typedef uint32_t uint32;
// //
#define ARDUINO 267 #include <c_types.h>
#define ESP8266 1 #include <core_esp8266_features.h>
#define A0 0
#define LED_BUILTIN 0
#define F_CPU 80000000
#define LWIP_OPEN_SRC
#define TCP_MSS 536
#define LWIP_FEATURES 1
// uint32_t esp_get_cycle_count();
#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 <Arduino.h> #include <Arduino.h>