Merge pull request #1504 from antmicro/msieron/fix-etherbone-timeouts
remote/comm_udp: Fix Etherbone timeout errors
This commit is contained in:
commit
4afee8535b
|
@ -22,13 +22,14 @@ class CommUDP(CSRBuilder):
|
||||||
self.port = port
|
self.port = port
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
self.timeout= timeout
|
self.timeout= timeout
|
||||||
|
self.read_counter = 0
|
||||||
|
|
||||||
def open(self, probe=True):
|
def open(self, probe=True):
|
||||||
if hasattr(self, "socket"):
|
if hasattr(self, "socket"):
|
||||||
return
|
return
|
||||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
self.socket.bind(("", self.port))
|
self.socket.bind(("", self.port))
|
||||||
self.socket.settimeout(2)
|
self.socket.settimeout(self.timeout)
|
||||||
if probe:
|
if probe:
|
||||||
self.probe(self.server, self.port)
|
self.probe(self.server, self.port)
|
||||||
|
|
||||||
|
@ -46,7 +47,6 @@ class CommUDP(CSRBuilder):
|
||||||
packet.bytes += bytes([0x00, 0x00, 0x00, 0x00]) # Add Padding as payload.
|
packet.bytes += bytes([0x00, 0x00, 0x00, 0x00]) # Add Padding as payload.
|
||||||
|
|
||||||
retries = 10
|
retries = 10
|
||||||
self.socket.settimeout(self.timeout / retries)
|
|
||||||
|
|
||||||
# Send probe request to server and get server's response.
|
# Send probe request to server and get server's response.
|
||||||
for r in range(retries):
|
for r in range(retries):
|
||||||
|
@ -76,44 +76,60 @@ class CommUDP(CSRBuilder):
|
||||||
def scan(self, ip="192.168.1.x"):
|
def scan(self, ip="192.168.1.x"):
|
||||||
print(f"Etherbone scan on {ip} network:")
|
print(f"Etherbone scan on {ip} network:")
|
||||||
ip = ip.replace("x", "{}")
|
ip = ip.replace("x", "{}")
|
||||||
self.socket.settimeout(0.01)
|
|
||||||
for i in range(1, 255):
|
for i in range(1, 255):
|
||||||
if self.probe(ip=ip.format(str(i)), port=self.port, loose=True):
|
if self.probe(ip=ip.format(str(i)), port=self.port, loose=True):
|
||||||
print("- {}".format(ip.format(i)))
|
print("- {}".format(ip.format(i)))
|
||||||
self.socket.settimeout(1)
|
|
||||||
|
|
||||||
def read(self, addr, length=None, burst="incr"):
|
def read(self, addr, length=None, burst="incr"):
|
||||||
assert burst == "incr"
|
assert burst == "incr"
|
||||||
length_int = 1 if length is None else length
|
length_int = 1 if length is None else length
|
||||||
record = EtherboneRecord()
|
|
||||||
record.reads = EtherboneReads(addrs=[addr+4*j for j in range(length_int)])
|
|
||||||
record.rcount = len(record.reads)
|
|
||||||
|
|
||||||
packet = EtherbonePacket()
|
|
||||||
packet.records = [record]
|
|
||||||
packet.encode()
|
|
||||||
|
|
||||||
retries = 10
|
retries = 10
|
||||||
|
|
||||||
self.socket.settimeout(self.timeout / retries)
|
|
||||||
for r in range(retries):
|
for r in range(retries):
|
||||||
|
self.read_counter += 1
|
||||||
|
|
||||||
|
record = EtherboneRecord()
|
||||||
|
record.reads = EtherboneReads(addrs=[addr+4*j for j in range(length_int)])
|
||||||
|
record.rcount = len(record.reads)
|
||||||
|
record.reads.base_ret_addr = self.read_counter
|
||||||
|
|
||||||
|
packet = EtherbonePacket()
|
||||||
|
packet.records = [record]
|
||||||
|
packet.encode()
|
||||||
|
|
||||||
self.socket.sendto(packet.bytes, (self.server, self.port))
|
self.socket.sendto(packet.bytes, (self.server, self.port))
|
||||||
try:
|
|
||||||
datas, dummy = self.socket.recvfrom(8192)
|
timed_out = False
|
||||||
except socket.timeout:
|
while True:
|
||||||
if self.debug:
|
try:
|
||||||
print("socket timeout, retrying ({}/{})".format(r+1, retries))
|
datas, dummy = self.socket.recvfrom(8192)
|
||||||
continue
|
except socket.timeout:
|
||||||
break
|
if self.debug:
|
||||||
|
print("socket timeout, retrying ({}/{})".format(r+1, retries))
|
||||||
|
timed_out = True
|
||||||
|
break
|
||||||
|
|
||||||
|
packet = EtherbonePacket(datas)
|
||||||
|
packet.decode()
|
||||||
|
record = packet.records.pop()
|
||||||
|
datas = record.writes.get_datas()
|
||||||
|
if record.writes.base_addr == self.read_counter:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.debug:
|
||||||
|
print(f"WARNING: request/response id mismatch: 0x{self.read_counter:08x} != 0x{record.writes.base_addr:08x}")
|
||||||
|
|
||||||
|
if not timed_out:
|
||||||
|
break
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise socket.timeout
|
raise socket.timeout
|
||||||
|
|
||||||
packet = EtherbonePacket(datas)
|
|
||||||
packet.decode()
|
|
||||||
datas = packet.records.pop().writes.get_datas()
|
|
||||||
if self.debug:
|
if self.debug:
|
||||||
for i, value in enumerate(datas):
|
for i, value in enumerate(datas):
|
||||||
print("read 0x{:08x} @ 0x{:08x}".format(value, addr + 4*i))
|
print("read 0x{:08x} @ 0x{:08x}".format(value, addr + 4*i))
|
||||||
|
|
||||||
return datas[0] if length is None else datas
|
return datas[0] if length is None else datas
|
||||||
|
|
||||||
def write(self, addr, datas):
|
def write(self, addr, datas):
|
||||||
|
|
Loading…
Reference in New Issue