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

Pass timeout to optimistic_yield, add cont_can_yield check

This commit is contained in:
Ivan Grokhotkov 2015-07-20 15:48:25 +03:00
parent 01361fc4c8
commit e5d2ba5db8
11 changed files with 193 additions and 177 deletions

View File

@ -38,9 +38,6 @@ extern "C" {
#include "esp8266_peri.h" #include "esp8266_peri.h"
#include "twi.h" #include "twi.h"
void yield(void);
void optimistic_yield(void);
#define HIGH 0x1 #define HIGH 0x1
#define LOW 0x0 #define LOW 0x0
@ -207,6 +204,9 @@ void detachInterrupt(uint8_t);
void setup(void); void setup(void);
void loop(void); void loop(void);
void yield(void);
void optimistic_yield(uint32_t interval_us);
// Get the bit location within the hardware port of the given virtual pin. // Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration. // This comes from the pins_*.c file for the active board configuration.
#define digitalPinToPort(pin) (0) #define digitalPinToPort(pin) (0)

View File

@ -559,7 +559,7 @@ int HardwareSerial::available(void) {
} }
if (!result) { if (!result) {
optimistic_yield(); optimistic_yield(USD(_uart->uart_nr) / 128);
} }
return result; return result;

View File

@ -109,6 +109,9 @@ cont_norm:
l32i a2, a1, 4 l32i a2, a1, 4
/* sp <- cont_ctx.sp_ret */ /* sp <- cont_ctx.sp_ret */
l32i a1, a2, 4 l32i a1, a2, 4
/* 0 -> cont_ctx.pc_ret */
movi a4, 0
s32i a4, a2, 0
cont_ret: cont_ret:
/* restore registers */ /* restore registers */

View File

@ -21,6 +21,8 @@
#ifndef CONT_H_ #ifndef CONT_H_
#define CONT_H_ #define CONT_H_
#include <stdbool.h>
#ifndef CONT_STACKSIZE #ifndef CONT_STACKSIZE
#define CONT_STACKSIZE 4096 #define CONT_STACKSIZE 4096
#endif #endif
@ -58,4 +60,8 @@ void cont_yield(cont_t*);
// return 1 if guard bytes were overwritten. // return 1 if guard bytes were overwritten.
int cont_check(cont_t* cont); int cont_check(cont_t* cont);
// Check if yield() may be called. Returns true if we are running inside
// continuation stack
bool cont_can_yield(cont_t* cont);
#endif /* CONT_H_ */ #endif /* CONT_H_ */

View File

@ -19,6 +19,9 @@
*/ */
#include "cont.h" #include "cont.h"
#include <stddef.h>
#include "ets_sys.h"
#define CONT_STACKGUARD 0xfeefeffe #define CONT_STACKGUARD 0xfeefeffe
@ -34,3 +37,8 @@ int cont_check(cont_t* cont) {
return 0; return 0;
} }
bool cont_can_yield(cont_t* cont) {
return !ETS_INTR_WITHINISR() &&
cont->pc_ret != 0 && cont->pc_yield == 0;
}

View File

@ -64,16 +64,16 @@ extern void (*__init_array_end)(void);
cont_t g_cont __attribute__ ((aligned (16))); cont_t g_cont __attribute__ ((aligned (16)));
static os_event_t g_loop_queue[LOOP_QUEUE_SIZE]; static os_event_t g_loop_queue[LOOP_QUEUE_SIZE];
static uint32_t g_micros_at_last_task_yield; static uint32_t g_micros_at_task_start;
extern "C" void abort() { extern "C" void abort() {
while(1) { do {
} *((int*)0) = 0;
} while(true);
} }
extern "C" void esp_yield() { extern "C" void esp_yield() {
g_micros_at_last_task_yield = system_get_time();
cont_yield(&g_cont); cont_yield(&g_cont);
} }
@ -82,16 +82,22 @@ extern "C" void esp_schedule() {
} }
extern "C" void __yield() { extern "C" void __yield() {
if (cont_can_yield(&g_cont)) {
esp_schedule(); esp_schedule();
esp_yield(); esp_yield();
} }
else {
abort();
}
}
extern "C" void yield(void) __attribute__ ((weak, alias("__yield"))); extern "C" void yield(void) __attribute__ ((weak, alias("__yield")));
extern "C" void optimistic_yield(void) { extern "C" void optimistic_yield(uint32_t interval_us) {
if (!ETS_INTR_WITHINISR() && if (cont_can_yield(&g_cont) &&
(system_get_time() - g_micros_at_last_task_yield) > OPTIMISTIC_YIELD_TIME_US) (system_get_time() - g_micros_at_task_start) > interval_us)
{ {
__yield(); yield();
} }
} }
@ -107,10 +113,10 @@ static void loop_wrapper() {
} }
static void loop_task(os_event_t *events) { static void loop_task(os_event_t *events) {
g_micros_at_last_task_yield = system_get_time(); g_micros_at_task_start = system_get_time();
cont_run(&g_cont, &loop_wrapper); cont_run(&g_cont, &loop_wrapper);
if(cont_check(&g_cont) != 0) { if(cont_check(&g_cont) != 0) {
ets_printf("\r\nheap collided with sketch stack\r\n"); ets_printf("\r\nsketch stack overflow detected\r\n");
abort(); abort();
} }
} }
@ -127,13 +133,11 @@ void init_done() {
esp_schedule(); esp_schedule();
} }
extern "C" {
void user_init(void) { extern "C" void user_init(void) {
struct rst_info *rtc_info_ptr = system_get_rst_info(); struct rst_info *rtc_info_ptr = system_get_rst_info();
memcpy((void *) &resetInfo, (void *) rtc_info_ptr, sizeof(resetInfo)); memcpy((void *) &resetInfo, (void *) rtc_info_ptr, sizeof(resetInfo));
uart_div_modify(0, UART_CLK_FREQ / (115200)); uart_div_modify(0, UART_CLK_FREQ / (115200));
init(); init();
@ -148,5 +152,3 @@ void user_init(void) {
system_init_done_cb(&init_done); system_init_done_cb(&init_done);
} }
}

View File

@ -653,7 +653,7 @@ bool ESP8266WiFiClass::beginWPSConfig(void) {
disconnect(); disconnect();
DEBUGV("wps begin: %d\n", wps_type); DEBUGV("wps begin\n");
if(!wifi_wps_disable()) { if(!wifi_wps_disable()) {
DEBUGV("wps disable faild\n"); DEBUGV("wps disable faild\n");

View File

@ -179,14 +179,13 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size)
int WiFiClient::available() int WiFiClient::available()
{ {
int result = 0; if (!_client)
return false;
if (_client) { int result = _client->getSize();
result = _client->getSize();
}
if (!result) { if (!result) {
optimistic_yield(); optimistic_yield(100);
} }
return result; return result;
} }

View File

@ -99,7 +99,7 @@ WiFiClient WiFiServer::available(byte* status)
return result; return result;
} }
optimistic_yield(); optimistic_yield(1000);
return WiFiClient(); return WiFiClient();
} }
@ -161,4 +161,3 @@ void WiFiServer::_s_discard(void* server, ClientContext* ctx)
{ {
reinterpret_cast<WiFiServer*>(server)->_discard(ctx); reinterpret_cast<WiFiServer*>(server)->_discard(ctx);
} }

View File

@ -122,10 +122,6 @@ int WiFiUDP::available() {
result = static_cast<int>(_ctx->getSize()); result = static_cast<int>(_ctx->getSize());
} }
if (!result) {
optimistic_yield();
}
return result; return result;
} }
@ -207,8 +203,12 @@ int WiFiUDP::parsePacket()
{ {
if (!_ctx) if (!_ctx)
return 0; return 0;
if (!_ctx->next())
if (!_ctx->next()) {
optimistic_yield(100);
return 0; return 0;
}
return _ctx->getSize(); return _ctx->getSize();
} }
@ -284,4 +284,3 @@ void WiFiUDP::stopAll()
it->stop(); it->stop();
} }
} }

View File

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