1
- # 1. Asynchronous programming in MicroPython
1
+ # Asynchronous programming in MicroPython
2
2
3
3
CPython supports asynchronous programming via the ` asyncio ` library.
4
4
MicroPython provides ` uasyncio ` which is a subset of this, optimised for small
5
5
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.
8
7
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
11
9
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 ) .
13
12
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 ` .
18
17
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.
24
19
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
26
41
27
42
* [ A tutorial] ( ./TUTORIAL.md ) An introductory tutorial on asynchronous
28
43
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.
48
63
boards to communicate without using a UART. This is hardware agnostic but
49
64
slower than the I2C version.
50
65
51
- ## Resources specific to V2.0
52
-
53
- ### The fast_io variant
66
+ ## 1.2 The fast_io variant
54
67
55
68
This comprises two parts.
56
69
1 . The [ fast_io] ( ./FASTPOLL.md ) version of ` uasyncio ` is a "drop in"
@@ -59,85 +72,73 @@ This comprises two parts.
59
72
2 . An optional extension module enabling the [ fast_io] ( ./FASTPOLL.md ) version
60
73
to run with very low power draw. This is Pyboard-only including Pyboard D.
61
74
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.
75
81
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.
80
86
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.
92
92
93
- ### 3.1.1 Implications for this repository
93
+ ## 1.2.1 A Pyboard-only low power module
94
94
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.
99
100
100
- #### 3.1.1.2 Fast I/O
101
+ ## 1.3 Under the hood
101
102
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 ` .
103
105
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
111
107
112
- #### 3.1.1.3 Synchronisation Primitives
108
+ All solutions listed below work with stock ` uasyncio ` V2 or ` fast_io ` .
113
109
114
110
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 ` .
120
116
* ` 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 ` .
124
125
125
126
The ` Event ` class in ` asyn.py ` provides a nonstandard option to supply a data
126
127
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
128
133
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.
133
137
* ` Pushbutton `
134
138
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 )
139
140
140
- ## 3.2 The current version V2.0
141
+ # 2. Version 2.0 usage notes
141
142
142
143
These notes are intended for users familiar with ` asyncio ` under CPython.
143
144
@@ -168,13 +169,13 @@ It supports millisecond level timing with the following:
168
169
169
170
Classes ` Task ` and ` Future ` are not supported.
170
171
171
- ## 3. 2.1 Asynchronous I/O
172
+ ## 2.1 Asynchronous I/O
172
173
173
174
Asynchronous I/O (` StreamReader ` and ` StreamWriter ` classes) support devices
174
175
with streaming drivers, such as UARTs and sockets. It is now possible to write
175
176
streaming device drivers in Python.
176
177
177
- ## 3. 2.2 Time values
178
+ ## 2.2 Time values
178
179
179
180
For timing asyncio uses floating point values of seconds. The ` uasyncio.sleep `
180
181
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.
186
187
The ` loop.time ` method returns an integer number of milliseconds whereas
187
188
CPython returns a floating point number of seconds. ` call_at ` follows the
188
189
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