Skip to content

Commit cbc1ef6

Browse files
committed
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().
1 parent 1154545 commit cbc1ef6

File tree

7 files changed

+58
-31
lines changed

7 files changed

+58
-31
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/HardwareSerial.cpp

+12-6
Original file line numberDiff line numberDiff line change
@@ -551,14 +551,20 @@ bool HardwareSerial::isRxEnabled(void) {
551551
return _uart->rxEnabled;
552552
}
553553

554+
extern "C" void optimistic_yield();
555+
554556
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;
557+
int result = 0;
558+
559+
if (_uart != NULL && _uart->rxEnabled) {
560+
result = static_cast<int>(_rx_buffer->getSize());
561561
}
562+
563+
if (!result) {
564+
optimistic_yield();
565+
}
566+
567+
return result;
562568
}
563569

564570
int HardwareSerial::peek(void) {

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

+12-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,13 @@ extern "C" void __yield() {
8787
}
8888
extern "C" void yield(void) __attribute__ ((weak, alias("__yield")));
8989

90+
extern "C" void optimistic_yield() {
91+
if (system_get_time() - g_micros_at_last_task_yield > OPTIMISTIC_YIELD_TIME_US)
92+
{
93+
__yield();
94+
}
95+
}
96+
9097
static void loop_wrapper() {
9198
static bool setup_done = false;
9299
if(!setup_done) {
@@ -99,7 +106,7 @@ static void loop_wrapper() {
99106
}
100107

101108
static void loop_task(os_event_t *events) {
102-
g_micros_at_task_start = system_get_time();
109+
g_micros_at_last_task_yield = system_get_time();
103110
cont_run(&g_cont, &loop_wrapper);
104111
if(cont_check(&g_cont) != 0) {
105112
ets_printf("\r\nheap collided with sketch stack\r\n");

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

+8-9
Original file line numberDiff line numberDiff line change
@@ -177,20 +177,19 @@ 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();
180+
extern "C" void optimistic_yield();
181181

182182
int WiFiClient::available()
183183
{
184-
static uint32_t lastPollTime = 0;
185-
if (!_client)
186-
return 0;
187-
188-
if (lastPollTime > esp_micros_at_task_start())
189-
yield();
184+
int result = 0;
190185

191-
lastPollTime = micros();
186+
if (_client) {
187+
result = _client->getSize();
188+
}
192189

193-
int result = _client->getSize();
190+
if (!result) {
191+
optimistic_yield();
192+
}
194193
return result;
195194
}
196195

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

+3-7
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,15 @@ 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

92+
extern "C" void optimistic_yield();
93+
9494
WiFiClient WiFiServer::available(byte* status)
9595
{
96-
static uint32_t lastPollTime = 0;
97-
9896
if (_unclaimed)
9997
{
10098
WiFiClient result(_unclaimed);
@@ -103,9 +101,7 @@ WiFiClient WiFiServer::available(byte* status)
103101
return result;
104102
}
105103

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

110106
return WiFiClient();
111107
}

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

+13-3
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,22 @@ uint8_t WiFiUDP::beginMulticast(IPAddress interfaceAddr, IPAddress multicast, ui
113113
return 1;
114114
}
115115

116+
extern "C" void optimistic_yield();
117+
116118
/* return number of bytes available in the current packet,
117119
will return zero if parsePacket hasn't been called yet */
118120
int WiFiUDP::available() {
119-
if (!_ctx)
120-
return 0;
121-
return static_cast<int>(_ctx->getSize());
121+
int result = 0;
122+
123+
if (_ctx) {
124+
result = static_cast<int>(_ctx->getSize());
125+
}
126+
127+
if (!result) {
128+
optimistic_yield();
129+
}
130+
131+
return result;
122132
}
123133

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

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,16 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity){
160160
return quantity;
161161
}
162162

163+
extern "C" void optimistic_yield();
164+
163165
int TwoWire::available(void){
164-
return rxBufferLength - rxBufferIndex;
166+
int result = rxBufferLength - rxBufferIndex;
167+
168+
if (!result) {
169+
optimistic_yield();
170+
}
171+
172+
return result;
165173
}
166174

167175
int TwoWire::read(void){

0 commit comments

Comments
 (0)