Skip to content

Commit 6296f21

Browse files
committed
Tutorial: document ThreadSafeFlag and remove irq_event.py.
1 parent 0dacf40 commit 6296f21

File tree

4 files changed

+137
-283
lines changed

4 files changed

+137
-283
lines changed

v3/docs/DRIVERS.md

Lines changed: 7 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ events.
1111
The asynchronous ADC supports pausing a task until the value read from an ADC
1212
goes outside defined bounds.
1313

14-
An IRQ_EVENT class provides a means of interfacing uasyncio to hard or soft
15-
interrupt service routines.
16-
1714
# 1. Contents
1815

1916
1. [Contents](./DRIVERS.md#1-contents)
@@ -27,10 +24,9 @@ interrupt service routines.
2724
5. [ADC monitoring](./DRIVERS.md#5-adc-monitoring) Pause until an ADC goes out of bounds
2825
5.1 [AADC class](./DRIVERS.md#51-aadc-class)
2926
5.2 [Design note](./DRIVERS.md#52-design-note)
30-
6. [IRQ_EVENT](./DRIVERS.md#6-irq_event) Interfacing to interrupt service routines.
31-
7. [Additional functions](./DRIVERS.md#7-additional-functions)
32-
7.1 [launch](./DRIVERS.md#71-launch) Run a coro or callback interchangeably
33-
7.2 [set_global_exception](./DRIVERS.md#72-set_global_exception) Simplify debugging with a global exception handler
27+
6. [Additional functions](./DRIVERS.md#6-additional-functions)
28+
6.1 [launch](./DRIVERS.md#61-launch) Run a coro or callback interchangeably
29+
6.2 [set_global_exception](./DRIVERS.md#62-set_global_exception) Simplify debugging with a global exception handler
3430

3531
###### [Tutorial](./TUTORIAL.md#contents)
3632

@@ -342,100 +338,11 @@ this for applications requiring rapid response.
342338

343339
###### [Contents](./DRIVERS.md#1-contents)
344340

345-
# 6. IRQ_EVENT
346-
347-
Interfacing an interrupt service routine to `uasyncio` requires care. It is
348-
invalid to issue `create_task` or to trigger an `Event` in an ISR as it can
349-
cause a race condition in the scheduler. It is intended that `Event` will
350-
become compatible with soft IRQ's in a future revison of `uasyncio`. See
351-
[iss 6415](https://github.com/micropython/micropython/issues/6415),
352-
[PR 6106](https://github.com/micropython/micropython/pull/6106) and
353-
[iss 5795](https://github.com/micropython/micropython/issues/5795).
354-
355-
Currently there are two ways of interfacing hard or soft IRQ's with `uasyncio`.
356-
One is to use a busy-wait loop as per the
357-
[Message](https://github.com/peterhinch/micropython-async/blob/master/v3/docs/TUTORIAL.md#36-message)
358-
primitive. A more efficient approach is to use this `IRQ_EVENT` class. The API
359-
is a subset of the `Event` class, so if official `Event` becomes thread-safe
360-
it may readily be substituted. The `IRQ_EVENT` class uses uses the `uasyncio`
361-
I/O mechanism to achieve thread-safe operation.
362-
363-
Unlike `Event` only one task can wait on an `IRQ_EVENT`.
364-
365-
Constructor:
366-
* This has no args.
367-
368-
Synchronous Methods:
369-
* `set()` Initiates the event. May be called from a hard or soft ISR. Returns
370-
fast.
371-
* `is_set()` Returns `True` if the irq_event is set.
372-
* `clear()` This does nothing; its purpose is to enable code to be written
373-
compatible with a future thread-safe `Event` class, with the ISR setting then
374-
immediately clearing the event.
375-
376-
Asynchronous Method:
377-
* `wait` Pause until irq_event is set. The irq_event is cleared.
378-
379-
A single task waits on the event by issuing `await irq_event.wait()`; execution
380-
pauses until the ISR issues `irq_event.set()`. Execution of the paused task
381-
resumes when it is next scheduled. Under current `uasyncio` (V3.0.0) scheduling
382-
of the paused task does not occur any faster than using busy-wait. In typical
383-
use the ISR services the interrupting device, saving received data, then sets
384-
the irq_event to trigger processing of the received data.
385-
386-
If interrupts occur faster than `uasyncio` can schedule the paused task, more
387-
than one interrupt may occur before the paused task runs.
388-
389-
Example usage (assumes a Pyboard with pins X1 and X2 linked):
390-
```python
391-
from machine import Pin
392-
from pyb import LED
393-
import uasyncio as asyncio
394-
import micropython
395-
from primitives.irq_event import IRQ_EVENT
396-
397-
micropython.alloc_emergency_exception_buf(100)
398-
399-
driver = Pin(Pin.board.X2, Pin.OUT)
400-
receiver = Pin(Pin.board.X1, Pin.IN)
401-
evt_rx = IRQ_EVENT() # IRQ_EVENT instance for receiving Pin
402-
403-
def pin_han(pin): # Hard IRQ handler. Typically services a device
404-
evt_rx.set() # then issues this which returns quickly
341+
# 6. Additional functions
405342

406-
receiver.irq(pin_han, Pin.IRQ_FALLING, hard=True) # Set up hard ISR
343+
## 6.1 Launch
407344

408-
async def pulse_gen(pin):
409-
while True:
410-
await asyncio.sleep_ms(500)
411-
pin(not pin())
412-
413-
async def red_handler(evt_rx, iterations):
414-
led = LED(1)
415-
for x in range(iterations):
416-
await evt_rx.wait() # Pause until next interrupt
417-
print(x)
418-
led.toggle()
419-
420-
async def irq_test(iterations):
421-
pg = asyncio.create_task(pulse_gen(driver))
422-
await red_handler(evt_rx, iterations)
423-
pg.cancel()
424-
425-
def test(iterations=20):
426-
try:
427-
asyncio.run(irq_test(iterations))
428-
finally:
429-
asyncio.new_event_loop()
430-
```
431-
432-
###### [Contents](./DRIVERS.md#1-contents)
433-
434-
# 7. Additional functions
435-
436-
## 7.1 Launch
437-
438-
Importe as follows:
345+
Import as follows:
439346
```python
440347
from primitives import launch
441348
```
@@ -445,7 +352,7 @@ runs it and returns the callback's return value. If a coro is passed, it is
445352
converted to a `task` and run asynchronously. The return value is the `task`
446353
instance. A usage example is in `primitives/switch.py`.
447354

448-
## 7.2 set_global_exception
355+
## 6.2 set_global_exception
449356

450357
Import as follows:
451358
```python

0 commit comments

Comments
 (0)