Skip to content
Snippets Groups Projects
Commit ee21ca65 authored by Martin Teichmann's avatar Martin Teichmann
Browse files

don't wait for a response before sending next

until now we only had one asynchronous packet on the wire.
This allows to send them as fast as possible, waiting for them
in bulk.
parent bd90b716
No related branches found
No related tags found
No related merge requests found
...@@ -27,8 +27,8 @@ Low-level access to EtherCAT ...@@ -27,8 +27,8 @@ Low-level access to EtherCAT
this modules contains the code to actually talk to EtherCAT terminals. this modules contains the code to actually talk to EtherCAT terminals.
""" """
from asyncio import ( from asyncio import (
ensure_future, Event, Future, gather, get_event_loop, Protocol, Queue, CancelledError, ensure_future, Event, Future, gather, get_event_loop,
Lock) Protocol, Queue, Lock)
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from enum import Enum, IntEnum from enum import Enum, IntEnum
from itertools import count from itertools import count
...@@ -305,26 +305,41 @@ class EtherCat(Protocol): ...@@ -305,26 +305,41 @@ class EtherCat(Protocol):
This method runs while we are connected, takes the datagrams This method runs while we are connected, takes the datagrams
to be sent from a queue, packs them in a packet and ships them to be sent from a queue, packs them in a packet and ships them
out. """ out. """
packet = Packet() try:
dgrams = [] packet = Packet()
while True: dgrams = []
*dgram, future = await self.send_queue.get() while True:
lastsize = packet.size *dgram, future = await self.send_queue.get()
packet.append(*dgram) lastsize = packet.size
dgrams.append((lastsize + 10, packet.size - 2, future)) packet.append(*dgram)
if packet.full() or self.send_queue.empty(): dgrams.append((lastsize + 10, packet.size - 2, future))
data = await self.roundtrip_packet(packet) if packet.full() or self.send_queue.empty():
for start, stop, future in dgrams: ensure_future(self.process_packet(dgrams, packet))
wkc, = unpack("<H", data[stop:stop+2]) dgrams = []
if wkc == 0: packet = Packet()
future.set_exception( except CancelledError:
EtherCatError("datagram was not processed")) raise
elif not future.done(): except Exception:
future.set_result(data[start:stop]) logging.exception("sendloop failed")
else: raise
logging.info("future already done, dropped datagram")
dgrams = [] async def process_packet(self, dgrams, packet):
packet = Packet() try:
data = await self.roundtrip_packet(packet)
for start, stop, future in dgrams:
wkc, = unpack("<H", data[stop:stop+2])
if wkc == 0:
future.set_exception(
EtherCatError("datagram was not processed"))
elif not future.done():
future.set_result(data[start:stop])
else:
logging.info("future already done, dropped datagram")
except CancelledError:
raise
except Exception:
logging.exception("process_packet failed")
raise
async def roundtrip_packet(self, packet): async def roundtrip_packet(self, packet):
"""Send a packet and return the response """Send a packet and return the response
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment