From cbc1ef64fc1623a7d3cc3d92423d91c7235f6dea Mon Sep 17 00:00:00 2001 From: Makuna Date: Mon, 13 Jul 2015 13:47:13 -0700 Subject: [PATCH 1/3] optimistic_yield() this introduces optimistic_yield() used for when standard library methods are normally used in tight loops waiting for something to happen, like available(). --- README.md | 1 + .../esp8266/cores/esp8266/HardwareSerial.cpp | 18 ++++++++++++------ .../cores/esp8266/core_esp8266_main.cpp | 17 ++++++++++++----- .../libraries/ESP8266WiFi/src/WiFiClient.cpp | 17 ++++++++--------- .../libraries/ESP8266WiFi/src/WiFiServer.cpp | 10 +++------- .../libraries/ESP8266WiFi/src/WiFiUdp.cpp | 16 +++++++++++++--- .../esp8266com/esp8266/libraries/Wire/Wire.cpp | 10 +++++++++- 7 files changed, 58 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 201d0f250e..db43813bb3 100644 --- a/README.md +++ b/README.md @@ -218,6 +218,7 @@ Libraries that don't rely on low-level access to AVR registers should work well. - [PubSubClient](https://github.com/Imroy/pubsubclient) MQTT library by @Imroy. - [RTC](https://github.com/Makuna/Rtc) - Arduino Library for Ds1307 & Ds3231 compatible with esp8266. - [Souliss, Smart Home](https://github.com/souliss/souliss) - Framework for Smart Home based on Arduino, Android and openHAB. +- [ST7735](https://github.com/nzmichaelh/Adafruit-ST7735-Library) - Adafruit's ST7735 library modified to be compatible with esp8266. Just make sure to modify the pins in the examples as they are still AVR specific. #### Upload via serial port #### Pick the correct serial port. diff --git a/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp b/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp index e77fe3ef43..7f1f2cc92b 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp @@ -551,14 +551,20 @@ bool HardwareSerial::isRxEnabled(void) { return _uart->rxEnabled; } +extern "C" void optimistic_yield(); + int HardwareSerial::available(void) { - if(_uart == 0) - return 0; - if(_uart->rxEnabled) { - return static_cast(_rx_buffer->getSize()); - } else { - return 0; + int result = 0; + + if (_uart != NULL && _uart->rxEnabled) { + result = static_cast(_rx_buffer->getSize()); } + + if (!result) { + optimistic_yield(); + } + + return result; } int HardwareSerial::peek(void) { diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp index dcf5631eab..04ab9f116f 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp @@ -34,6 +34,8 @@ extern "C" { #define LOOP_TASK_PRIORITY 0 #define LOOP_QUEUE_SIZE 1 +#define OPTIMISTIC_YIELD_TIME_US 16000 + struct rst_info resetInfo; int atexit(void (*func)()) { @@ -62,11 +64,8 @@ extern void (*__init_array_end)(void); cont_t g_cont __attribute__ ((aligned (16))); static os_event_t g_loop_queue[LOOP_QUEUE_SIZE]; -static uint32_t g_micros_at_task_start; +static uint32_t g_micros_at_last_task_yield; -extern "C" uint32_t esp_micros_at_task_start() { - return g_micros_at_task_start; -} extern "C" void abort() { while(1) { @@ -74,6 +73,7 @@ extern "C" void abort() { } extern "C" void esp_yield() { + g_micros_at_last_task_yield = system_get_time(); cont_yield(&g_cont); } @@ -87,6 +87,13 @@ extern "C" void __yield() { } extern "C" void yield(void) __attribute__ ((weak, alias("__yield"))); +extern "C" void optimistic_yield() { + if (system_get_time() - g_micros_at_last_task_yield > OPTIMISTIC_YIELD_TIME_US) + { + __yield(); + } +} + static void loop_wrapper() { static bool setup_done = false; if(!setup_done) { @@ -99,7 +106,7 @@ static void loop_wrapper() { } static void loop_task(os_event_t *events) { - g_micros_at_task_start = system_get_time(); + g_micros_at_last_task_yield = system_get_time(); cont_run(&g_cont, &loop_wrapper); if(cont_check(&g_cont) != 0) { ets_printf("\r\nheap collided with sketch stack\r\n"); diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp index 3b4a9b6f08..4327b90416 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -177,20 +177,19 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size) return _client->write(reinterpret_cast(buf), size); } -extern "C" uint32_t esp_micros_at_task_start(); +extern "C" void optimistic_yield(); int WiFiClient::available() { - static uint32_t lastPollTime = 0; - if (!_client) - return 0; - - if (lastPollTime > esp_micros_at_task_start()) - yield(); + int result = 0; - lastPollTime = micros(); + if (_client) { + result = _client->getSize(); + } - int result = _client->getSize(); + if (!result) { + optimistic_yield(); + } return result; } diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiServer.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiServer.cpp index 69ad4ff81a..8c5378cd51 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiServer.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiServer.cpp @@ -84,17 +84,15 @@ bool WiFiServer::getNoDelay(){ return tcp_nagle_disabled(_pcb); } -extern "C" uint32_t esp_micros_at_task_start(); - bool WiFiServer::hasClient(){ if (_unclaimed) return true; return false; } +extern "C" void optimistic_yield(); + WiFiClient WiFiServer::available(byte* status) { - static uint32_t lastPollTime = 0; - if (_unclaimed) { WiFiClient result(_unclaimed); @@ -103,9 +101,7 @@ WiFiClient WiFiServer::available(byte* status) return result; } - if (lastPollTime > esp_micros_at_task_start()) - yield(); - lastPollTime = micros(); + optimistic_yield(); return WiFiClient(); } diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp index 80b005556b..aa7e071d76 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp @@ -113,12 +113,22 @@ uint8_t WiFiUDP::beginMulticast(IPAddress interfaceAddr, IPAddress multicast, ui return 1; } +extern "C" void optimistic_yield(); + /* return number of bytes available in the current packet, will return zero if parsePacket hasn't been called yet */ int WiFiUDP::available() { - if (!_ctx) - return 0; - return static_cast(_ctx->getSize()); + int result = 0; + + if (_ctx) { + result = static_cast(_ctx->getSize()); + } + + if (!result) { + optimistic_yield(); + } + + return result; } /* Release any resources being used by this WiFiUDP instance */ diff --git a/hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp b/hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp index 7591592032..39a2526ba5 100644 --- a/hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp +++ b/hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp @@ -160,8 +160,16 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity){ return quantity; } +extern "C" void optimistic_yield(); + int TwoWire::available(void){ - return rxBufferLength - rxBufferIndex; + int result = rxBufferLength - rxBufferIndex; + + if (!result) { + optimistic_yield(); + } + + return result; } int TwoWire::read(void){ From 8ee16129fc646c4ec669d1487833dbad20b2e830 Mon Sep 17 00:00:00 2001 From: Makuna Date: Wed, 15 Jul 2015 15:06:41 -0700 Subject: [PATCH 2/3] never yield within an ISR --- .../esp8266/cores/esp8266/core_esp8266_main.cpp | 3 ++- hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp index 04ab9f116f..53f154bd0f 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp @@ -88,7 +88,8 @@ extern "C" void __yield() { extern "C" void yield(void) __attribute__ ((weak, alias("__yield"))); extern "C" void optimistic_yield() { - if (system_get_time() - g_micros_at_last_task_yield > OPTIMISTIC_YIELD_TIME_US) + if (!ETS_INTR_WITHINISR() && + (system_get_time() - g_micros_at_last_task_yield) > OPTIMISTIC_YIELD_TIME_US) { __yield(); } diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h index a96e2f0be7..8d7adbde3f 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h @@ -61,6 +61,14 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_DISABLE(inum) \ ets_isr_mask((1< 0); +} + inline uint32_t ETS_INTR_ENABLED(void) { uint32_t enabled; From 073f81fce9575f13bac7ba8a5b0645498a263088 Mon Sep 17 00:00:00 2001 From: Makuna Date: Wed, 15 Jul 2015 16:32:49 -0700 Subject: [PATCH 3/3] define in header remove extern from cpp files --- hardware/esp8266com/esp8266/cores/esp8266/Arduino.h | 1 + hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp | 2 -- hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp | 2 +- .../esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp | 2 -- .../esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiServer.cpp | 2 -- .../esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp | 2 -- hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp | 2 -- 7 files changed, 2 insertions(+), 11 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index c712bf756b..ad0e7cb36d 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h @@ -39,6 +39,7 @@ extern "C" { #include "twi.h" void yield(void); +void optimistic_yield(void); #define HIGH 0x1 #define LOW 0x0 diff --git a/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp b/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp index 7f1f2cc92b..493561a24e 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp @@ -551,8 +551,6 @@ bool HardwareSerial::isRxEnabled(void) { return _uart->rxEnabled; } -extern "C" void optimistic_yield(); - int HardwareSerial::available(void) { int result = 0; diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp index 53f154bd0f..ca78055696 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp @@ -87,7 +87,7 @@ extern "C" void __yield() { } extern "C" void yield(void) __attribute__ ((weak, alias("__yield"))); -extern "C" void optimistic_yield() { +extern "C" void optimistic_yield(void) { if (!ETS_INTR_WITHINISR() && (system_get_time() - g_micros_at_last_task_yield) > OPTIMISTIC_YIELD_TIME_US) { diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp index 4327b90416..083463444e 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -177,8 +177,6 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size) return _client->write(reinterpret_cast(buf), size); } -extern "C" void optimistic_yield(); - int WiFiClient::available() { int result = 0; diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiServer.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiServer.cpp index 8c5378cd51..cf975a330f 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiServer.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiServer.cpp @@ -89,8 +89,6 @@ bool WiFiServer::hasClient(){ return false; } -extern "C" void optimistic_yield(); - WiFiClient WiFiServer::available(byte* status) { if (_unclaimed) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp index aa7e071d76..71f8ff41a5 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp @@ -113,8 +113,6 @@ uint8_t WiFiUDP::beginMulticast(IPAddress interfaceAddr, IPAddress multicast, ui return 1; } -extern "C" void optimistic_yield(); - /* return number of bytes available in the current packet, will return zero if parsePacket hasn't been called yet */ int WiFiUDP::available() { diff --git a/hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp b/hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp index 39a2526ba5..84b4c8c224 100644 --- a/hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp +++ b/hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp @@ -160,8 +160,6 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity){ return quantity; } -extern "C" void optimistic_yield(); - int TwoWire::available(void){ int result = rxBufferLength - rxBufferIndex;