ESP32 asyncio run in _thread
I'm using MicroPython v1.22.0-preview.4.g9f835df35.dirty on an ESP32 device without PSRAM, with ESP-IDF v5.0.2.
The problem arises when running asyncio in a thread. Here are the steps that lead to the issue:
-
Run:
loop = asyncio.get_event_loop()
_ = _thread.stack_size(12 * 1024)
_thread.start_new_thread(loop.run_forever, ()) -
Connect to WIFI successfully.
Inside the loop, connect to MQTT using asyncio:
reader, writer = await asyncio.wait_for(asyncio.open_connection(self.addr, self.port), 5)
-
Run the WebREPL service.
-
Try connecting to WebREPL and typing commands or a lot time some "sdfsdfdsfds".
However, during this process, the following issues occur:
Loss of ping and disconnection from Wi-Fi:
Disconnected, received disassociation: no activity (4), signal strength -35
WebREPL raises an exception in the read() method and deactivates with the error:
OSError: [Errno 113] ECONNABORTED
<img width="922" alt="image" src="https://github.com/micropython/micropython/assets/34532/905fce67-49eb-4dd7-866e-6242e69bd590">
- Interestingly, when running the same code without a _thread, it works normally. Additionally, when using an ESP32 with PSRAM and thread, the code also works normally too.
V1.22 creating new thread leads to hangup
Dear micropython developers,
this morning I found about micropython V1.22 and tried this on my Raspberry Pico (non W). But unfortunately I had to find out that my programs stop when the second thread is created.
consider this boot.py to reproduce the issue:
import _thread
import machine
import asyncio
from time import sleep, sleep_ms
async def thread1task():
print("thread 1 started")
while True:
print("thread 1 talking ... ")
await asyncio.sleep(1)
def thread2task():
print("thread 2 started")
while True:
print("thread 2 talking ... ")
sleep(1)
if __name__ == "__main__":
try:
loop = asyncio.get_event_loop()
messagestart = const(">> starting script in ... ")
print(messagestart + f"3")
sleep(1)
print(messagestart + f"2")
sleep(1)
print(messagestart + f"1")
sleep(1)
print(">> Loop is starting")
taskobj = loop.create_task(thread1task())
print(">> starting second thread...")
_thread.start_new_thread(thread2task,())
print(">> running loop ...")
loop.run_forever()
except KeyboardInterrupt:
loop.stop()
_thread.exit() # does not work, code hangs
print(f"INTERRUPTED")
The hangup is not always at the exact same spot, but the "most" debug output I could receive was:
MPY: soft reboot
>> starting script in ... 3
>> starting script in ... 2
>> starting script in ... 1
>> Loop is starting
>> starting second thread...
>> running loop ...thread 2 started
thread 2 talking ...
After that the serial port is blocked, device does not react to CTRL+C or any other keys.
Executing the code above with V1.21 has no issues and runs forever as expected.