Python for microcontrollers and structured concurrency

I’m one of the core developers of CircuitPython, developed by Adafruit. It’s a friendly fork of MicroPython. For concurrency, MicroPython has a version of asyncio called uasyncio, and also has Python-based hardware interrupt handlers, which must be written carefully to avoid storage management issues.

We (and MicroPython) come to the concurrency world not so much from trying to do network I/O and the like, but to process real-time events, or schedule things in a time manner (e.g., reading a sensor at a fixed interval). CircuitPython’s emphasis is on the educational market and use by non-professional programmers. We’ve kind of despaired at introducing asyncio or interrupt handlers for concurrent programming, yet at the same time, people often ask for this capability, usually by describing mechanisms (hardware interrupt handlers) rather than functionality (handling asynchronous events).

We have avoided providing uasyncio or interrupts for CircuitPython up to now, because it just seems too painful for our audience. For now, we just suggest people do polling. For async events that must be handled, we provide native modules that implement specific functionality (e.g., reading pulse trains). But in the long run, we want to provide simple but usable asynchronous event and concurrency handling.

We have been discussing concurrency possibilities in github: github.com/adafruit/circuitpython/issues/1380. I have made a few strawman proposals there (see the when module especially), and Noralf Trønnes (github . com/notro/) and Bernhard Boser (github . com/bboser) have also added their thoughts about some work they’ve done independently:

github . com/adafruit/circuitpython/pull/1415 (@notro)
github . com/bboser/eventio
github . com/bboser/iotpython

Recently, I started reading about curio and trio, and have gotten pretty excited about the “structured concurrency” thinking I see here, because I think it matches our thinking a lot more, especially in terms of our user audience.

We’d welcome your thoughts about this, either here or in our issues. We’ll also be at PyCon in Cleveland. I’ll leave a note in the PyCon 2019 thread in this forum as well. Thanks.

[Aplogies: I’ve had to mangle the links above because I can only insert two as a new poster.]

4 Likes

I suspect Trio would be great for this use case-- assuming all the the Python user code is run from a single thread.

I’ve witnessed a large group of casual programmers get along fine with the Trio API given reasonable guide rails (examples, templates, basic tutorials).

I’m not sure about your proposed when API. In any case it’s quite easy to build encapsulation organically as your uses grow.

Trio performs well and is exceptional at keeping concurrency manageable.

I have ported (a fork of) the Trio core to MicroPython.

There’s a ton of stuff missing (the worst offender: going from an interrupt handler to a Trio “async for” loop), but I think it’d be a good base to move forward with.

You’d have to backport at least one fix from MicroPython.

The code is in git@github.com:smurfix/trio.git, “micro” branch.

1 Like