mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-07 14:05:21 +00:00
Require all implementations to provide a do_create(), a new ZephyrBinaryRunner abstract class method, and make create() itself concrete. This allows us to enforce common conventions related to individual runner capabilities as each runner provides to the core via RunnerCaps. For now, just enforce that: - common options related to capabilities are always added, so runners can't reuse them for different ends - common options provided for runners which don't support them emit sensible error messages that should be easy to diagnose and support Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
102 lines
3.6 KiB
Python
102 lines
3.6 KiB
Python
# Copyright (c) 2018 Roman Tataurov <diytronic@yandex.ru>
|
|
# Modified 2018 Tavish Naruka <tavishnaruka@gmail.com>
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
'''Runner for flashing with Black Magic Probe.'''
|
|
# https://github.com/blacksphere/blackmagic/wiki
|
|
|
|
import signal
|
|
|
|
from runners.core import ZephyrBinaryRunner, RunnerCaps
|
|
|
|
class BlackMagicProbeRunner(ZephyrBinaryRunner):
|
|
'''Runner front-end for Black Magic probe.'''
|
|
|
|
def __init__(self, cfg, gdb_serial):
|
|
super().__init__(cfg)
|
|
self.gdb = [cfg.gdb] if cfg.gdb else None
|
|
self.elf_file = cfg.elf_file
|
|
self.gdb_serial = gdb_serial
|
|
|
|
@classmethod
|
|
def name(cls):
|
|
return 'blackmagicprobe'
|
|
|
|
@classmethod
|
|
def capabilities(cls):
|
|
return RunnerCaps(commands={'flash', 'debug', 'attach'})
|
|
|
|
@classmethod
|
|
def do_create(cls, cfg, args):
|
|
return BlackMagicProbeRunner(cfg, args.gdb_serial)
|
|
|
|
@classmethod
|
|
def do_add_parser(cls, parser):
|
|
parser.add_argument('--gdb-serial', default='/dev/ttyACM0',
|
|
help='GDB serial port')
|
|
|
|
def bmp_flash(self, command, **kwargs):
|
|
if self.elf_file is None:
|
|
raise ValueError('Cannot debug; elf file is missing')
|
|
command = (self.gdb +
|
|
['-ex', "set confirm off",
|
|
'-ex', "target extended-remote {}".format(self.gdb_serial),
|
|
'-ex', "monitor swdp_scan",
|
|
'-ex', "attach 1",
|
|
'-ex', "load {}".format(self.elf_file),
|
|
'-ex', "kill",
|
|
'-ex', "quit",
|
|
'-silent'])
|
|
self.check_call(command)
|
|
|
|
def check_call_ignore_sigint(self, command):
|
|
previous = signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
try:
|
|
self.check_call(command)
|
|
finally:
|
|
signal.signal(signal.SIGINT, previous)
|
|
|
|
def bmp_attach(self, command, **kwargs):
|
|
if self.elf_file is None:
|
|
command = (self.gdb +
|
|
['-ex', "set confirm off",
|
|
'-ex', "target extended-remote {}".format(
|
|
self.gdb_serial),
|
|
'-ex', "monitor swdp_scan",
|
|
'-ex', "attach 1"])
|
|
else:
|
|
command = (self.gdb +
|
|
['-ex', "set confirm off",
|
|
'-ex', "target extended-remote {}".format(
|
|
self.gdb_serial),
|
|
'-ex', "monitor swdp_scan",
|
|
'-ex', "attach 1",
|
|
'-ex', "file {}".format(self.elf_file)])
|
|
self.check_call_ignore_sigint(command)
|
|
|
|
def bmp_debug(self, command, **kwargs):
|
|
if self.elf_file is None:
|
|
raise ValueError('Cannot debug; elf file is missing')
|
|
command = (self.gdb +
|
|
['-ex', "set confirm off",
|
|
'-ex', "target extended-remote {}".format(self.gdb_serial),
|
|
'-ex', "monitor swdp_scan",
|
|
'-ex', "attach 1",
|
|
'-ex', "file {}".format(self.elf_file),
|
|
'-ex', "load {}".format(self.elf_file)])
|
|
self.check_call_ignore_sigint(command)
|
|
|
|
def do_run(self, command, **kwargs):
|
|
if self.gdb is None:
|
|
raise ValueError('Cannot execute; gdb not specified')
|
|
self.require(self.gdb[0])
|
|
|
|
if command == 'flash':
|
|
self.bmp_flash(command, **kwargs)
|
|
elif command == 'debug':
|
|
self.bmp_debug(command, **kwargs)
|
|
elif command == 'attach':
|
|
self.bmp_attach(command, **kwargs)
|
|
else:
|
|
self.bmp_flash(command, **kwargs)
|