Added retransmission logic for EtherBone UDP reads.
Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
This commit is contained in:
parent
80b309d1a4
commit
cb8e0193fc
|
@ -6,6 +6,7 @@
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
import socket
|
import socket
|
||||||
|
import time
|
||||||
|
|
||||||
from litex.tools.remote.etherbone import EtherbonePacket, EtherboneRecord
|
from litex.tools.remote.etherbone import EtherbonePacket, EtherboneRecord
|
||||||
from litex.tools.remote.etherbone import EtherboneReads, EtherboneWrites
|
from litex.tools.remote.etherbone import EtherboneReads, EtherboneWrites
|
||||||
|
@ -15,11 +16,12 @@ from litex.tools.remote.csr_builder import CSRBuilder
|
||||||
# CommUDP ------------------------------------------------------------------------------------------
|
# CommUDP ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
class CommUDP(CSRBuilder):
|
class CommUDP(CSRBuilder):
|
||||||
def __init__(self, server="192.168.1.50", port=1234, csr_csv=None, debug=False):
|
def __init__(self, server="192.168.1.50", port=1234, csr_csv=None, debug=False, timeout=1.0):
|
||||||
CSRBuilder.__init__(self, comm=self, csr_csv=csr_csv)
|
CSRBuilder.__init__(self, comm=self, csr_csv=csr_csv)
|
||||||
self.server = server
|
self.server = server
|
||||||
self.port = port
|
self.port = port
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
|
self.timeout= timeout
|
||||||
|
|
||||||
def open(self, probe=True):
|
def open(self, probe=True):
|
||||||
if hasattr(self, "socket"):
|
if hasattr(self, "socket"):
|
||||||
|
@ -37,24 +39,38 @@ class CommUDP(CSRBuilder):
|
||||||
del self.socket
|
del self.socket
|
||||||
|
|
||||||
def probe(self, ip, port, loose=False):
|
def probe(self, ip, port, loose=False):
|
||||||
try:
|
|
||||||
# Send probe request to server...
|
|
||||||
packet = EtherbonePacket()
|
|
||||||
packet.pf = 1
|
|
||||||
packet.encode()
|
|
||||||
packet.bytes += bytes([0x00, 0x00, 0x00, 0x00]) # Add Padding as payload.
|
|
||||||
self.socket.sendto(packet.bytes, (ip, port))
|
|
||||||
|
|
||||||
# ...and get/check server's response.
|
packet = EtherbonePacket()
|
||||||
datas, dummy = self.socket.recvfrom(8192)
|
packet.pf = 1
|
||||||
|
packet.encode()
|
||||||
|
packet.bytes += bytes([0x00, 0x00, 0x00, 0x00]) # Add Padding as payload.
|
||||||
|
|
||||||
|
retries = 10
|
||||||
|
self.socket.settimeout(self.timeout / retries)
|
||||||
|
|
||||||
|
# Send probe request to server and get server's response.
|
||||||
|
for r in range(retries):
|
||||||
|
try:
|
||||||
|
self.socket.sendto(packet.bytes, (ip, port))
|
||||||
|
datas, dummy = self.socket.recvfrom(8192)
|
||||||
|
except socket.timeout:
|
||||||
|
if self.debug:
|
||||||
|
print("socket timeout, retrying ({}/{})".format(r+1, retries))
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
datas = None
|
||||||
|
|
||||||
|
# Check the response
|
||||||
|
if not loose and datas is None:
|
||||||
|
raise Exception(f"Unable to probe Etherbone server at {self.server}.")
|
||||||
|
|
||||||
|
if datas is not None:
|
||||||
packet = EtherbonePacket(datas)
|
packet = EtherbonePacket(datas)
|
||||||
packet.decode()
|
packet.decode()
|
||||||
assert packet.pr == 1
|
assert packet.pr == 1
|
||||||
return 1
|
return 1
|
||||||
except:
|
|
||||||
if not loose:
|
|
||||||
self.close()
|
|
||||||
raise Exception(f"Unable to probe Etherbone server at {self.server}.")
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def scan(self, ip="192.168.1.x"):
|
def scan(self, ip="192.168.1.x"):
|
||||||
|
@ -77,9 +93,21 @@ class CommUDP(CSRBuilder):
|
||||||
packet.records = [record]
|
packet.records = [record]
|
||||||
packet.encode()
|
packet.encode()
|
||||||
|
|
||||||
self.socket.sendto(packet.bytes, (self.server, self.port))
|
retries = 10
|
||||||
|
|
||||||
|
self.socket.settimeout(self.timeout / retries)
|
||||||
|
for r in range(retries):
|
||||||
|
self.socket.sendto(packet.bytes, (self.server, self.port))
|
||||||
|
try:
|
||||||
|
datas, dummy = self.socket.recvfrom(8192)
|
||||||
|
except socket.timeout:
|
||||||
|
if self.debug:
|
||||||
|
print("socket timeout, retrying ({}/{})".format(r+1, retries))
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise socket.timeout
|
||||||
|
|
||||||
datas, dummy = self.socket.recvfrom(8192)
|
|
||||||
packet = EtherbonePacket(datas)
|
packet = EtherbonePacket(datas)
|
||||||
packet.decode()
|
packet.decode()
|
||||||
datas = packet.records.pop().writes.get_datas()
|
datas = packet.records.pop().writes.get_datas()
|
||||||
|
|
Loading…
Reference in New Issue