[SOLVED] uasyncio is blocked for 1 hour, 11 minutes on ESP8266
Posted: Fri May 17, 2019 12:21 pm
UPDATE may 22: Cause found. The blocking is caused by a bug in mp_hal_ticks_ms.
Under certain conditions uasyncio is blocked for exactly 1 hour, 11 minutes. This was first reported in topic viewtopic.php?f=16&t=4706. I have been running several esp8266 (ESP-12) units to try to reduce the code that shows this behavior. I came to this code:
Two coroutines:
'time_loop', that update self.seconds.
'show' that waits until self.seconds is 0 and then blinks a led for 30 times.
The watchdog watch if the seconds get updated. If not then self.buz (Buzzer) will get high.
If this code is run (just put this as main.py on your esp8266.) then after a while (can be hours or days) the coroutines are blocked for exactly 1 hour, 11 minutes. After this time the coroutines and the program will continue as if nothing happened.
(btw. 1 hour, 11 minutes is 2^32 uSeconds, that is one cycle of the internal system_get_time() call of the Espressif SDK.)
The same (more or less) code without uasyncio never blocks and this unit is running continuously for months without problems.
I have tried the standard 1.10 version of MP and the version of pfalcon (pycopy, uasyncio V2) but they al have the same behaviour.
How can this bug reported? I don't have a github account.
Anyone has suggestions to avoid this blocking without skipping uasyncio?
Under certain conditions uasyncio is blocked for exactly 1 hour, 11 minutes. This was first reported in topic viewtopic.php?f=16&t=4706. I have been running several esp8266 (ESP-12) units to try to reduce the code that shows this behavior. I came to this code:
Code: Select all
# Date: april 26, 2019
import utime
from machine import Pin, Timer
import uasyncio as asyncio
class MP_BUG:
def __init__(self):
Pin(12, Pin.OUT).value(0); Pin(13, Pin.OUT).value(0); Pin(15, Pin.OUT).value(0)
self.buz = Pin(5, Pin.OUT) ; self.buz.value(0)
self.led = Pin(2, Pin.OUT) ; self.led.value(1)
self.tim = Timer(-1)
self.tim.init(period=5000, callback=self.watchdog)
self.second = self.watchdog_second = 0
def watchdog(self, timer):
print("Watchdog", self.second)
if self.second == self.watchdog_second:
self.buz.value(1)
self.watchdog_second = self.second
def now_sec(self):
"""Return time."""
return utime.ticks_us()//1000000
@asyncio.coroutine
def time_loop(self):
print("Start coroutine time_loop")
while True:
now = utime.localtime(self.now_sec())
self.second = now[5]
await asyncio.sleep_ms(10)
@asyncio.coroutine
def show(self):
print("Start coroutine show")
while True:
while not self.second == 0:
await asyncio.sleep_ms(100)
# Blink 30 times
for i in range(30):
self.led.value(0)
await asyncio.sleep_ms(4)
self.led.value(1)
await asyncio.sleep_ms(50)
await asyncio.sleep(2)
def run(self):
loop = asyncio.get_event_loop()
loop.create_task(self.show())
loop.run_until_complete(self.time_loop())
stop = Pin(4, Pin.IN, Pin.PULL_UP)
utime.sleep(2)
if not stop.value() == 0:
mpbug = MP_BUG()
mpbug.run()
'time_loop', that update self.seconds.
'show' that waits until self.seconds is 0 and then blinks a led for 30 times.
The watchdog watch if the seconds get updated. If not then self.buz (Buzzer) will get high.
If this code is run (just put this as main.py on your esp8266.) then after a while (can be hours or days) the coroutines are blocked for exactly 1 hour, 11 minutes. After this time the coroutines and the program will continue as if nothing happened.
(btw. 1 hour, 11 minutes is 2^32 uSeconds, that is one cycle of the internal system_get_time() call of the Espressif SDK.)
The same (more or less) code without uasyncio never blocks and this unit is running continuously for months without problems.
I have tried the standard 1.10 version of MP and the version of pfalcon (pycopy, uasyncio V2) but they al have the same behaviour.
How can this bug reported? I don't have a github account.
Anyone has suggestions to avoid this blocking without skipping uasyncio?