Skip to content

Commit 6e23468

Browse files
committed
Merge pull request #551 from Makuna/availbleYield
optimistic_yield()
2 parents 4849ff7 + 073f81f commit 6e23468

File tree

9 files changed

+59
-32
lines changed

9 files changed

+59
-32
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ Libraries that don't rely on low-level access to AVR registers should work well.
218218
- [PubSubClient](https://github.com/Imroy/pubsubclient) MQTT library by @Imroy.
219219
- [RTC](https://github.com/Makuna/Rtc) - Arduino Library for Ds1307 & Ds3231 compatible with esp8266.
220220
- [Souliss, Smart Home](https://github.com/souliss/souliss) - Framework for Smart Home based on Arduino, Android and openHAB.
221+
- [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.
221222

222223
#### Upload via serial port ####
223224
Pick the correct serial port.

hardware/esp8266com/esp8266/cores/esp8266/Arduino.h

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ extern "C" {
3939
#include "twi.h"
4040

4141
void yield(void);
42+
void optimistic_yield(void);
4243

4344
#define HIGH 0x1
4445
#define LOW 0x0

hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp

+10-6
Original file line numberDiff line numberDiff line change
@@ -552,13 +552,17 @@ bool HardwareSerial::isRxEnabled(void) {
552552
}
553553

554554
int HardwareSerial::available(void) {
555-
if(_uart == 0)
556-
return 0;
557-
if(_uart->rxEnabled) {
558-
return static_cast<int>(_rx_buffer->getSize());
559-
} else {
560-
return 0;
555+
int result = 0;
556+
557+
if (_uart != NULL && _uart->rxEnabled) {
558+
result = static_cast<int>(_rx_buffer->getSize());
559+
}
560+
561+
if (!result) {
562+
optimistic_yield();
561563
}
564+
565+
return result;
562566
}
563567

564568
int HardwareSerial::peek(void) {

hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp

+13-5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ extern "C" {
3434
#define LOOP_TASK_PRIORITY 0
3535
#define LOOP_QUEUE_SIZE 1
3636

37+
#define OPTIMISTIC_YIELD_TIME_US 16000
38+
3739
struct rst_info resetInfo;
3840

3941
int atexit(void (*func)()) {
@@ -62,18 +64,16 @@ extern void (*__init_array_end)(void);
6264
cont_t g_cont __attribute__ ((aligned (16)));
6365
static os_event_t g_loop_queue[LOOP_QUEUE_SIZE];
6466

65-
static uint32_t g_micros_at_task_start;
67+
static uint32_t g_micros_at_last_task_yield;
6668

67-
extern "C" uint32_t esp_micros_at_task_start() {
68-
return g_micros_at_task_start;
69-
}
7069

7170
extern "C" void abort() {
7271
while(1) {
7372
}
7473
}
7574

7675
extern "C" void esp_yield() {
76+
g_micros_at_last_task_yield = system_get_time();
7777
cont_yield(&g_cont);
7878
}
7979

@@ -87,6 +87,14 @@ extern "C" void __yield() {
8787
}
8888
extern "C" void yield(void) __attribute__ ((weak, alias("__yield")));
8989

90+
extern "C" void optimistic_yield(void) {
91+
if (!ETS_INTR_WITHINISR() &&
92+
(system_get_time() - g_micros_at_last_task_yield) > OPTIMISTIC_YIELD_TIME_US)
93+
{
94+
__yield();
95+
}
96+
}
97+
9098
static void loop_wrapper() {
9199
static bool setup_done = false;
92100
if(!setup_done) {
@@ -99,7 +107,7 @@ static void loop_wrapper() {
99107
}
100108

101109
static void loop_task(os_event_t *events) {
102-
g_micros_at_task_start = system_get_time();
110+
g_micros_at_last_task_yield = system_get_time();
103111
cont_run(&g_cont, &loop_wrapper);
104112
if(cont_check(&g_cont) != 0) {
105113
ets_printf("\r\nheap collided with sketch stack\r\n");

hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp

+7-10
Original file line numberDiff line numberDiff line change
@@ -177,20 +177,17 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size)
177177
return _client->write(reinterpret_cast<const char*>(buf), size);
178178
}
179179

180-
extern "C" uint32_t esp_micros_at_task_start();
181-
182180
int WiFiClient::available()
183181
{
184-
static uint32_t lastPollTime = 0;
185-
if (!_client)
186-
return 0;
182+
int result = 0;
187183

188-
if (lastPollTime > esp_micros_at_task_start())
189-
yield();
190-
191-
lastPollTime = micros();
184+
if (_client) {
185+
result = _client->getSize();
186+
}
192187

193-
int result = _client->getSize();
188+
if (!result) {
189+
optimistic_yield();
190+
}
194191
return result;
195192
}
196193

hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiServer.cpp

+1-7
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,13 @@ bool WiFiServer::getNoDelay(){
8484
return tcp_nagle_disabled(_pcb);
8585
}
8686

87-
extern "C" uint32_t esp_micros_at_task_start();
88-
8987
bool WiFiServer::hasClient(){
9088
if (_unclaimed) return true;
9189
return false;
9290
}
9391

9492
WiFiClient WiFiServer::available(byte* status)
9593
{
96-
static uint32_t lastPollTime = 0;
97-
9894
if (_unclaimed)
9995
{
10096
WiFiClient result(_unclaimed);
@@ -103,9 +99,7 @@ WiFiClient WiFiServer::available(byte* status)
10399
return result;
104100
}
105101

106-
if (lastPollTime > esp_micros_at_task_start())
107-
yield();
108-
lastPollTime = micros();
102+
optimistic_yield();
109103

110104
return WiFiClient();
111105
}

hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,17 @@ uint8_t WiFiUDP::beginMulticast(IPAddress interfaceAddr, IPAddress multicast, ui
116116
/* return number of bytes available in the current packet,
117117
will return zero if parsePacket hasn't been called yet */
118118
int WiFiUDP::available() {
119-
if (!_ctx)
120-
return 0;
121-
return static_cast<int>(_ctx->getSize());
119+
int result = 0;
120+
121+
if (_ctx) {
122+
result = static_cast<int>(_ctx->getSize());
123+
}
124+
125+
if (!result) {
126+
optimistic_yield();
127+
}
128+
129+
return result;
122130
}
123131

124132
/* Release any resources being used by this WiFiUDP instance */

hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,13 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity){
161161
}
162162

163163
int TwoWire::available(void){
164-
return rxBufferLength - rxBufferIndex;
164+
int result = rxBufferLength - rxBufferIndex;
165+
166+
if (!result) {
167+
optimistic_yield();
168+
}
169+
170+
return result;
165171
}
166172

167173
int TwoWire::read(void){

hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h

+8
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ typedef void (*int_handler_t)(void*);
6161
#define ETS_INTR_DISABLE(inum) \
6262
ets_isr_mask((1<<inum))
6363

64+
inline bool ETS_INTR_WITHINISR()
65+
{
66+
uint32_t ps;
67+
__asm__ __volatile__("rsr %0,ps":"=a" (ps));
68+
// PS.EXCM and PS.UM bit checks
69+
return ((ps & ((1 << 4) | (1 << 5))) > 0);
70+
}
71+
6472
inline uint32_t ETS_INTR_ENABLED(void)
6573
{
6674
uint32_t enabled;

0 commit comments

Comments
 (0)