scripts: refactor flash/debug scripts to remove "shell"

The Python-based runners have replaced the old shell scripts. Refactor
the build system accordingly:

- FLASH_SCRIPT is now BOARD_FLASH_RUNNER
- DEBUG_SCRIPT is now BOARD_DEBUG_RUNNER

The values, rather than being the names of files, are now the names of
runners in scripts/support/runner. They are still short, descriptive
names like "openocd", "jlink", "em-starterkit", etc.

Adjust the zephyr_flash_debug.py call and runner internals
accordingly. Have each runner class report a name and the commands it
can handle. This lets us move some boilerplate from each do_run()
method into the common run() routine, and enables further improvements
in future patches.

The handles_command() method is temporary, and will be replaced by a
more general mechanism for describing runner capabilities in a
subsequent patch. The initial use case for extending this is to add
device tree awareness to the runners.

To try to avoid user confusion, abort the configuration if an
xxx_SCRIPT is defined.

Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
This commit is contained in:
Marti Bolivar 2017-11-16 13:32:00 -05:00 committed by Anas Nashif
commit e33ec242fd
49 changed files with 222 additions and 179 deletions

View file

@ -1,5 +1,5 @@
if(DEFINED ENV{ZEPHYR_FLASH_OVER_DFU})
set(FLASH_SCRIPT dfuutil.sh)
set(BOARD_FLASH_RUNNER dfu-util)
set(DFUUTIL_PID 8087:0aba)
set(DFUUTIL_ALT sensor_core)
@ -11,10 +11,10 @@ if(DEFINED ENV{ZEPHYR_FLASH_OVER_DFU})
DFUUTIL_IMG
)
else()
set(FLASH_SCRIPT openocd.sh)
set(BOARD_FLASH_RUNNER openocd)
endif()
set(DEBUG_SCRIPT openocd.sh)
set(BOARD_DEBUG_RUNNER openocd)
set(OPENOCD_PRE_CMD "targets 1")
set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}")

View file

@ -1,5 +1,5 @@
set(FLASH_SCRIPT arc_debugger.sh)
set(DEBUG_SCRIPT arc_debugger.sh)
set(BOARD_FLASH_RUNNER em-starterkit)
set(BOARD_DEBUG_RUNNER em-starterkit)
set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} ${CONFIG_FLASH_BASE_ADDRESS}")
set(OPENOCD_VERIFY_CMD "verify_image ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} ${CONFIG_FLASH_BASE_ADDRESS}")

View file

@ -1,4 +1,4 @@
set(FLASH_SCRIPT dfuutil.sh)
set(BOARD_FLASH_RUNNER dfu-util)
set(DFUUTIL_PID 0483:df11)
set(DFUUTIL_ALT 0)

View file

@ -1,5 +1,5 @@
set(FLASH_SCRIPT pyocd.sh)
set(DEBUG_SCRIPT pyocd.sh)
set(BOARD_FLASH_RUNNER pyocd)
set(BOARD_DEBUG_RUNNER pyocd)
set(PYOCD_TARGET nrf52)

View file

@ -1,5 +1,5 @@
if(DEFINED ENV{ZEPHYR_FLASH_OVER_DFU})
set(FLASH_SCRIPT dfuutil.sh)
set(BOARD_FLASH_RUNNER dfu-util)
set(DFUUTIL_PID 8087:0aba)
set(DFUUTIL_ALT ble_core)

View file

@ -1 +1 @@
set(FLASH_SCRIPT bossa-flash.sh)
set(BOARD_FLASH_RUNNER bossac)

View file

@ -1,5 +1,5 @@
set(FLASH_SCRIPT pyocd.sh)
set(DEBUG_SCRIPT pyocd.sh)
set(BOARD_FLASH_RUNNER pyocd)
set(BOARD_DEBUG_RUNNER pyocd)
set(PYOCD_TARGET nrf51)

View file

@ -1,10 +1,10 @@
set_ifndef(OPENSDA_FW daplink)
if(OPENSDA_FW STREQUAL jlink)
set_ifndef(DEBUG_SCRIPT jlink.sh)
set_ifndef(BOARD_DEBUG_RUNNER jlink)
elseif(OPENSDA_FW STREQUAL daplink)
set_ifndef(DEBUG_SCRIPT pyocd.sh)
set_ifndef(FLASH_SCRIPT pyocd.sh)
set_ifndef(BOARD_DEBUG_RUNNER pyocd)
set_ifndef(BOARD_FLASH_RUNNER pyocd)
endif()
set(JLINK_DEVICE MK64FN1M0xxx12)

View file

@ -1,10 +1,10 @@
set_ifndef(OPENSDA_FW daplink)
if(OPENSDA_FW STREQUAL jlink)
set_ifndef(DEBUG_SCRIPT jlink.sh)
set_ifndef(BOARD_DEBUG_RUNNER jlink)
elseif(OPENSDA_FW STREQUAL daplink)
set_ifndef(DEBUG_SCRIPT pyocd.sh)
set_ifndef(FLASH_SCRIPT pyocd.sh)
set_ifndef(BOARD_DEBUG_RUNNER pyocd)
set_ifndef(BOARD_FLASH_RUNNER pyocd)
endif()
set(JLINK_DEVICE MKL25Z128xxx4)

View file

@ -1,10 +1,10 @@
set_ifndef(OPENSDA_FW jlink)
if(OPENSDA_FW STREQUAL jlink)
set_ifndef(DEBUG_SCRIPT jlink.sh)
set_ifndef(BOARD_DEBUG_RUNNER jlink)
elseif(OPENSDA_FW STREQUAL daplink)
set_ifndef(DEBUG_SCRIPT pyocd.sh)
set_ifndef(FLASH_SCRIPT pyocd.sh)
set_ifndef(BOARD_DEBUG_RUNNER pyocd)
set_ifndef(BOARD_FLASH_RUNNER pyocd)
endif()
set(JLINK_DEVICE MKW41Z512xxx4)

View file

@ -1,10 +1,10 @@
set_ifndef(OPENSDA_FW daplink)
if(OPENSDA_FW STREQUAL jlink)
set_ifndef(DEBUG_SCRIPT jlink.sh)
set_ifndef(BOARD_DEBUG_RUNNER jlink)
elseif(OPENSDA_FW STREQUAL daplink)
set_ifndef(DEBUG_SCRIPT pyocd.sh)
set_ifndef(FLASH_SCRIPT pyocd.sh)
set_ifndef(BOARD_DEBUG_RUNNER pyocd)
set_ifndef(BOARD_FLASH_RUNNER pyocd)
endif()
set(JLINK_DEVICE MK64FN1M0xxx12)

View file

@ -1,10 +1,10 @@
set_ifndef(OPENSDA_FW jlink)
if(OPENSDA_FW STREQUAL jlink)
set_ifndef(DEBUG_SCRIPT jlink.sh)
set_ifndef(BOARD_DEBUG_RUNNER jlink)
elseif(OPENSDA_FW STREQUAL daplink)
set_ifndef(DEBUG_SCRIPT pyocd.sh)
set_ifndef(FLASH_SCRIPT pyocd.sh)
set_ifndef(BOARD_DEBUG_RUNNER pyocd)
set_ifndef(BOARD_FLASH_RUNNER pyocd)
endif()
set(JLINK_DEVICE MKW40Z160xxx4)

View file

@ -7,7 +7,7 @@
set_ifndef(OPENSDA_FW jlink)
if(OPENSDA_FW STREQUAL jlink)
set_ifndef(DEBUG_SCRIPT jlink.sh)
set_ifndef(BOARD_DEBUG_RUNNER jlink)
endif()
set(JLINK_DEVICE Cortex-M7)

View file

@ -1,4 +1,4 @@
set(FLASH_SCRIPT nrf_flash.sh)
set(BOARD_FLASH_RUNNER nrfjprog)
set(NRF_FAMILY NRF51)

View file

@ -1,5 +1,5 @@
set(FLASH_SCRIPT pyocd.sh)
set(DEBUG_SCRIPT pyocd.sh)
set(BOARD_FLASH_RUNNER pyocd)
set(BOARD_DEBUG_RUNNER pyocd)
set(PYOCD_TARGET nrf51)

View file

@ -1,4 +1,4 @@
set(FLASH_SCRIPT nrf_flash.sh)
set(BOARD_FLASH_RUNNER nrfjprog)
set(NRF_FAMILY NRF52)
set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS

View file

@ -1,5 +1,5 @@
set(FLASH_SCRIPT pyocd.sh)
set(DEBUG_SCRIPT pyocd.sh)
set(BOARD_FLASH_RUNNER pyocd)
set(BOARD_DEBUG_RUNNER pyocd)
set(PYOCD_TARGET nrf52)

View file

@ -1,4 +1,4 @@
set(FLASH_SCRIPT nrf_flash.sh)
set(BOARD_FLASH_RUNNER nrfjprog)
set(NRF_FAMILY NRF52)

View file

@ -1,5 +1,5 @@
set(FLASH_SCRIPT pyocd.sh)
set(DEBUG_SCRIPT pyocd.sh)
set(BOARD_FLASH_RUNNER pyocd)
set(BOARD_DEBUG_RUNNER pyocd)
set(PYOCD_TARGET nrf52)

View file

@ -8,4 +8,4 @@ set(QEMU_FLAGS_${ARCH}
-vga none
)
set(DEBUG_SCRIPT qemu.sh)
set(BOARD_DEBUG_RUNNER qemu)

View file

@ -1,4 +1,4 @@
set(DEBUG_SCRIPT jlink.sh)
set(BOARD_DEBUG_RUNNER jlink)
set(JLINK_DEVICE MKW24D512xxx5)

View file

@ -1 +1 @@
set(DEBUG_SCRIPT openocd.sh)
set(BOARD_DEBUG_RUNNER openocd)

View file

@ -1,5 +1,5 @@
set(FLASH_SCRIPT openocd.sh)
set(DEBUG_SCRIPT openocd.sh)
set(BOARD_FLASH_RUNNER openocd)
set(BOARD_DEBUG_RUNNER openocd)
set(OPENOCD_LOAD_CMD "flash write_image erase ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}")
set(OPENOCD_VERIFY_CMD "verify_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}")

View file

@ -1,4 +1,4 @@
set(FLASH_SCRIPT nios2.sh)
set(DEBUG_SCRIPT nios2.sh)
set(BOARD_FLASH_RUNNER nios2)
set(BOARD_DEBUG_RUNNER nios2)
set(NIOS2_CPU_SOF $ENV{ZEPHYR_BASE}/arch/nios2/soc/nios2f-zephyr/cpu/ghrd_10m50da.sof)
set_property(GLOBAL APPEND PROPERTY FLASH_SCRIPT_ENV_VARS NIOS2_CPU_SOF)

View file

@ -7,4 +7,4 @@ set(QEMU_FLAGS_${ARCH}
-nographic
)
set(DEBUG_SCRIPT qemu.sh)
set(BOARD_DEBUG_RUNNER qemu)

View file

@ -8,4 +8,4 @@ set(QEMU_FLAGS_${ARCH}
-machine sifive
)
set(DEBUG_SCRIPT qemu.sh)
set(BOARD_DEBUG_RUNNER qemu)

View file

@ -1,5 +1,5 @@
if(DEFINED ENV{ZEPHYR_FLASH_OVER_DFU})
set(FLASH_SCRIPT dfuutil.sh)
set(BOARD_FLASH_RUNNER dfu-util)
set(DFUUTIL_PID 8087:0aba)
set(DFUUTIL_ALT x86_app)
@ -11,10 +11,10 @@ if(DEFINED ENV{ZEPHYR_FLASH_OVER_DFU})
DFUUTIL_IMG
)
else()
set(FLASH_SCRIPT openocd.sh)
set(BOARD_FLASH_RUNNER openocd)
endif()
set(DEBUG_SCRIPT openocd.sh)
set(BOARD_DEBUG_RUNNER openocd)
set(OPENOCD_PRE_CMD "targets 1")
set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}")

View file

@ -1,5 +1,5 @@
set(FLASH_SCRIPT openocd.sh)
set(DEBUG_SCRIPT openocd.sh)
set(BOARD_FLASH_RUNNER openocd)
set(BOARD_DEBUG_RUNNER openocd)
set(OPENOCD_PRE_CMD "targets 1")
set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_PHYS_LOAD_ADDR}")

View file

@ -23,6 +23,6 @@ set(QEMU_FLAGS_${ARCH}
)
# TODO: Support debug
# set(DEBUG_SCRIPT qemu.sh)
# set(BOARD_DEBUG_RUNNER qemu)
# debugserver: QEMU_EXTRA_FLAGS += -s -S
# debugserver: qemu

View file

@ -1,5 +1,5 @@
if(DEFINED ENV{ZEPHYR_FLASH_OVER_DFU})
set(FLASH_SCRIPT dfuutil.sh)
set(BOARD_FLASH_RUNNER dfu-util)
set(DFUUTIL_PID 8087:0aba)
set(DFUUTIL_ALT x86_app)
@ -11,10 +11,10 @@ if(DEFINED ENV{ZEPHYR_FLASH_OVER_DFU})
DFUUTIL_IMG
)
else()
set(FLASH_SCRIPT openocd.sh)
set(BOARD_FLASH_RUNNER openocd)
endif()
set(DEBUG_SCRIPT openocd.sh)
set(BOARD_DEBUG_RUNNER openocd)
set(OPENOCD_PRE_CMD "targets 1")
set(OPENOCD_LOAD_CMD "load_image ${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}")

View file

@ -35,6 +35,6 @@ set(QEMU_FLAGS_${ARCH}
)
# TODO: Support debug
# set(DEBUG_SCRIPT qemu.sh)
# set(BOARD_DEBUG_RUNNER qemu)
# debugserver: QEMU_EXTRA_FLAGS += -s -S
# debugserver: qemu

View file

@ -1 +1 @@
set(FLASH_SCRIPT esp32.sh)
set(BOARD_FLASH_RUNNER esp32)

View file

@ -7,6 +7,6 @@ set(QEMU_FLAGS_${ARCH}
)
# TODO: Support debug
# set(DEBUG_SCRIPT qemu.sh)
# set(BOARD_DEBUG_RUNNER qemu)
# debugserver: QEMU_EXTRA_FLAGS += -s -S
# debugserver: qemu

View file

@ -1 +1 @@
set(DEBUG_SCRIPT xt-gdb.sh)
set(BOARD_DEBUG_RUNNER xtensa)

View file

@ -246,7 +246,7 @@ May include isr_tables.c etc."
set_property(GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES "")
define_property(GLOBAL PROPERTY FLASH_SCRIPT_ENV_VARS
BRIEF_DOCS "Environment variables that should be passed to FLASH_SCRIPT"
FULL_DOCS "Environment variables that should be passed to FLASH_SCRIPT"
BRIEF_DOCS "Environment variables to pass to the flash/debug script"
FULL_DOCS "Environment variables to pass to the flash/debug script"
)
set_property(GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES "")

View file

@ -1,3 +1,6 @@
assert_not(FLASH_SCRIPT "FLASH_SCRIPT has been removed; use BOARD_FLASH_RUNNER")
assert_not(DEBUG_SCRIPT "DEBUG_SCRIPT has been removed; use BOARD_DEBUG_RUNNER")
get_property(ENV_VARS GLOBAL PROPERTY FLASH_SCRIPT_ENV_VARS)
set(ENV_VARS_FORMATTED "")
@ -21,13 +24,13 @@ list(APPEND ENV_VARS_FORMATTED
foreach(target flash debug debugserver)
if(target STREQUAL flash)
set(comment "Flashing ${BOARD}")
set(script ${FLASH_SCRIPT})
set(runner ${BOARD_FLASH_RUNNER})
elseif(target STREQUAL debug)
set(comment "Debugging ${BOARD}")
set(script ${DEBUG_SCRIPT})
set(runner ${BOARD_DEBUG_RUNNER})
elseif(target STREQUAL debugserver)
set(comment "Debugging ${BOARD}")
set(script ${DEBUG_SCRIPT})
set(runner ${BOARD_DEBUG_RUNNER})
if(EMU_PLATFORM)
# cmake/qemu/CMakeLists.txt will add a debugserver target for
# emulation platforms, so we don't add one here
@ -35,14 +38,14 @@ foreach(target flash debug debugserver)
endif()
endif()
if(script)
if(runner)
set(cmd
${CMAKE_COMMAND} -E env
${ENV_VARS_FORMATTED}
${PYTHON_EXECUTABLE}
$ENV{ZEPHYR_BASE}/scripts/support/zephyr_flash_debug.py
${runner}
${target}
${script}
DEPENDS ${logical_target_for_zephyr_elf}
WORKING_DIRECTORY ${APPLICATION_BINARY_DIR}
)

View file

@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: Apache-2.0
'''ARC architecture-specific runner.'''
'''ARC architecture-specific runners.'''
from os import path
import os
@ -15,7 +15,7 @@ DEFAULT_ARC_TELNET_PORT = 4444
DEFAULT_ARC_GDB_PORT = 3333
class ArcBinaryRunner(ZephyrBinaryRunner):
class EmStarterKitBinaryRunner(ZephyrBinaryRunner):
'''Runner front-end for the EM Starterkit board, using openocd.'''
# This unusual 'flash' implementation matches the original shell script.
@ -31,7 +31,7 @@ class ArcBinaryRunner(ZephyrBinaryRunner):
tui=None, tcl_port=DEFAULT_ARC_TCL_PORT,
telnet_port=DEFAULT_ARC_TELNET_PORT,
gdb_port=DEFAULT_ARC_GDB_PORT, debug=False):
super(ArcBinaryRunner, self).__init__(debug=debug)
super(EmStarterKitBinaryRunner, self).__init__(debug=debug)
self.elf = elf
self.zephyr_base = zephyr_base
self.board_dir = board_dir
@ -46,9 +46,9 @@ class ArcBinaryRunner(ZephyrBinaryRunner):
self.telnet_port = telnet_port
self.gdb_port = gdb_port
def replaces_shell_script(shell_script, command):
return (command in {'flash', 'debug', 'debugserver'} and
shell_script == 'arc_debugger.sh')
@classmethod
def name(cls):
return 'em-starterkit'
def create_from_env(command, debug):
'''Create runner from environment.
@ -90,11 +90,12 @@ class ArcBinaryRunner(ZephyrBinaryRunner):
gdb_port = int(os.environ.get('GDB_PORT',
str(DEFAULT_ARC_GDB_PORT)))
return ArcBinaryRunner(elf, zephyr_base, board_dir,
gdb, openocd=openocd, extra_init=extra_init,
default_path=default_path, tui=tui,
tcl_port=tcl_port, telnet_port=telnet_port,
gdb_port=gdb_port, debug=debug)
return EmStarterKitBinaryRunner(
elf, zephyr_base, board_dir,
gdb, openocd=openocd, extra_init=extra_init,
default_path=default_path, tui=tui,
tcl_port=tcl_port, telnet_port=telnet_port,
gdb_port=gdb_port, debug=debug)
def do_run(self, command, **kwargs):
if command not in {'flash', 'debug', 'debugserver'}:

View file

@ -23,8 +23,13 @@ class BossacBinaryRunner(ZephyrBinaryRunner):
self.bossac = bossac
self.port = port
def replaces_shell_script(shell_script, command):
return command == 'flash' and shell_script == 'bossa-flash.sh'
@classmethod
def name(cls):
return 'bossac'
@classmethod
def handles_command(cls, command):
return command == 'flash'
def create_from_env(command, debug):
'''Create flasher from environment.
@ -47,9 +52,6 @@ class BossacBinaryRunner(ZephyrBinaryRunner):
debug=debug)
def do_run(self, command, **kwargs):
if command != 'flash':
raise ValueError('only flash is supported')
if platform.system() != 'Linux':
msg = 'CAUTION: No flash tool for your host system found!'
raise NotImplementedError(msg)

View file

@ -1,6 +1,7 @@
#! /usr/bin/env python3
# Copyright (c) 2017 Linaro Limited.
# Copyright (c) 2017 Open Source Foundries Limited.
#
# SPDX-License-Identifier: Apache-2.0
@ -145,12 +146,16 @@ class NetworkPortHelper:
class ZephyrBinaryRunner(abc.ABC):
'''Abstract superclass for binary runners (flashers, debuggers).
**Note**: these APIs are still evolving, and will change!
With some exceptions, boards supported by Zephyr must provide
generic means to be flashed (have a Zephyr firmware binary
permanently installed on the device for running) and debugged
(have a breakpoint debugger and program loader on a host
workstation attached to a running target). This is supported by
three top-level commands managed by the Zephyr build system:
workstation attached to a running target).
This is supported by three top-level commands managed by the
Zephyr build system:
- 'flash': flash a previously configured binary to the board,
start execution on the target, then return.
@ -164,71 +169,103 @@ class ZephyrBinaryRunner(abc.ABC):
connect to a debug server with symbol tables loaded from the
binary.
Runner functionality relies on a variety of target-specific tools
and configuration values, the user interface to which is
abstracted by this class. Each runner subclass should take any
values it needs to execute one of these commands in its
constructor. The actual command execution is handled in the run()
method.
This class provides an API for these commands. Every runner has a
name, and declares commands it can handle. Zephyr boards declare
compatible runner(s) by name to the build system, which can then
call into the create_runner() method below to make a concrete
runner instance for use executing a command.
This functionality has replaced the legacy Zephyr runners,
which were shell scripts.
If your board can use an existing runner, all you have to do is
give its name to the build system. How to do that is out of the
scope of this documentation, but use the existing boards as a
starting point.
At present, the Zephyr build system uses a variety of
tool-specific environment variables to control runner behavior.
To support a transition to ZephyrBinaryRunner and subclasses, this
class provides a create_for_shell_script() static factory method.
This method iterates over ZephyrBinaryRunner subclasses,
determines which (if any) can provide equivalent functionality to
the old shell-based runner, and returns a subclass instance with its
configuration determined from the environment.
If you want to define and use your own runner:
To support this, subclasess currently must provide a pair of
static methods, replaces_shell_script() and create_from_env(). The
first allows the runner subclass to declare which commands and
scripts it can replace. The second is called by
create_for_shell_script() to create a concrete runner instance.
1. Define a ZephyrBinaryRunner subclass, and implement its
abstract methods. Override any methods you need to, especially
handles_command().
2. Make sure the Python module defining your runner class is
imported by this package's __init__.py (otherwise,
create_runner() won't work).
3. Give your runner's name to the Zephyr build system in your
board's build files.
Runners use a variety of target-specific tools and configuration
values, the user interface to which is abstracted by this
class. Each runner subclass should take any values it needs to
execute one of these commands in its constructor. The actual
command execution is handled in the run() method.
At present, the Zephyr build system uses environment variables to
control runner behavior. To support this, a create_runner()
method is defined below. This method takes a runner name, and
iterates over defined ZephyrBinaryRunner subclasses to find the
runner class. It then checks that it supports the command, then
instantiates and returns a runner with configuration determined by
the environment.
To support this, subclasses currently must define a static method:
create_from_env(). This is called by create_runner() to create a
concrete runner instance.
The environment-based factories are for legacy use *only*; the
build system is moving away from use of environment variables. The
user must be able to construct and use a runner using only the
constructor and run() method.'''
constructor and run() method.
'''
def __init__(self, debug=False):
self.debug = debug
@staticmethod
def create_for_shell_script(shell_script, command, debug):
'''Factory for using as a drop-in replacement to a shell script.
def create_runner(runner_name, command, debug):
for cls in ZephyrBinaryRunner.__subclasses__():
if cls.name() == runner_name:
break
else:
raise ValueError('no runner named {} is known'.format(runner_name))
Command is one of 'flash', 'debug', 'debugserver'.
if not cls.handles_command(command):
raise ValueError('runner {} does not implement command {}'.format(
runner_name, command))
Get runner instance to use in place of shell_script, deriving
configuration from the environment.'''
for sub_cls in ZephyrBinaryRunner.__subclasses__():
if sub_cls.replaces_shell_script(shell_script, command):
return sub_cls.create_from_env(command, debug)
raise ValueError('cannot implement script {} command {}'.format(
shell_script, command))
return cls.create_from_env(command, debug)
@staticmethod
@classmethod
@abc.abstractmethod
def replaces_shell_script(shell_script, command):
'''Check if this class replaces shell_script for the given command.'''
def name(cls):
'''Return this runner's user-visible name.
When choosing a name, pick something short and lowercase,
based on the name of the tool (like openocd, jlink, etc.) or
the target architecture/board (like xtensa, em-starterkit,
etc.).'''
@classmethod
def handles_command(cls, command):
'''Return True iff this class can run the given command.
The default implementation returns True if the command is
valid (i.e. is one of "flash", "debug", and "debugserver").
Subclasses should override if they only provide a subset.'''
return command in {'flash', 'debug', 'debugserver'}
@staticmethod
@abc.abstractmethod
def create_from_env(command, debug):
'''Create new flasher instance from environment variables.
This class must be able to replace the current shell script
(FLASH_SCRIPT or DEBUG_SCRIPT, depending on command). The
environment variables expected by that script are used to build
the flasher in a backwards-compatible manner.'''
'''Create new runner instance from environment variables.'''
def run(self, command, **kwargs):
'''Runs command ('flash', 'debug', 'debugserver').
This is the main entry point to this runner.'''
if not self.handles_command(command):
raise ValueError('runner {} does not implement command {}'.format(
self.name(), command))
self.do_run(command, **kwargs)
@abc.abstractmethod

View file

@ -25,8 +25,13 @@ class DfuUtilBinaryRunner(ZephyrBinaryRunner):
except ValueError:
self.list_pattern = ', name="{}",'.format(self.alt)
def replaces_shell_script(shell_script, command):
return command == 'flash' and shell_script == 'dfuutil.sh'
@classmethod
def name(cls):
return 'dfu-util'
@classmethod
def handles_command(cls, command):
return command == 'flash'
def create_from_env(command, debug):
'''Create flasher from environment.
@ -59,9 +64,6 @@ class DfuUtilBinaryRunner(ZephyrBinaryRunner):
return self.list_pattern in output
def do_run(self, command, **kwargs):
if command != 'flash':
raise ValueError('only flash is supported')
reset = 0
if not self.find_device():
reset = 1

View file

@ -25,8 +25,13 @@ class Esp32BinaryRunner(ZephyrBinaryRunner):
self.flash_mode = flash_mode
self.espidf = espidf
def replaces_shell_script(shell_script, command):
return command == 'flash' and shell_script == 'esp32.sh'
@classmethod
def name(cls):
return 'esp32'
@classmethod
def handles_command(cls, command):
return command == 'flash'
def create_from_env(command, debug):
'''Create flasher from environment.
@ -68,9 +73,6 @@ class Esp32BinaryRunner(ZephyrBinaryRunner):
debug=debug)
def do_run(self, command, **kwargs):
if command != 'flash':
raise ValueError('only flash is supported')
bin_name = path.splitext(self.elf)[0] + path.extsep + 'bin'
cmd_convert = [self.espidf, '--chip', 'esp32', 'elf2image', self.elf]
cmd_flash = [self.espidf, '--chip', 'esp32', '--port', self.device,

View file

@ -28,9 +28,13 @@ class JLinkBinaryRunner(ZephyrBinaryRunner):
self.gdb_port = gdb_port
self.tui_arg = [tui] if tui is not None else []
def replaces_shell_script(shell_script, command):
return (command in {'debug', 'debugserver'} and
shell_script == 'jlink.sh')
@classmethod
def name(cls):
return 'jlink'
@classmethod
def handles_command(cls, command):
return command in {'debug', 'debugserver'}
def create_from_env(command, debug):
'''Create runner from environment.
@ -80,9 +84,6 @@ class JLinkBinaryRunner(ZephyrBinaryRunner):
print('JLink GDB server running on port {}'.format(self.gdb_port))
def do_run(self, command, **kwargs):
if command not in {'debug', 'debugserver'}:
raise ValueError('{} is not supported'.format(command))
server_cmd = (self.gdbserver_cmd +
['-port', str(self.gdb_port),
'-if', self.iface,

View file

@ -29,9 +29,9 @@ class Nios2BinaryRunner(ZephyrBinaryRunner):
self.gdb_cmd = [gdb] if gdb is not None else None
self.tui_arg = [tui] if tui is not None else []
def replaces_shell_script(shell_script, command):
return (command in {'flash', 'debug', 'debugserver'} and
shell_script == 'nios2.sh')
@classmethod
def name(cls):
return 'nios2'
def create_from_env(command, debug):
'''Create runner from environment.
@ -77,9 +77,6 @@ class Nios2BinaryRunner(ZephyrBinaryRunner):
gdb=gdb, tui=tui, debug=debug)
def do_run(self, command, **kwargs):
if command not in {'flash', 'debug', 'debugserver'}:
raise ValueError('{} is not supported'.format(command))
if command == 'flash':
self.flash(**kwargs)
else:

View file

@ -18,8 +18,13 @@ class NrfJprogBinaryRunner(ZephyrBinaryRunner):
self.hex_ = hex_
self.family = family
def replaces_shell_script(shell_script, command):
return command == 'flash' and shell_script == 'nrf_flash.sh'
@classmethod
def name(cls):
return 'nrfjprog'
@classmethod
def handles_command(cls, command):
return command == 'flash'
def create_from_env(command, debug):
'''Create flasher from environment.
@ -61,9 +66,6 @@ class NrfJprogBinaryRunner(ZephyrBinaryRunner):
return snrs[value - 1]
def do_run(self, command, **kwargs):
if command != 'flash':
raise ValueError('only flash is supported')
board_snr = self.get_board_snr_from_user()
print('Flashing file: {}'.format(self.hex_))

View file

@ -47,9 +47,9 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner):
self.gdb_cmd = [gdb] if gdb is not None else None
self.tui_arg = [tui] if tui is not None else []
def replaces_shell_script(shell_script, command):
return (command in {'flash', 'debug', 'debugserver'} and
shell_script == 'openocd.sh')
@classmethod
def name(cls):
return 'openocd'
def create_from_env(command, debug):
'''Create runner from environment.
@ -135,9 +135,6 @@ class OpenOcdBinaryRunner(ZephyrBinaryRunner):
gdb=gdb, tui=tui, debug=debug)
def do_run(self, command, **kwargs):
if command not in {'flash', 'debug', 'debugserver'}:
raise ValueError('{} is not supported'.format(command))
if command == 'flash':
self.do_flash(**kwargs)
elif command == 'debug':

View file

@ -41,9 +41,9 @@ class PyOcdBinaryRunner(ZephyrBinaryRunner):
daparg_args = ['-da', daparg]
self.daparg_args = daparg_args
def replaces_shell_script(shell_script, command):
return (command in {'flash', 'debug', 'debugserver'} and
shell_script == 'pyocd.sh')
@classmethod
def name(cls):
return 'pyocd'
def port_args(self):
return ['-p', str(self.gdb_port)]
@ -108,9 +108,6 @@ class PyOcdBinaryRunner(ZephyrBinaryRunner):
board_id=board_id, daparg=daparg, debug=debug)
def do_run(self, command, **kwargs):
if command not in {'flash', 'debug', 'debugserver'}:
raise ValueError('{} is not supported'.format(command))
if command == 'flash':
self.flash(**kwargs)
else:

View file

@ -13,8 +13,9 @@ class QemuBinaryRunner(ZephyrBinaryRunner):
def __init__(self, debug=False):
super(QemuBinaryRunner, self).__init__(debug=debug)
def replaces_shell_script(shell_script, command):
return shell_script == 'qemu.sh'
@classmethod
def name(cls):
return 'qemu'
def create_from_env(command, debug):
'''Create runner. No environment dependencies.'''

View file

@ -17,8 +17,13 @@ class XtensaBinaryRunner(ZephyrBinaryRunner):
self.gdb_cmd = [gdb]
self.elf_name = elf_name
def replaces_shell_script(shell_script, command):
return command == 'debug' and shell_script == 'xt-gdb.sh'
@classmethod
def name(cls):
return 'xtensa'
@classmethod
def handles_command(cls, command):
return command == 'debug'
def create_from_env(command, debug):
'''Create runner from environment.
@ -36,9 +41,6 @@ class XtensaBinaryRunner(ZephyrBinaryRunner):
return XtensaBinaryRunner(xt_gdb, elf_name)
def do_run(self, command, **kwargs):
if command != 'debug':
raise ValueError('Only debug is supported')
gdb_cmd = (self.gdb_cmd + [self.elf_name])
self.check_call(gdb_cmd)

View file

@ -27,13 +27,12 @@ from runner.core import ZephyrBinaryRunner, get_env_bool_or
# python zephyr_flash_debug.py openocd --openocd-bin=/openocd/path ...
#
# For now, maintain compatibility.
def run(shell_script, command, debug):
def run(runner_name, command, debug):
try:
runner = ZephyrBinaryRunner.create_for_shell_script(shell_script,
command,
debug)
runner = ZephyrBinaryRunner.create_runner(runner_name, command, debug)
except ValueError:
print('Unrecognized shell script {}'.format(shell_script),
print('runner {} is not available or does not support {}'.format(
runner_name, command),
file=sys.stderr)
raise
@ -45,10 +44,10 @@ if __name__ == '__main__':
debug = True
try:
debug = get_env_bool_or('VERBOSE', False)
if len(sys.argv) != 3 or sys.argv[1] not in commands:
raise ValueError('usage: {} <{}> script-name'.format(
if len(sys.argv) != 3 or sys.argv[2] not in commands:
raise ValueError('usage: {} <runner-name> <{}>'.format(
sys.argv[0], '|'.join(commands)))
run(sys.argv[2], sys.argv[1], debug)
run(sys.argv[1], sys.argv[2], debug)
except Exception as e:
if debug:
raise