From 76bc57851bce3a49425e73f8047b7c3f5e8ea891 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Sun, 14 Apr 2019 08:56:51 +0200 Subject: [PATCH 1/4] litex_server: refactor parameters and to allow setting bind address In some cases, it can be useful to bind to "0.0.0.0" instead of "localhost". While adding bind address support, parameters passing has also been refactored to ease adding parameters in the future. --- litex/utils/litex_server.py | 84 +++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/litex/utils/litex_server.py b/litex/utils/litex_server.py index 8bb2f86f5..c89261b63 100755 --- a/litex/utils/litex_server.py +++ b/litex/utils/litex_server.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +import argparse + import sys import socket import time @@ -10,8 +12,9 @@ from litex.soc.tools.remote.etherbone import EtherboneIPC class RemoteServer(EtherboneIPC): - def __init__(self, comm, port=1234): + def __init__(self, comm, bind, port=1234): self.comm = comm + self.bind = bind self.port = port self.lock = False @@ -21,7 +24,7 @@ class RemoteServer(EtherboneIPC): self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) for i in range(32): try: - self.socket.bind(("localhost", self.port + i)) + self.socket.bind((bind, self.port + i)) break except: pass @@ -95,46 +98,57 @@ class RemoteServer(EtherboneIPC): def main(): print("LiteX remote server") - if len(sys.argv) < 2 or len(sys.argv) > 4: - print("usages:") - print("litex_server uart [port] [baudrate]") - print("litex_server udp [server] [server_port]") - print("litex_server pcie [bar]") - sys.exit() - comm = sys.argv[1] - if comm == "uart": + parser = argparse.ArgumentParser() + # Common arguments + parser.add_argument("--bind", default="localhost", + help="Host binding address") + + # UART arguments + parser.add_argument("--uart", action="store_true", + help="Select UART interface") + parser.add_argument("--uart-port", default="", + help="Set UART port") + parser.add_argument("--uart-baudrate", default=115200, + help="Set UART baudrate") + + # UDP arguments + parser.add_argument("--udp", action="store_true", + help="Select UDP interface") + parser.add_argument("--udp-ip", default="192.168.1.50", + help="Set UDP remote IP address") + parser.add_argument("--udp-port", default=1234, + help="Set UDP remote port") + + # PCIe arguments + parser.add_argument("--pcie", action="store_true", + help="Select PCIe interface") + parser.add_argument("--pcie-bar", default="", + help="Set PCIe BAR") + args = parser.parse_args() + + + if args.uart: from litex.soc.tools.remote import CommUART - uart_port = None - uart_baudrate = 115200 - if len(sys.argv) > 2: - uart_port = sys.argv[2] - if len(sys.argv) > 3: - uart_baudrate = int(float(sys.argv[3])) + uart_port = args.uart_port + uart_baudrate = int(float(args.uart_baudrate)) print("[CommUART] port: {} / baudrate: {} / ".format(uart_port, uart_baudrate), end="") comm = CommUART(uart_port, uart_baudrate) - elif comm == "udp": + elif args.udp: from litex.soc.tools.remote import CommUDP - server = "192.168.1.50" - server_port = 1234 - if len(sys.argv) > 2: - server = sys.argv[2] - if len(sys.argv) > 3: - server_port = int(sys.argv[3]) - print("[CommUDP] server: {} / port: {} / ".format(server, server_port), end="") - comm = CommUDP(server, server_port) - elif comm == "pcie": + udp_ip = args.udp_ip + udp_port = int(args.udp_port) + print("[CommUDP] ip: {} / port: {} / ".format(udp_ip, udp_port), end="") + comm = CommUDP(udp_ip, udp_port) + elif args.pcie: from litex.soc.tools.remote import CommPCIe - bar = "" - if len(sys.argv) > 2: - bar = sys.argv[2] - if len(sys.argv) > 3: - bar_size = int(sys.argv[3]) - print("[CommPCIe] bar: {} / ".format(bar), end="") - comm = CommPCIe(bar) + pcie_bar = args.pcie_bar + print("[CommPCIe] bar: {} / ".format(args.pcie_bar), end="") + comm = CommPCIe(args.pcie_bar) else: - raise NotImplementedError + parser.print_help() + exit() - server = RemoteServer(comm) + server = RemoteServer(comm, args.bind) server.open() server.start(4) try: From db11aec9610d176481e095d9a143918f9d7c8aa6 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Sun, 14 Apr 2019 12:11:37 +0200 Subject: [PATCH 2/4] litex_server: allow setting bind port, remove auto-incrementing on bind_port --- litex/utils/litex_server.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/litex/utils/litex_server.py b/litex/utils/litex_server.py index c89261b63..ba14d01d7 100755 --- a/litex/utils/litex_server.py +++ b/litex/utils/litex_server.py @@ -12,23 +12,18 @@ from litex.soc.tools.remote.etherbone import EtherboneIPC class RemoteServer(EtherboneIPC): - def __init__(self, comm, bind, port=1234): + def __init__(self, comm, bind_ip, bind_port=1234): self.comm = comm - self.bind = bind - self.port = port + self.bind_ip = bind_ip + self.bind_port = bind_port self.lock = False def open(self): if hasattr(self, "socket"): return self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - for i in range(32): - try: - self.socket.bind((bind, self.port + i)) - break - except: - pass - print("tcp port: {:d}".format(self.port + i)) + self.socket.bind((self.bind_ip, self.bind_port)) + print("tcp port: {:d}".format(self.bind_port)) self.socket.listen(1) self.comm.open() @@ -100,8 +95,10 @@ def main(): print("LiteX remote server") parser = argparse.ArgumentParser() # Common arguments - parser.add_argument("--bind", default="localhost", - help="Host binding address") + parser.add_argument("--bind-ip", default="localhost", + help="Host bind address") + parser.add_argument("--bind-port", default=1234, + help="Host bind port") # UART arguments parser.add_argument("--uart", action="store_true", @@ -148,7 +145,7 @@ def main(): parser.print_help() exit() - server = RemoteServer(comm, args.bind) + server = RemoteServer(comm, args.bind_ip, int(args.bind_port)) server.open() server.start(4) try: From be99083e2b64fc82d4398b9a16c29b10565742ae Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Sun, 14 Apr 2019 14:00:35 +0200 Subject: [PATCH 3/4] litex_server: add message and exit when mandarory arguments are missing. --- litex/utils/litex_server.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/litex/utils/litex_server.py b/litex/utils/litex_server.py index ba14d01d7..b5dcb8f3a 100755 --- a/litex/utils/litex_server.py +++ b/litex/utils/litex_server.py @@ -103,7 +103,7 @@ def main(): # UART arguments parser.add_argument("--uart", action="store_true", help="Select UART interface") - parser.add_argument("--uart-port", default="", + parser.add_argument("--uart-port", default=None, help="Set UART port") parser.add_argument("--uart-baudrate", default=115200, help="Set UART baudrate") @@ -119,13 +119,16 @@ def main(): # PCIe arguments parser.add_argument("--pcie", action="store_true", help="Select PCIe interface") - parser.add_argument("--pcie-bar", default="", + parser.add_argument("--pcie-bar", default=None, help="Set PCIe BAR") args = parser.parse_args() if args.uart: from litex.soc.tools.remote import CommUART + if args.uart_port is None: + print("Need to specify --uart-port, exiting.") + exit() uart_port = args.uart_port uart_baudrate = int(float(args.uart_baudrate)) print("[CommUART] port: {} / baudrate: {} / ".format(uart_port, uart_baudrate), end="") @@ -139,6 +142,9 @@ def main(): elif args.pcie: from litex.soc.tools.remote import CommPCIe pcie_bar = args.pcie_bar + if args.pcie_bar is None: + print("Need to speficy --pcie-bar, exiting.") + exit() print("[CommPCIe] bar: {} / ".format(args.pcie_bar), end="") comm = CommPCIe(args.pcie_bar) else: From a2bc4bb777dc19a4f6e9b67605834c0bc5904a3e Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 15 Apr 2019 08:23:27 +0200 Subject: [PATCH 4/4] litex_server: set socket.SO_REUSEPORT to avoid waiting 60s in case of unclean termination --- litex/utils/litex_server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/litex/utils/litex_server.py b/litex/utils/litex_server.py index b5dcb8f3a..f8c6b116e 100755 --- a/litex/utils/litex_server.py +++ b/litex/utils/litex_server.py @@ -22,6 +22,7 @@ class RemoteServer(EtherboneIPC): if hasattr(self, "socket"): return self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) self.socket.bind((self.bind_ip, self.bind_port)) print("tcp port: {:d}".format(self.bind_port)) self.socket.listen(1)