@@ -1612,15 +1612,20 @@ The behaviour is "correct": CPython `asyncio` behaves identically. Ref
1612
1612
At heart all interfaces between ` uasyncio ` and external asynchronous events
1613
1613
rely on polling. Hardware requiring a fast response may use an interrupt. But
1614
1614
the interface between the interrupt service routine (ISR) and a user task will
1615
- be polled. For example the ISR might trigger an ` Event ` or set a global flag,
1616
- while a task awaiting the outcome polls the object each time it is
1617
- scheduled .
1615
+ be polled. For example the ISR might set a global flag with the task awaiting
1616
+ the outcome polling the flag each time it is scheduled. This is explicit
1617
+ polling .
1618
1618
1619
- Polling may be effected in two ways, explicitly or implicitly. The latter is
1620
- performed by using the ` stream I/O ` mechanism which is a system designed for
1621
- stream devices such as UARTs and sockets. At its simplest explicit polling may
1622
- consist of code like this:
1619
+ Polling may also be effected implicitly. This is performed by using the
1620
+ ` stream I/O ` mechanism which is a system designed for stream devices such as
1621
+ UARTs and sockets.
1623
1622
1623
+ There are hazards involved with approaches to interfacing ISR's which appear to
1624
+ avoid polling. See [ the IRQ_EVENT class] ( ./DRIVERS.md#6-irq_event ) for details.
1625
+ This class is a thread-safe way to implement this interface with efficient
1626
+ implicit polling.
1627
+
1628
+ At its simplest explicit polling may consist of code like this:
1624
1629
``` python
1625
1630
async def poll_my_device ():
1626
1631
global my_flag # Set by device ISR
@@ -1631,17 +1636,17 @@ async def poll_my_device():
1631
1636
await asyncio.sleep(0 )
1632
1637
```
1633
1638
1634
- In place of a global, an instance variable, an ` Event ` object or an instance of
1635
- an awaitable class might be used. Explicit polling is discussed
1636
- further [ below] ( ./TUTORIAL.md#62-polling-hardware-with-a-task ) .
1639
+ In place of a global, an instance variable or an instance of an awaitable class
1640
+ might be used. Explicit polling is discussed further
1641
+ [ below] ( ./TUTORIAL.md#62-polling-hardware-with-a-task ) .
1637
1642
1638
1643
Implicit polling consists of designing the driver to behave like a stream I/O
1639
1644
device such as a socket or UART, using ` stream I/O ` . This polls devices using
1640
1645
Python's ` select.poll ` system: because the polling is done in C it is faster
1641
1646
and more efficient than explicit polling. The use of ` stream I/O ` is discussed
1642
1647
[ here] ( ./TUTORIAL.md#63-using-the-stream-mechanism ) .
1643
1648
1644
- Owing to its efficiency implicit polling benefits most fast I/O device drivers:
1649
+ Owing to its efficiency implicit polling most benefits fast I/O device drivers:
1645
1650
streaming drivers can be written for many devices not normally considered as
1646
1651
streaming devices [ section 6.4] ( ./TUTORIAL.md#64-writing-streaming-device-drivers ) .
1647
1652
@@ -1678,10 +1683,6 @@ and `sleep_ms()` functions. The worst-case value for this overrun may be
1678
1683
calculated by summing, for every other task, the worst-case execution time
1679
1684
between yielding to the scheduler.
1680
1685
1681
- The [ fast_io] ( ./FASTPOLL.md ) version of ` uasyncio ` in this repo provides a way
1682
- to ensure that stream I/O is polled on every iteration of the scheduler. It is
1683
- hoped that official ` uasyncio ` will adopt code to this effect in due course.
1684
-
1685
1686
###### [ Contents] ( ./TUTORIAL.md#contents )
1686
1687
1687
1688
## 6.2 Polling hardware with a task
@@ -1915,14 +1916,14 @@ class MillisecTimer(io.IOBase):
1915
1916
self .sreader = asyncio.StreamReader(self )
1916
1917
1917
1918
def __iter__ (self ):
1918
- await self .sreader.readline( )
1919
+ await self .sreader.read( 1 )
1919
1920
1920
1921
def __call__ (self , ms ):
1921
1922
self .end = utime.ticks_add(utime.ticks_ms(), ms)
1922
1923
return self
1923
1924
1924
- def readline (self ):
1925
- return b ' \n '
1925
+ def read (self , _ ):
1926
+ pass
1926
1927
1927
1928
def ioctl (self , req , arg ):
1928
1929
ret = MP_STREAM_ERROR
@@ -1979,10 +1980,9 @@ class PinCall(io.IOBase):
1979
1980
v = self .pinval
1980
1981
if v and self .cb_rise is not None :
1981
1982
self .cb_rise(* self .cbr_args)
1982
- return b ' \n '
1983
+ return
1983
1984
if not v and self .cb_fall is not None :
1984
1985
self .cb_fall(* self .cbf_args)
1985
- return b ' \n '
1986
1986
1987
1987
def ioctl (self , req , arg ):
1988
1988
ret = MP_STREAM_ERROR
0 commit comments