scripts: zephyr_flash_debug: add debug support to pyocd
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
diff --git a/scripts/support/zephyr_flash_debug.py b/scripts/support/zephyr_flash_debug.py
index 2271a9a..343775b 100755
--- a/scripts/support/zephyr_flash_debug.py
+++ b/scripts/support/zephyr_flash_debug.py
@@ -855,17 +855,27 @@
check_call(cmd, self.debug)
+DEFAULT_PYOCD_GDB_PORT = 3333
+
+
class PyOcdBinaryRunner(ZephyrBinaryRunner):
'''Runner front-end for pyocd-flashtool.'''
def __init__(self, target, flashtool='pyocd-flashtool',
- bin_name=None,
+ gdb=None, gdbserver='pyocd-gdbserver',
+ gdb_port=DEFAULT_PYOCD_GDB_PORT, tui=None,
+ bin_name=None, elf_name=None,
board_id=None, daparg=None, debug=False):
super(PyOcdBinaryRunner, self).__init__(debug=debug)
self.target_args = ['-t', target]
self.flashtool = flashtool
+ self.gdb_cmd = [gdb] if gdb is not None else None
+ self.gdbserver = gdbserver
+ self.gdb_port = gdb_port
+ self.tui_args = [tui] if tui is not None else []
self.bin_name = bin_name
+ self.elf_name = elf_name
board_args = []
if board_id is not None:
@@ -878,15 +888,24 @@
self.daparg_args = daparg_args
def replaces_shell_script(shell_script, command):
- return command == 'flash' and shell_script == 'pyocd.sh'
+ return (command in {'flash', 'debug', 'debugserver'} and
+ shell_script == 'pyocd.sh')
+
+ def port_args(self):
+ return ['-p', str(self.gdb_port)]
def create_from_env(command, debug):
- '''Create flasher from environment.
+ '''Create runner from environment.
Required:
- PYOCD_TARGET: target override
+ Optional:
+
+ - PYOCD_DAPARG: arguments to pass to pyocd tool, default is none
+ - PYOCD_BOARD_ID: ID of board to flash, default is to prompt
+
Required for 'flash':
- O: build output directory
@@ -895,25 +914,44 @@
Optional for 'flash':
- PYOCD_FLASHTOOL: flash tool path, defaults to pyocd-flashtool
- - PYOCD_BOARD_ID: ID of board to flash, default is to guess
- - PYOCD_DAPARG: arguments to pass to flashtool, default is none
+
+ Required for 'debug':
+
+ - O: build output directory
+ - KERNEL_ELF_NAME
+ - GDB: gdb executable
+
+ Optional for 'debug', 'debugserver':
+
+ - TUI: one additional argument to GDB (e.g. -tui)
+ - GDB_PORT: pyocd gdb port, defaults to 3333
+ - PYOCD_GDBSERVER: gdb server executable, defaults to pyocd-gdbserver
'''
target = get_env_or_bail('PYOCD_TARGET')
o = os.environ.get('O', None)
bin_ = os.environ.get('KERNEL_BIN_NAME', None)
+ elf = os.environ.get('KERNEL_ELF_NAME', None)
bin_name = None
+ elf_name = None
if o is not None:
if bin_ is not None:
bin_name = path.join(o, bin_)
+ if elf is not None:
+ elf_name = path.join(o, elf)
flashtool = os.environ.get('PYOCD_FLASHTOOL', 'pyocd-flashtool')
board_id = os.environ.get('PYOCD_BOARD_ID', None)
daparg = os.environ.get('PYOCD_DAPARG', None)
+ gdb = os.environ.get('GDB', None)
+ gdbserver = os.environ.get('PYOCD_GDBSERVER', 'pyocd-gdbserver')
+ gdb_port = os.environ.get('GDB_PORT', DEFAULT_PYOCD_GDB_PORT)
+ tui = os.environ.get('TUI', None)
- return PyOcdBinaryRunner(target, flashtool=flashtool,
- bin_name=bin_name, board_id=board_id,
- daparg=daparg, debug=debug)
+ return PyOcdBinaryRunner(target, flashtool=flashtool, gdb=gdb,
+ gdbserver=gdbserver, gdb_port=gdb_port,
+ tui=tui, bin_name=bin_name, elf_name=elf_name,
+ board_id=board_id, daparg=daparg, debug=debug)
def run(self, command, **kwargs):
if command not in {'flash', 'debug', 'debugserver'}:
@@ -937,8 +975,32 @@
print('Flashing Target Device')
check_call(cmd, self.debug)
- def debug_debugserver(command, **kwargs):
- raise NotImplementedError()
+ def print_gdbserver_message(self):
+ print('pyOCD GDB server running on port {}'.format(self.gdb_port))
+
+ def debug_debugserver(self, command, **kwargs):
+ server_cmd = ([self.gdbserver] +
+ self.daparg_args +
+ self.port_args() +
+ self.target_args +
+ self.board_args)
+
+ if command == 'debugserver':
+ self.print_gdbserver_message()
+ check_call(server_cmd, self.debug)
+ else:
+ if self.gdb_cmd is None:
+ raise ValueError('Cannot debug; gdb is missing')
+ if self.elf_name is None:
+ raise ValueError('Cannot debug; elf is missing')
+ client_cmd = (self.gdb_cmd +
+ self.tui_args +
+ [self.elf_name] +
+ ['-ex', 'target remote :{}'.format(self.gdb_port),
+ '-ex', 'load',
+ '-ex', 'monitor reset halt'])
+ self.print_gdbserver_message()
+ self.run_server_and_client(server_cmd, client_cmd)
# TODO: Stop using environment variables.