@@ -2076,20 +2076,32 @@ following methods: `ioctl`, `read`, `readline` and `write`. See
2076
2076
[ Writing streaming device drivers] ( ./TUTORIAL.md#64-writing-streaming-device-drivers )
2077
2077
for details on how such drivers may be written in Python.
2078
2078
2079
- A UART can receive data at any time. The stream I/O mechanism checks for pending
2080
- incoming characters whenever the scheduler has control. When a task is running
2081
- an interrupt service routine buffers incoming characters; these will be removed
2082
- when the task yields to the scheduler. Consequently UART applications should be
2083
- designed such that tasks minimise the time between yielding to the scheduler to
2084
- avoid buffer overflows and data loss. This can be ameliorated by using a larger
2085
- UART read buffer or a lower baudrate. Alternatively hardware flow control will
2086
- provide a solution if the data source supports it.
2079
+ ###### StreamReader read methods
2087
2080
2088
2081
The ` StreamReader ` read methods fall into two categories depending on whether
2089
2082
they wait for a specific end condition. Thus ` .readline ` pauses until a newline
2090
2083
byte has been received, ` .read(-1) ` waits for EOF, and ` readexactly ` waits for
2091
2084
a precise number of bytes. Other methods return the number of bytes available
2092
- at the time they are called (upto a maximum).
2085
+ at the time they are called (upto a maximum). Consider the following fragment:
2086
+ ``` python
2087
+ async def foo (device ):
2088
+ sr = StreamReader(device)
2089
+ data = sr.read(20 )
2090
+ ```
2091
+ When ` read ` is issued, task ` foo ` is descheduled. Other tasks are scheduled,
2092
+ resulting in a delay. During that period, depending on the stream source, bytes
2093
+ may be received. The hardware or the device driver may buffer the data, at some
2094
+ point flagging their availability. When the concurrent tasks permit, asyncio
2095
+ polls the device. If data is available ` foo ` is rescheduled and pending data is
2096
+ returned. It should be evident that the number of bytes returned and the
2097
+ duration of the pause are variable.
2098
+
2099
+ There are also implications for application and device driver design: in the
2100
+ period while the task is descheduled, incoming data must be buffered to avoid
2101
+ data loss. For example in the case of a UART an interrupt service routine
2102
+ buffers incoming characters. To avoid data loss the size of the read buffer
2103
+ should be set based on the maximum latency caused by other tasks along with the
2104
+ baudrate. The buffer size can be reduced if hardware flow control is available.
2093
2105
2094
2106
### 6.3.1 A UART driver example
2095
2107
0 commit comments