Skip to content

Commit 2f79789

Browse files
committed
Add uasyncio V3 information.
1 parent 3d545ff commit 2f79789

39 files changed

+7203
-124
lines changed

README.md

Lines changed: 83 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,43 @@
1-
# 1. Asynchronous programming in MicroPython
1+
# Asynchronous programming in MicroPython
22

33
CPython supports asynchronous programming via the `asyncio` library.
44
MicroPython provides `uasyncio` which is a subset of this, optimised for small
55
code size and high performance on bare metal targets. This repository provides
6-
documentation, tutorial material and code to aid in its effective use. It also
7-
contains an optional `fast_io` variant of `uasyncio`.
6+
documentation, tutorial material and code to aid in its effective use.
87

9-
Damien has completely rewritten `uasyncio`. V3.0 now been released, see
10-
[PR5332](https://github.com/micropython/micropython/pull/5332) and [below](./README.md#31-the-new-version).
8+
## uasyncio versions
119

12-
#### NOTE ON NEW RELEASE
10+
Damien has completely rewritten `uasyncio` which has been released as V3.0. See
11+
[PR5332](https://github.com/micropython/micropython/pull/5332).
1312

14-
The material in this repo largely relates to the old version V2.0 and I intend
15-
a substantial revision. I believe most of the material in the tutorial is still
16-
valid as it aims to be CPython compatible. I also expect the example scripts to
17-
work, based on testing with pre-release versions.
13+
There is currently a choice to be made over whether to run V2 or V3. To run V2,
14+
ensure your firmware build is official MicroPython V1.12 and follow the
15+
`uasyncio` installation instructions in [the V2 tutorial](./TUTORIAL.md). For
16+
V3, install the latest daily build which includes `uasyncio`.
1817

19-
There is currently no support for fast I/O scheduling: I/O is scheduled in
20-
round robin fashion with other tasks. There are situations where this is too
21-
slow, for example in I2S applications and ones involving multiple fast I/O
22-
streams. In these applications there is still a use case for the fast_io
23-
version. I hope that the new version acquires a facility to prioritise I/O.
18+
Resources for V3 and an updated tutorial may be found in the v3 directory.
2419

25-
## Resources
20+
### [Go to V3 docs](./v3/README.md)
21+
22+
The remainder of this document is for users of V2 and its `fast_io` variant.
23+
24+
# 1. uasyncio V2
25+
26+
This repo also contains an optional `fast_io` variant of `uasyncio` V2. This
27+
variant offers high I/O performance and also includes workrounds for many of
28+
the bugs in V2. (Bugs properly fixed in V3.)
29+
30+
## Reasons for running V2
31+
32+
In general I recommend V3, especially for new projects. It is better in every
33+
respect bar one: the `fast_io` variant of V2 currently offers superior I/O
34+
performance, relative both to V2 and V3.
35+
36+
The main reason for running official V2 is that many existing libraries have
37+
not yet been ported to V3. Some will run without change, but those using more
38+
advanced features of `uasyncio` may not.
39+
40+
## 1.1 Resources
2641

2742
* [A tutorial](./TUTORIAL.md) An introductory tutorial on asynchronous
2843
programming and the use of the `uasyncio` library.
@@ -48,9 +63,7 @@ version. I hope that the new version acquires a facility to prioritise I/O.
4863
boards to communicate without using a UART. This is hardware agnostic but
4964
slower than the I2C version.
5065

51-
## Resources specific to V2.0
52-
53-
### The fast_io variant
66+
## 1.2 The fast_io variant
5467

5568
This comprises two parts.
5669
1. The [fast_io](./FASTPOLL.md) version of `uasyncio` is a "drop in"
@@ -59,85 +72,73 @@ This comprises two parts.
5972
2. An optional extension module enabling the [fast_io](./FASTPOLL.md) version
6073
to run with very low power draw. This is Pyboard-only including Pyboard D.
6174

62-
### Under the hood
63-
64-
[Under the hood](./UNDER_THE_HOOD.md) A guide to help understand the V2
65-
`uasyncio` code. For scheduler geeks and those wishing to modify `uasyncio`.
66-
67-
# 2. Version and installation of uasyncio
68-
69-
The new release of `uasyncio` is pre-installed in current daily firmware
70-
builds.
71-
72-
# 3. uasyncio development state
73-
74-
## 3.1 The new version
75+
Official `uasyncio` suffers from high levels of latency when scheduling I/O in
76+
typical applications. It also has an issue which can cause bidirectional
77+
devices such as UART's to block. The `fast_io` version fixes the bug. It also
78+
provides a facility for reducing I/O latency which can substantially improve
79+
the performance of stream I/O drivers. It provides other features aimed at
80+
providing greater control over scheduling behaviour.
7581

76-
This complete rewrite of `uasyncio` supports CPython 3.8 syntax. A design aim
77-
is that it should be be a compatible subset of `asyncio`. Many applications
78-
using the coding style advocated in the tutorial will work unchanged. The
79-
following features will involve minor changes to application code:
82+
To take advantage of the reduced latency device drivers should be written to
83+
employ stream I/O. To operate at low latency they are simply run under the
84+
`fast_io` version. The [tutorial](./TUTORIAL.md#64-writing-streaming-device-drivers)
85+
has details of how to write streaming drivers.
8086

81-
* Task cancellation: `cancel` is now a method of a `Task` instance.
82-
* Event loop methods: `call_at`, `call_later`, `call_later_ms` and
83-
`call_soon` are no longer supported. In CPython docs these are
84-
[lightly deprecated](https://docs.python.org/3/library/asyncio-eventloop.html#preface)
85-
in application code; there are simple workrounds.
86-
* `yield` in coroutines should be replaced by `await asyncio.sleep_ms(0)`:
87-
this is in accord with CPython where `yield` will produce a syntax error.
88-
* Awaitable classes: currently under discussion. The `__iter__` method works
89-
but `yield` should be replaced by `await asyncio.sleep_ms(0)`. As yet I have
90-
found no way to write an awaitable class compatible with the new `uasyncio`
91-
and which does not throw syntax errors under CPython 3.8/`asyncio`.
87+
The current `fast_io` version 0.24 fixes an issue with task cancellation and
88+
timeouts. In `uasyncio` version 2.0, where a coroutine is waiting on a
89+
`sleep()` or on I/O, a timeout or cancellation is deferred until the coroutine
90+
is next scheduled. This introduces uncertainty into when the coroutine is
91+
stopped.
9292

93-
### 3.1.1 Implications for this repository
93+
## 1.2.1 A Pyboard-only low power module
9494

95-
It is planned to retain V2 under a different name. The new version fixes bugs
96-
which have been outstanding for a long time. In my view V2 is best viewed as
97-
deprecated. I will support V3 in a separate directory, the resources in this
98-
directory being retained for existing applications and users of V2 and fast_io.
95+
This is documented [here](./lowpower/README.md). In essence a Python file is
96+
placed on the device which configures the `fast_io` version of `uasyncio` to
97+
reduce power consumption at times when it is not busy. This provides a means of
98+
using `uasyncio` in battery powered projects. This is decidedly experimental:
99+
hopefully `uasyncio` V3 will introduce power saving in a less hacky manner.
99100

100-
#### 3.1.1.2 Fast I/O
101+
## 1.3 Under the hood
101102

102-
The `fast_io` fork is incompatible and will be relegated to the V2 directory.
103+
[Under the hood](./UNDER_THE_HOOD.md) A guide to help understand the V2
104+
`uasyncio` code. For scheduler geeks and those wishing to modify `uasyncio`.
103105

104-
The new version's design greatly simplifies the implementation of fast I/O:
105-
I therefore hope the new `uasyncio` will include it. The other principal aims
106-
were to provide workrounds for bugs now fixed. If `uasyncio` includes fast I/O
107-
there is no reason to fork the new version; other `fast_io` features will be
108-
lost unless Damien sees fit to implement them. The low priority task option is
109-
little used and arguably is ill-conceived: I will not be advocating for its
110-
inclusion.
106+
## 1.4 Synchronisation Primitives
111107

112-
#### 3.1.1.3 Synchronisation Primitives
108+
All solutions listed below work with stock `uasyncio` V2 or `fast_io`.
113109

114110
The CPython `asyncio` library supports these synchronisation primitives:
115-
* `Lock` - already incorporated in new `uasyncio`.
116-
* `Event` - already incorporated.
117-
* `gather` - already incorporated.
118-
* `Semaphore` and `BoundedSemaphore`. My classes work under new version.
119-
* `Condition`. Works under new version.
111+
* `Lock`
112+
* `Event`
113+
* `gather`
114+
* `Semaphore` and `BoundedSemaphore`.
115+
* `Condition`.
120116
* `Queue`. This was implemented by Paul Sokolvsky in `uasyncio.queues`.
121-
122-
Incorporating these will produce more efficient implementations; my solutions
123-
were designed to work with stock `uasyncio` V2.
117+
118+
See [CPython docs](https://docs.python.org/3/library/asyncio-sync.html).
119+
120+
The file `asyn.py` contains implementations of these, also
121+
* `Barrier` An additional synchronisation primitive.
122+
* Cancellation decorators and classes: these are workrounds for the bug where
123+
in V2 cancellation does not occur promptly.
124+
* Support for `gather`.
124125

125126
The `Event` class in `asyn.py` provides a nonstandard option to supply a data
126127
value to the `.set` method and to retrieve this with `.value`. It is also an
127-
awaitable class. I will support these by subclassing the native `Event`.
128+
awaitable class.
129+
130+
#### These are documented [here](./PRIMITIVES.md)
131+
132+
## 1.5 Switches, Pushbuttons and Timeouts
128133

129-
The following work under new and old versions:
130-
* `Barrier` (now adapted).
131-
* `Delay_ms` (this and the following in aswitch.py)
132-
* `Switch`
134+
The file `aswitch.py` provides support for:
135+
* `Delay_ms` A software retriggerable monostable or watchdog.
136+
* `Switch` Debounced switch and pushbutton classes with callbacks.
133137
* `Pushbutton`
134138

135-
The following were workrounds for bugs and omissions in V2 which are now fixed.
136-
They will be removed.
137-
* The cancellation decorators and classes (cancellation works as per CPython).
138-
* The nonstandard support for `gather` (now properly supported).
139+
#### It is documented [here](./DRIVERS.md)
139140

140-
## 3.2 The current version V2.0
141+
# 2. Version 2.0 usage notes
141142

142143
These notes are intended for users familiar with `asyncio` under CPython.
143144

@@ -168,13 +169,13 @@ It supports millisecond level timing with the following:
168169

169170
Classes `Task` and `Future` are not supported.
170171

171-
## 3.2.1 Asynchronous I/O
172+
## 2.1 Asynchronous I/O
172173

173174
Asynchronous I/O (`StreamReader` and `StreamWriter` classes) support devices
174175
with streaming drivers, such as UARTs and sockets. It is now possible to write
175176
streaming device drivers in Python.
176177

177-
## 3.2.2 Time values
178+
## 2.2 Time values
178179

179180
For timing asyncio uses floating point values of seconds. The `uasyncio.sleep`
180181
method accepts floats (including sub-second values) or integers. Note that in
@@ -186,45 +187,3 @@ millisecond level functions (with integer arguments) employed where necessary.
186187
The `loop.time` method returns an integer number of milliseconds whereas
187188
CPython returns a floating point number of seconds. `call_at` follows the
188189
same convention.
189-
190-
# 4. The "fast_io" version.
191-
192-
Official `uasyncio` suffers from high levels of latency when scheduling I/O in
193-
typical applications. It also has an issue which can cause bidirectional
194-
devices such as UART's to block. The `fast_io` version fixes the bug. It also
195-
provides a facility for reducing I/O latency which can substantially improve
196-
the performance of stream I/O drivers. It provides other features aimed at
197-
providing greater control over scheduling behaviour.
198-
199-
To take advantage of the reduced latency device drivers should be written to
200-
employ stream I/O. To operate at low latency they are simply run under the
201-
`fast_io` version. The [tutorial](./TUTORIAL.md#64-writing-streaming-device-drivers)
202-
has details of how to write streaming drivers.
203-
204-
The current `fast_io` version 0.24 fixes an issue with task cancellation and
205-
timeouts. In `uasyncio` version 2.0, where a coroutine is waiting on a
206-
`sleep()` or on I/O, a timeout or cancellation is deferred until the coroutine
207-
is next scheduled. This introduces uncertainty into when the coroutine is
208-
stopped. This issue is also addressed in Paul Sokolovsky's fork.
209-
210-
## 4.1 A Pyboard-only low power module
211-
212-
This is documented [here](./lowpower/README.md). In essence a Python file is
213-
placed on the device which configures the `fast_io` version of `uasyncio` to
214-
reduce power consumption at times when it is not busy. This provides a means of
215-
using `uasyncio` in battery powered projects.
216-
217-
# 5. The asyn.py library
218-
219-
This library ([docs](./PRIMITIVES.md)) provides 'micro' implementations of the
220-
`asyncio` synchronisation primitives.
221-
[CPython docs](https://docs.python.org/3/library/asyncio-sync.html)
222-
223-
It also supports a `Barrier` class to facilitate coroutine synchronisation.
224-
225-
Coroutine cancellation is performed in an efficient manner in `uasyncio`. The
226-
`asyn` library uses this, further enabling the cancelling coro to pause until
227-
cancellation is complete. It also provides a means of checking the 'running'
228-
status of individual coroutines.
229-
230-
A lightweight implementation of `asyncio.gather` is provided.

0 commit comments

Comments
 (0)