Skip to content

Commit

Permalink
debug: use TCL-RPC to fetch results of OpenOCD commands instead of pa…
Browse files Browse the repository at this point in the history
…rsing log file

Quick and dirty fix for #520
  • Loading branch information
aap-sc committed Nov 8, 2023
1 parent 96403c8 commit 3e381ec
Showing 1 changed file with 25 additions and 24 deletions.
49 changes: 25 additions & 24 deletions debug/testlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import traceback

import pexpect
import tty
import yaml

print_log_names = False
Expand Down Expand Up @@ -308,20 +309,16 @@ def __init__(self, server_cmd=None, config=None, debug=False, timeout=60,
cmd = shlex.split(server_cmd)
else:
cmd = ["openocd"]
if debug:
cmd.append("-d")

# This command needs to come before any config scripts on the command
# line, since they are executed in order.
cmd += [
# Tell OpenOCD to bind gdb to an unused, ephemeral port.
"--command", "gdb_port 0",
# We don't use the TCL server.
"--command", "tcl_port disabled",
# Put the regular command prompt in stdin. Don't listen on a port
# because it will conflict if multiple OpenOCD instances are running
# at the same time.
"--command", "telnet_port pipe",
# We create a socket for OpenOCD command line (TCL-RPC)
"--command", "tcl_port 0",
# don't use telnet
"--command", "telnet_port disabled",
]

if config:
Expand All @@ -331,6 +328,7 @@ def __init__(self, server_cmd=None, config=None, debug=False, timeout=60,
sys.exit(1)

cmd += ["-f", self.config_file]

if debug:
cmd.append("-d")

Expand Down Expand Up @@ -366,12 +364,18 @@ def __init__(self, server_cmd=None, config=None, debug=False, timeout=60,
logfile.flush()

self.gdb_ports = []
self.tclrpc_port = None
self.start(cmd, logfile, extra_env)

self.openocd_cli = pexpect.spawn(f"nc localhost {self.tclrpc_port}")
# TCL-RPC uses \x1a as a watermark for end of message. We set raw
# pty mode to disable translation of \x1a to EOF
tty.setraw(self.openocd_cli.child_fd)

def start(self, cmd, logfile, extra_env):
combined_env = {**os.environ, **extra_env}
# pylint: disable-next=consider-using-with
self.process = subprocess.Popen(cmd, stdin=subprocess.PIPE,
self.process = subprocess.Popen(cmd, stdin=None,
stdout=logfile, stderr=logfile, env=combined_env)

try:
Expand All @@ -383,11 +387,16 @@ def start(self, cmd, logfile, extra_env):
while True:
m = self.expect(
rb"(Listening on port (\d+) for gdb connections|"
rb"tcl server disabled)",
rb"Listening on port (\d+) for tcl connections)",
message="Waiting for OpenOCD to start up...")
if b"gdb" in m.group(1):
if b"gdb connections" in m.group(1):
self.gdb_ports.append(int(m.group(2)))
else:
elif b"tcl connections" in m.group(1):
if self.tclrpc_port:
raise TestLibError("unexpected re-definition of TCL-RPC port")
self.tclrpc_port = int(m.group(3))

if self.tclrpc_port and (len(self.gdb_ports) > 0):
break

if self.debug_openocd:
Expand Down Expand Up @@ -422,18 +431,10 @@ def smp(self):
def command(self, cmd):
"""Write the command to OpenOCD's stdin. Return the output of the
command, minus the prompt."""
self.process.stdin.write(f"{cmd}\n".encode())
self.process.stdin.flush()
m = self.expect(re.escape(f"{cmd}\n".encode()))

# The prompt isn't flushed to the log, so send a unique command that
# lets us find where output of the last command ends.
magic = f"# {self.command_count}x".encode()
self.command_count += 1
self.process.stdin.write(magic + b"\n")
self.process.stdin.flush()
m = self.expect(rb"(.*)^>\s*" + re.escape(magic))
return m.group(1)
self.openocd_cli.write(f"{cmd}\n\x1a")
self.openocd_cli.expect(rb"(.*)\x1a")
m = self.openocd_cli.match.group(1)
return m

def expect(self, regex, message=None):
"""Wait for the regex to match the log, and return the match object. If
Expand Down

0 comments on commit 3e381ec

Please sign in to comment.