Skip to content

optimistic_yield() #551

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

Merged
merged 3 commits into from
Jul 16, 2015
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions hardware/esp8266com/esp8266/cores/esp8266/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ extern "C" {
#include "twi.h"

void yield(void);
void optimistic_yield(void);

#define HIGH 0x1
#define LOW 0x0
Expand Down
16 changes: 10 additions & 6 deletions hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,13 +552,17 @@ bool HardwareSerial::isRxEnabled(void) {
}

int HardwareSerial::available(void) {
if(_uart == 0)
return 0;
if(_uart->rxEnabled) {
return static_cast<int>(_rx_buffer->getSize());
} else {
return 0;
int result = 0;

if (_uart != NULL && _uart->rxEnabled) {
result = static_cast<int>(_rx_buffer->getSize());
}

if (!result) {
optimistic_yield();
}

return result;
}

int HardwareSerial::peek(void) {
Expand Down
18 changes: 13 additions & 5 deletions hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)()) {
Expand Down Expand Up @@ -62,18 +64,16 @@ 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) {
}
}

extern "C" void esp_yield() {
g_micros_at_last_task_yield = system_get_time();
cont_yield(&g_cont);
}

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

extern "C" void optimistic_yield(void) {
if (!ETS_INTR_WITHINISR() &&
(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) {
Expand All @@ -99,7 +107,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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,17 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size)
return _client->write(reinterpret_cast<const char*>(buf), size);
}

extern "C" uint32_t esp_micros_at_task_start();

int WiFiClient::available()
{
static uint32_t lastPollTime = 0;
if (!_client)
return 0;
int result = 0;

if (lastPollTime > esp_micros_at_task_start())
yield();

lastPollTime = micros();
if (_client) {
result = _client->getSize();
}

int result = _client->getSize();
if (!result) {
optimistic_yield();
}
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,13 @@ 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;
}

WiFiClient WiFiServer::available(byte* status)
{
static uint32_t lastPollTime = 0;

if (_unclaimed)
{
WiFiClient result(_unclaimed);
Expand All @@ -103,9 +99,7 @@ WiFiClient WiFiServer::available(byte* status)
return result;
}

if (lastPollTime > esp_micros_at_task_start())
yield();
lastPollTime = micros();
optimistic_yield();

return WiFiClient();
}
Expand Down
14 changes: 11 additions & 3 deletions hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,17 @@ uint8_t WiFiUDP::beginMulticast(IPAddress interfaceAddr, IPAddress multicast, ui
/* 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<int>(_ctx->getSize());
int result = 0;

if (_ctx) {
result = static_cast<int>(_ctx->getSize());
}

if (!result) {
optimistic_yield();
}

return result;
}

/* Release any resources being used by this WiFiUDP instance */
Expand Down
8 changes: 7 additions & 1 deletion hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,13 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity){
}

int TwoWire::available(void){
return rxBufferLength - rxBufferIndex;
int result = rxBufferLength - rxBufferIndex;

if (!result) {
optimistic_yield();
}

return result;
}

int TwoWire::read(void){
Expand Down
8 changes: 8 additions & 0 deletions hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ typedef void (*int_handler_t)(void*);
#define ETS_INTR_DISABLE(inum) \
ets_isr_mask((1<<inum))

inline bool ETS_INTR_WITHINISR()
{
uint32_t ps;
__asm__ __volatile__("rsr %0,ps":"=a" (ps));
// PS.EXCM and PS.UM bit checks
return ((ps & ((1 << 4) | (1 << 5))) > 0);
}

inline uint32_t ETS_INTR_ENABLED(void)
{
uint32_t enabled;
Expand Down