1# Copyright (c) 2023 Nordic Semiconductor 2# SPDX-License-Identifier: Apache-2.0 3 4"""This file provides a ZephyrBinaryRunner that launches GDB and enables 5flashing (running) a native application.""" 6 7import argparse 8 9from runners.core import RunnerCaps, RunnerConfig, ZephyrBinaryRunner 10 11DEFAULT_GDB_PORT = 3333 12 13class NativeSimBinaryRunner(ZephyrBinaryRunner): 14 """Runs the ELF binary under GDB.""" 15 16 def __init__(self, cfg, 17 tui=False, 18 gdb_port=DEFAULT_GDB_PORT): 19 super().__init__(cfg) 20 self.gdb_port = gdb_port 21 22 if cfg.gdb is None: 23 self.gdb_cmd = None 24 else: 25 self.gdb_cmd = [cfg.gdb] + (['-tui'] if tui else []) 26 27 if self.cfg.gdb is None: 28 raise ValueError("The provided RunnerConfig is missing the required field 'gdb'.") 29 30 if self.cfg.exe_file is None: 31 raise ValueError("The provided RunnerConfig is missing the required field 'exe_file'.") 32 33 34 @classmethod 35 def name(cls): 36 return 'native' 37 38 @classmethod 39 def capabilities(cls): 40 return RunnerCaps(commands={'debug', 'debugserver', 'flash'}) 41 42 @classmethod 43 def do_add_parser(cls, parser: argparse.ArgumentParser): 44 parser.add_argument('--tui', default=False, action='store_true', 45 help='if given, GDB uses -tui') 46 parser.add_argument('--gdb-port', default=DEFAULT_GDB_PORT, 47 help=f'gdb port, defaults to {DEFAULT_GDB_PORT}') 48 49 @classmethod 50 def do_create(cls, cfg: RunnerConfig, args: argparse.Namespace) -> ZephyrBinaryRunner: 51 return NativeSimBinaryRunner(cfg, 52 tui=args.tui, 53 gdb_port=args.gdb_port) 54 55 def do_run(self, command: str, **kwargs): 56 if command == 'flash': 57 self.do_flash(**kwargs) 58 elif command == 'debug': 59 self.do_debug(**kwargs) 60 elif command == 'debugserver': 61 self.do_debugserver(**kwargs) 62 else: 63 raise AssertionError 64 65 def do_flash(self, **kwargs): 66 cmd = [self.cfg.exe_file] 67 self.check_call(cmd) 68 69 def do_debug(self, **kwargs): 70 # Clues to debug missing RunnerConfig values (in context of `west debug`): 71 # build/zephyr/runners.yaml is missing `gdb` or `elf_file`. 72 # board.cmake should have `board_finalize_runner_args(native)`. 73 # build/CMakeCache.txt should have `CMAKE_GDB`. 74 75 cmd = (self.gdb_cmd + ['--quiet', self.cfg.exe_file]) 76 self.check_call(cmd) 77 78 def do_debugserver(self, **kwargs): 79 cmd = (['gdbserver', f':{self.gdb_port}', self.cfg.exe_file]) 80 81 self.check_call(cmd) 82