mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
Pass timeout to optimistic_yield, add cont_can_yield check
This commit is contained in:
parent
01361fc4c8
commit
e5d2ba5db8
@ -38,9 +38,6 @@ extern "C" {
|
||||
#include "esp8266_peri.h"
|
||||
#include "twi.h"
|
||||
|
||||
void yield(void);
|
||||
void optimistic_yield(void);
|
||||
|
||||
#define HIGH 0x1
|
||||
#define LOW 0x0
|
||||
|
||||
@ -207,6 +204,9 @@ void detachInterrupt(uint8_t);
|
||||
void setup(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.
|
||||
// This comes from the pins_*.c file for the active board configuration.
|
||||
#define digitalPinToPort(pin) (0)
|
||||
|
@ -559,7 +559,7 @@ int HardwareSerial::available(void) {
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
optimistic_yield();
|
||||
optimistic_yield(USD(_uart->uart_nr) / 128);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -18,106 +18,109 @@
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.literal_position
|
||||
.global cont_yield
|
||||
.type cont_yield, @function
|
||||
.text
|
||||
.align 4
|
||||
.literal_position
|
||||
.global cont_yield
|
||||
.type cont_yield, @function
|
||||
cont_yield:
|
||||
/* a1: sp */
|
||||
/* a2: void* cont_ctx */
|
||||
/* adjust stack and save registers */
|
||||
addi a1, a1, -24
|
||||
s32i a12, a1, 0
|
||||
s32i a13, a1, 4
|
||||
s32i a14, a1, 8
|
||||
s32i a15, a1, 12
|
||||
s32i a0, a1, 16
|
||||
s32i a2, a1, 20
|
||||
/* a1: sp */
|
||||
/* a2: void* cont_ctx */
|
||||
/* adjust stack and save registers */
|
||||
addi a1, a1, -24
|
||||
s32i a12, a1, 0
|
||||
s32i a13, a1, 4
|
||||
s32i a14, a1, 8
|
||||
s32i a15, a1, 12
|
||||
s32i a0, a1, 16
|
||||
s32i a2, a1, 20
|
||||
|
||||
/* &cont_continue -> cont_ctx.pc_yield */
|
||||
movi a3, cont_continue
|
||||
s32i a3, a2, 8
|
||||
/* sp -> cont_ctx.sp_yield */
|
||||
s32i a1, a2, 12
|
||||
/* &cont_continue -> cont_ctx.pc_yield */
|
||||
movi a3, cont_continue
|
||||
s32i a3, a2, 8
|
||||
/* sp -> cont_ctx.sp_yield */
|
||||
s32i a1, a2, 12
|
||||
|
||||
/* a0 <- cont_ctx.pc_ret */
|
||||
l32i a0, a2, 0
|
||||
/* sp <- cont_ctx.sp_ret */
|
||||
l32i a1, a2, 4
|
||||
jx a0
|
||||
/* a0 <- cont_ctx.pc_ret */
|
||||
l32i a0, a2, 0
|
||||
/* sp <- cont_ctx.sp_ret */
|
||||
l32i a1, a2, 4
|
||||
jx a0
|
||||
|
||||
cont_continue:
|
||||
l32i a12, a1, 0
|
||||
l32i a13, a1, 4
|
||||
l32i a14, a1, 8
|
||||
l32i a15, a1, 12
|
||||
l32i a0, a1, 16
|
||||
l32i a2, a1, 20
|
||||
addi a1, a1, 24
|
||||
ret
|
||||
.size cont_yield, . - cont_yield
|
||||
l32i a12, a1, 0
|
||||
l32i a13, a1, 4
|
||||
l32i a14, a1, 8
|
||||
l32i a15, a1, 12
|
||||
l32i a0, a1, 16
|
||||
l32i a2, a1, 20
|
||||
addi a1, a1, 24
|
||||
ret
|
||||
.size cont_yield, . - cont_yield
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.literal_position
|
||||
.global cont_run
|
||||
.type cont_run, @function
|
||||
.text
|
||||
.align 4
|
||||
.literal_position
|
||||
.global cont_run
|
||||
.type cont_run, @function
|
||||
cont_run:
|
||||
/* a1: sp */
|
||||
/* a2: void* cont_ctx */
|
||||
/* a3: void (*pfn) */
|
||||
/* a1: sp */
|
||||
/* a2: void* cont_ctx */
|
||||
/* a3: void (*pfn) */
|
||||
|
||||
/* adjust stack and save registers */
|
||||
addi a1, a1, -20
|
||||
s32i a12, a1, 0
|
||||
s32i a13, a1, 4
|
||||
s32i a14, a1, 8
|
||||
s32i a15, a1, 12
|
||||
s32i a0, a1, 16
|
||||
/* adjust stack and save registers */
|
||||
addi a1, a1, -20
|
||||
s32i a12, a1, 0
|
||||
s32i a13, a1, 4
|
||||
s32i a14, a1, 8
|
||||
s32i a15, a1, 12
|
||||
s32i a0, a1, 16
|
||||
|
||||
/* cont_ret -> a4 -> cont_ctx.pc_ret*/
|
||||
movi a4, cont_ret
|
||||
s32i a4, a2, 0
|
||||
/* sp -> cont_ctx.sp_ret */
|
||||
s32i a1, a2, 4
|
||||
/* cont_ret -> a4 -> cont_ctx.pc_ret*/
|
||||
movi a4, cont_ret
|
||||
s32i a4, a2, 0
|
||||
/* sp -> cont_ctx.sp_ret */
|
||||
s32i a1, a2, 4
|
||||
|
||||
/* if cont_ctx.pc_yield != 0, goto cont_resume */
|
||||
l32i a4, a2, 8
|
||||
bnez a4, cont_resume
|
||||
/* else */
|
||||
/* set new stack*/
|
||||
l32i a1, a2, 16;
|
||||
/* goto pfn */
|
||||
movi a0, cont_norm
|
||||
jx a3
|
||||
/* if cont_ctx.pc_yield != 0, goto cont_resume */
|
||||
l32i a4, a2, 8
|
||||
bnez a4, cont_resume
|
||||
/* else */
|
||||
/* set new stack*/
|
||||
l32i a1, a2, 16;
|
||||
/* goto pfn */
|
||||
movi a0, cont_norm
|
||||
jx a3
|
||||
|
||||
cont_resume:
|
||||
/* a1 <- cont_ctx.sp_yield */
|
||||
l32i a1, a2, 12
|
||||
/* reset yield flag, 0 -> cont_ctx.pc_yield */
|
||||
movi a3, 0
|
||||
s32i a3, a2, 8
|
||||
/* jump to saved cont_ctx.pc_yield */
|
||||
movi a0, cont_ret
|
||||
jx a4
|
||||
/* a1 <- cont_ctx.sp_yield */
|
||||
l32i a1, a2, 12
|
||||
/* reset yield flag, 0 -> cont_ctx.pc_yield */
|
||||
movi a3, 0
|
||||
s32i a3, a2, 8
|
||||
/* jump to saved cont_ctx.pc_yield */
|
||||
movi a0, cont_ret
|
||||
jx a4
|
||||
|
||||
cont_norm:
|
||||
/* calculate pointer to cont_ctx.struct_start from sp */
|
||||
l32i a2, a1, 4
|
||||
/* sp <- cont_ctx.sp_ret */
|
||||
l32i a1, a2, 4
|
||||
/* calculate pointer to cont_ctx.struct_start from sp */
|
||||
l32i a2, a1, 4
|
||||
/* sp <- cont_ctx.sp_ret */
|
||||
l32i a1, a2, 4
|
||||
/* 0 -> cont_ctx.pc_ret */
|
||||
movi a4, 0
|
||||
s32i a4, a2, 0
|
||||
|
||||
cont_ret:
|
||||
/* restore registers */
|
||||
l32i a12, a1, 0
|
||||
l32i a13, a1, 4
|
||||
l32i a14, a1, 8
|
||||
l32i a15, a1, 12
|
||||
l32i a0, a1, 16
|
||||
/* adjust stack and return */
|
||||
addi a1, a1, 20
|
||||
ret
|
||||
.size cont_run, . - cont_run
|
||||
/* restore registers */
|
||||
l32i a12, a1, 0
|
||||
l32i a13, a1, 4
|
||||
l32i a14, a1, 8
|
||||
l32i a15, a1, 12
|
||||
l32i a0, a1, 16
|
||||
/* adjust stack and return */
|
||||
addi a1, a1, 20
|
||||
ret
|
||||
.size cont_run, . - cont_run
|
||||
|
@ -21,6 +21,8 @@
|
||||
#ifndef CONT_H_
|
||||
#define CONT_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef CONT_STACKSIZE
|
||||
#define CONT_STACKSIZE 4096
|
||||
#endif
|
||||
@ -58,4 +60,8 @@ void cont_yield(cont_t*);
|
||||
// return 1 if guard bytes were overwritten.
|
||||
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_ */
|
||||
|
@ -19,6 +19,9 @@
|
||||
*/
|
||||
|
||||
#include "cont.h"
|
||||
#include <stddef.h>
|
||||
#include "ets_sys.h"
|
||||
|
||||
|
||||
#define CONT_STACKGUARD 0xfeefeffe
|
||||
|
||||
@ -34,3 +37,8 @@ int cont_check(cont_t* cont) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool cont_can_yield(cont_t* cont) {
|
||||
return !ETS_INTR_WITHINISR() &&
|
||||
cont->pc_ret != 0 && cont->pc_yield == 0;
|
||||
}
|
||||
|
@ -64,16 +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_last_task_yield;
|
||||
static uint32_t g_micros_at_task_start;
|
||||
|
||||
|
||||
extern "C" void abort() {
|
||||
while(1) {
|
||||
}
|
||||
do {
|
||||
*((int*)0) = 0;
|
||||
} while(true);
|
||||
}
|
||||
|
||||
extern "C" void esp_yield() {
|
||||
g_micros_at_last_task_yield = system_get_time();
|
||||
cont_yield(&g_cont);
|
||||
}
|
||||
|
||||
@ -82,16 +82,22 @@ extern "C" void esp_schedule() {
|
||||
}
|
||||
|
||||
extern "C" void __yield() {
|
||||
esp_schedule();
|
||||
esp_yield();
|
||||
if (cont_can_yield(&g_cont)) {
|
||||
esp_schedule();
|
||||
esp_yield();
|
||||
}
|
||||
else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
extern "C" void optimistic_yield(uint32_t interval_us) {
|
||||
if (cont_can_yield(&g_cont) &&
|
||||
(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) {
|
||||
g_micros_at_last_task_yield = system_get_time();
|
||||
g_micros_at_task_start = 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");
|
||||
ets_printf("\r\nsketch stack overflow detected\r\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
@ -127,13 +133,11 @@ void init_done() {
|
||||
esp_schedule();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void user_init(void) {
|
||||
|
||||
extern "C" void user_init(void) {
|
||||
struct rst_info *rtc_info_ptr = system_get_rst_info();
|
||||
|
||||
memcpy((void *) &resetInfo, (void *) rtc_info_ptr, sizeof(resetInfo));
|
||||
|
||||
|
||||
uart_div_modify(0, UART_CLK_FREQ / (115200));
|
||||
|
||||
init();
|
||||
@ -143,10 +147,8 @@ void user_init(void) {
|
||||
cont_init(&g_cont);
|
||||
|
||||
system_os_task(loop_task,
|
||||
LOOP_TASK_PRIORITY, g_loop_queue,
|
||||
LOOP_QUEUE_SIZE);
|
||||
LOOP_TASK_PRIORITY, g_loop_queue,
|
||||
LOOP_QUEUE_SIZE);
|
||||
|
||||
system_init_done_cb(&init_done);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -653,7 +653,7 @@ bool ESP8266WiFiClass::beginWPSConfig(void) {
|
||||
|
||||
disconnect();
|
||||
|
||||
DEBUGV("wps begin: %d\n", wps_type);
|
||||
DEBUGV("wps begin\n");
|
||||
|
||||
if(!wifi_wps_disable()) {
|
||||
DEBUGV("wps disable faild\n");
|
||||
|
@ -179,14 +179,13 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size)
|
||||
|
||||
int WiFiClient::available()
|
||||
{
|
||||
int result = 0;
|
||||
if (!_client)
|
||||
return false;
|
||||
|
||||
if (_client) {
|
||||
result = _client->getSize();
|
||||
}
|
||||
int result = _client->getSize();
|
||||
|
||||
if (!result) {
|
||||
optimistic_yield();
|
||||
optimistic_yield(100);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ WiFiClient WiFiServer::available(byte* status)
|
||||
return result;
|
||||
}
|
||||
|
||||
optimistic_yield();
|
||||
optimistic_yield(1000);
|
||||
|
||||
return WiFiClient();
|
||||
}
|
||||
@ -161,4 +161,3 @@ void WiFiServer::_s_discard(void* server, ClientContext* ctx)
|
||||
{
|
||||
reinterpret_cast<WiFiServer*>(server)->_discard(ctx);
|
||||
}
|
||||
|
||||
|
@ -122,10 +122,6 @@ int WiFiUDP::available() {
|
||||
result = static_cast<int>(_ctx->getSize());
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
optimistic_yield();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -207,8 +203,12 @@ int WiFiUDP::parsePacket()
|
||||
{
|
||||
if (!_ctx)
|
||||
return 0;
|
||||
if (!_ctx->next())
|
||||
|
||||
if (!_ctx->next()) {
|
||||
optimistic_yield(100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _ctx->getSize();
|
||||
}
|
||||
|
||||
@ -284,4 +284,3 @@ void WiFiUDP::stopAll()
|
||||
it->stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,8 +65,8 @@ 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);
|
||||
// PS.EXCM bit check
|
||||
return ((ps & (1 << 4)) != 0);
|
||||
}
|
||||
|
||||
inline uint32_t ETS_INTR_ENABLED(void)
|
||||
|
Loading…
x
Reference in New Issue
Block a user