Browse Source

esp8266: Update port to use new event functions.

This is necessary to avoid watchdog timeout in long i2c.scan(), as
previously machine_i2c.c would call MICROPY_EVENT_POLL_HOOK if
MICROPY_EVENT_POLL_HOOK_FAST was not available.

Compared to previous implementation, this implementation removes the
ets_event_poll() function and calls the SDK function ets_loop_iter() from
MICROPY_INTERNAL_EVENT_HOOK instead.  This allows using the port-agnostic
functions in more places.

There is a small behaviour change, which is that the event loop gets
iterated in a few more places (i.e. anywhere that mp_event_handle_nowait()
is called).  However, this looks like maybe only modselect.c - and is
probably good to process Wi-Fi events in that polling loop.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
pull/13096/head
Angus Gratton 11 months ago
committed by Damien George
parent
commit
73879734d9
  1. 7
      ports/esp8266/esp_mphal.c
  2. 3
      ports/esp8266/esp_mphal.h
  3. 2
      ports/esp8266/machine_uart.c
  4. 2
      ports/esp8266/modespnow.c
  5. 4
      ports/esp8266/modmachine.c
  6. 20
      ports/esp8266/mpconfigport.h
  7. 3
      ports/esp8266/uart.c

7
ports/esp8266/esp_mphal.c

@ -53,7 +53,7 @@ void mp_hal_init(void) {
void MP_FASTCODE(mp_hal_delay_us)(uint32_t us) {
uint32_t start = system_get_time();
while (system_get_time() - start < us) {
ets_event_poll();
mp_event_handle_nowait();
}
}
@ -122,11 +122,6 @@ uint64_t mp_hal_time_ns(void) {
return pyb_rtc_get_us_since_epoch() * 1000ULL;
}
void ets_event_poll(void) {
ets_loop_iter();
mp_handle_pending(true);
}
void __assert_func(const char *file, int line, const char *func, const char *expr) {
printf("assert:%s:%d:%s: %s\n", file, line, func, expr);
mp_raise_msg(&mp_type_AssertionError, MP_ERROR_TEXT("C-level assert"));

3
ports/esp8266/esp_mphal.h

@ -72,9 +72,6 @@ void dupterm_task_init();
uint32_t esp_disable_irq(void);
void esp_enable_irq(uint32_t state);
void ets_event_poll(void);
#define ETS_POLL_WHILE(cond) { while (cond) ets_event_poll(); }
// needed for machine.I2C
#include "osapi.h"
#define mp_hal_delay_us_fast(us) os_delay_us(us)

2
ports/esp8266/machine_uart.c

@ -300,7 +300,7 @@ STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uint
if (mp_machine_uart_txdone(self)) {
return 0;
}
MICROPY_EVENT_POLL_HOOK
mp_event_wait_ms(1);
} while (system_get_time() < timeout);
*errcode = MP_ETIMEDOUT;

2
ports/esp8266/modespnow.c

@ -285,7 +285,7 @@ static int ringbuf_get_bytes_wait(ringbuf_t *r, uint8_t *data, size_t len, mp_in
int status = 0;
while (((status = ringbuf_get_bytes(r, data, len)) == -1)
&& (timeout_ms < 0 || (mp_uint_t)(mp_hal_ticks_ms() - start) < (mp_uint_t)timeout_ms)) {
MICROPY_EVENT_POLL_HOOK;
mp_event_wait_ms(1);
}
return status;
}

4
ports/esp8266/modmachine.c

@ -91,7 +91,7 @@ STATIC mp_obj_t mp_machine_unique_id(void) {
STATIC void mp_machine_idle(void) {
asm ("waiti 0");
ets_event_poll(); // handle any events after possibly a long wait (eg feed WDT)
mp_event_handle_nowait(); // handle any events after possibly a long wait (eg feed WDT)
}
STATIC void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
@ -106,7 +106,7 @@ STATIC void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
uint32_t wifi_mode = wifi_get_opmode();
uint32_t start = system_get_time();
while (system_get_time() - start <= max_us) {
ets_event_poll();
mp_event_handle_nowait();
if (wifi_mode == NULL_MODE) {
// Can only idle if the wifi is off
asm ("waiti 0");

20
ports/esp8266/mpconfigport.h

@ -7,6 +7,7 @@
// Board-specific definitions
#include "mpconfigboard.h"
#include <stdbool.h>
#include <stdint.h>
// Set the rom feature level.
@ -116,13 +117,26 @@
#define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
#define MICROPY_ESP8266_APA102 (1)
#define MICROPY_EVENT_POLL_HOOK {ets_event_poll();}
// No blocking wait-for-event on ESP8266, only non-blocking pump of the "OS" event
// loop
//
// TODO: When TIMEOUT_MS==-1, it may be possible to have MICROPY_INTERNAL_WFE() call the "waiti" instruction.
// See mp_machine_idle() and mp_machine_lightsleep() in esp8266/modmachine.c
//
// Note: We have to scope the declaration of ets_loop_iter() here as there are multiple incompatible
// definitions at compile time between the SDK and axTLS!
#define MICROPY_INTERNAL_WFE(TIMEOUT_MS)
#define MICROPY_INTERNAL_EVENT_HOOK \
do { \
extern bool ets_loop_iter(void); \
ets_loop_iter(); \
} while (0)
#define MICROPY_VM_HOOK_COUNT (10)
#define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT;
#define MICROPY_VM_HOOK_POLL if (--vm_hook_divisor == 0) { \
vm_hook_divisor = MICROPY_VM_HOOK_COUNT; \
extern void ets_loop_iter(void); \
ets_loop_iter(); \
MICROPY_INTERNAL_EVENT_HOOK; \
}
#define MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_POLL
#define MICROPY_VM_HOOK_RETURN MICROPY_VM_HOOK_POLL

3
ports/esp8266/uart.c

@ -18,6 +18,7 @@
#include "c_types.h"
#include "user_interface.h"
#include "py/mphal.h"
#include "py/runtime.h"
// seems that this is missing in the Espressif SDK
#define FUNC_U0RXD 0
@ -218,7 +219,7 @@ bool ICACHE_FLASH_ATTR uart_rx_wait(uint32_t timeout_us) {
if (system_get_time() - start >= timeout_us) {
return false; // timeout
}
ets_event_poll();
mp_event_handle_nowait();
}
}

Loading…
Cancel
Save