2017-10-24 12:29:03 -04:00
|
|
|
# Copyright (c) 2017 Linaro Limited.
|
|
|
|
#
|
|
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
|
|
|
'''Runner for flashing with dfu-util.'''
|
|
|
|
|
2017-12-14 16:52:59 -05:00
|
|
|
from collections import namedtuple
|
2017-10-24 12:29:03 -04:00
|
|
|
import sys
|
|
|
|
import time
|
|
|
|
|
2019-01-10 10:13:16 -07:00
|
|
|
from west import log
|
|
|
|
from west.runners.core import ZephyrBinaryRunner, RunnerCaps, \
|
|
|
|
BuildConfiguration
|
2017-12-14 16:52:59 -05:00
|
|
|
|
|
|
|
|
|
|
|
DfuSeConfig = namedtuple('DfuSeConfig', ['address', 'options'])
|
2017-10-24 12:29:03 -04:00
|
|
|
|
|
|
|
|
|
|
|
class DfuUtilBinaryRunner(ZephyrBinaryRunner):
|
|
|
|
'''Runner front-end for dfu-util.'''
|
|
|
|
|
2018-05-10 00:58:03 -04:00
|
|
|
def __init__(self, cfg, pid, alt, img, exe='dfu-util',
|
|
|
|
dfuse_config=None):
|
|
|
|
super(DfuUtilBinaryRunner, self).__init__(cfg)
|
2017-10-24 12:29:03 -04:00
|
|
|
self.alt = alt
|
|
|
|
self.img = img
|
|
|
|
self.cmd = [exe, '-d,{}'.format(pid)]
|
|
|
|
try:
|
|
|
|
self.list_pattern = ', alt={},'.format(int(self.alt))
|
|
|
|
except ValueError:
|
|
|
|
self.list_pattern = ', name="{}",'.format(self.alt)
|
|
|
|
|
2017-12-14 16:52:59 -05:00
|
|
|
if dfuse_config is None:
|
|
|
|
self.dfuse = False
|
|
|
|
else:
|
|
|
|
self.dfuse = True
|
|
|
|
self.dfuse_config = dfuse_config
|
|
|
|
|
2017-11-16 13:32:00 -05:00
|
|
|
@classmethod
|
|
|
|
def name(cls):
|
|
|
|
return 'dfu-util'
|
|
|
|
|
|
|
|
@classmethod
|
2017-11-16 14:31:29 -05:00
|
|
|
def capabilities(cls):
|
2017-12-14 16:52:59 -05:00
|
|
|
return RunnerCaps(commands={'flash'}, flash_addr=True)
|
2017-10-24 12:29:03 -04:00
|
|
|
|
scripts: runner: use arguments, not environment vars
The various runners (flash/debug scripts) use environment variables to
take arguments. This is legacy behavior which is not desirable.
Use command line arguments instead.
Note: this leaves more general environment variables with publicly
documented behavior in place for now, for compatibility, e.g.:
ZEPHYR_FLASH_OVER_DFU, OPENSDA_FW, ESP_IDF_PATH, PYOCD_DAPARG
For example, when using dfu-util to flash arduino_101, instead of
setting DFUUTIL_PID, DFUUTIL_ALT, and DFUUTIL_IMG environment
variables, have the script invocation look like this:
python3 .../zephyr_flash_debug.py dfu-util flash \
[common arguments omitted] \
--pid=8087:0aba --alt=x86_app \
--img=.../build/zephyr/zephyr.bin
Make similar changes for other runners (openocd, etc.) and
targets (debug, debugserver).
To implement this in the scripts:
- have the individual scripts/support/runner/some-runner.py files
register their own command line arguments
- teach them to construct instances from arguments, not the
environment
- have zephyr_flash_debug.py request runners to register command
line argument parsers, and handle arguments
In the build system:
- add a new board_runner_args() extension function that board.cmake
files can use to add to the zephyr_flash_debug.py command line
- adjust cmake/flash/CMakeLists.txt to invoke with arguments
- add new helper include files for each runner (like
boards/common/dfu-util.board.cmake, etc.), which add default
options as needed and then add on overrides from
board_runner_args() calls
- update board.cmake files to use the new includes and extension
This implied some tweaking when using openocd to make the CMake string
escaping and unescaping work properly.
Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
2017-11-16 17:45:38 -05:00
|
|
|
@classmethod
|
|
|
|
def do_add_parser(cls, parser):
|
|
|
|
# Required:
|
|
|
|
parser.add_argument("--pid", required=True,
|
|
|
|
help="USB VID:PID of the board")
|
|
|
|
parser.add_argument("--alt", required=True,
|
|
|
|
help="interface alternate setting number or name")
|
|
|
|
|
|
|
|
# Optional:
|
|
|
|
parser.add_argument("--img",
|
2019-01-10 10:13:16 -07:00
|
|
|
help="binary to flash, default is --bin-file")
|
2017-12-14 16:52:59 -05:00
|
|
|
parser.add_argument("--dfuse", default=False, action='store_true',
|
|
|
|
help='''set if target is a DfuSe device;
|
|
|
|
implies --dt-flash.''')
|
2017-12-14 16:55:45 -05:00
|
|
|
parser.add_argument("--dfuse-modifiers", default='leave',
|
|
|
|
help='''colon-separated list of DfuSe modifiers
|
|
|
|
(default is "leave", which starts execution
|
|
|
|
immediately); --dfuse must also be given for this
|
|
|
|
option to take effect.''')
|
scripts: runner: use arguments, not environment vars
The various runners (flash/debug scripts) use environment variables to
take arguments. This is legacy behavior which is not desirable.
Use command line arguments instead.
Note: this leaves more general environment variables with publicly
documented behavior in place for now, for compatibility, e.g.:
ZEPHYR_FLASH_OVER_DFU, OPENSDA_FW, ESP_IDF_PATH, PYOCD_DAPARG
For example, when using dfu-util to flash arduino_101, instead of
setting DFUUTIL_PID, DFUUTIL_ALT, and DFUUTIL_IMG environment
variables, have the script invocation look like this:
python3 .../zephyr_flash_debug.py dfu-util flash \
[common arguments omitted] \
--pid=8087:0aba --alt=x86_app \
--img=.../build/zephyr/zephyr.bin
Make similar changes for other runners (openocd, etc.) and
targets (debug, debugserver).
To implement this in the scripts:
- have the individual scripts/support/runner/some-runner.py files
register their own command line arguments
- teach them to construct instances from arguments, not the
environment
- have zephyr_flash_debug.py request runners to register command
line argument parsers, and handle arguments
In the build system:
- add a new board_runner_args() extension function that board.cmake
files can use to add to the zephyr_flash_debug.py command line
- adjust cmake/flash/CMakeLists.txt to invoke with arguments
- add new helper include files for each runner (like
boards/common/dfu-util.board.cmake, etc.), which add default
options as needed and then add on overrides from
board_runner_args() calls
- update board.cmake files to use the new includes and extension
This implied some tweaking when using openocd to make the CMake string
escaping and unescaping work properly.
Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
2017-11-16 17:45:38 -05:00
|
|
|
parser.add_argument('--dfu-util', default='dfu-util',
|
|
|
|
help='dfu-util executable; defaults to "dfu-util"')
|
2017-10-24 12:29:03 -04:00
|
|
|
|
scripts: runner: use arguments, not environment vars
The various runners (flash/debug scripts) use environment variables to
take arguments. This is legacy behavior which is not desirable.
Use command line arguments instead.
Note: this leaves more general environment variables with publicly
documented behavior in place for now, for compatibility, e.g.:
ZEPHYR_FLASH_OVER_DFU, OPENSDA_FW, ESP_IDF_PATH, PYOCD_DAPARG
For example, when using dfu-util to flash arduino_101, instead of
setting DFUUTIL_PID, DFUUTIL_ALT, and DFUUTIL_IMG environment
variables, have the script invocation look like this:
python3 .../zephyr_flash_debug.py dfu-util flash \
[common arguments omitted] \
--pid=8087:0aba --alt=x86_app \
--img=.../build/zephyr/zephyr.bin
Make similar changes for other runners (openocd, etc.) and
targets (debug, debugserver).
To implement this in the scripts:
- have the individual scripts/support/runner/some-runner.py files
register their own command line arguments
- teach them to construct instances from arguments, not the
environment
- have zephyr_flash_debug.py request runners to register command
line argument parsers, and handle arguments
In the build system:
- add a new board_runner_args() extension function that board.cmake
files can use to add to the zephyr_flash_debug.py command line
- adjust cmake/flash/CMakeLists.txt to invoke with arguments
- add new helper include files for each runner (like
boards/common/dfu-util.board.cmake, etc.), which add default
options as needed and then add on overrides from
board_runner_args() calls
- update board.cmake files to use the new includes and extension
This implied some tweaking when using openocd to make the CMake string
escaping and unescaping work properly.
Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
2017-11-16 17:45:38 -05:00
|
|
|
@classmethod
|
2018-05-10 00:58:03 -04:00
|
|
|
def create(cls, cfg, args):
|
scripts: runner: use arguments, not environment vars
The various runners (flash/debug scripts) use environment variables to
take arguments. This is legacy behavior which is not desirable.
Use command line arguments instead.
Note: this leaves more general environment variables with publicly
documented behavior in place for now, for compatibility, e.g.:
ZEPHYR_FLASH_OVER_DFU, OPENSDA_FW, ESP_IDF_PATH, PYOCD_DAPARG
For example, when using dfu-util to flash arduino_101, instead of
setting DFUUTIL_PID, DFUUTIL_ALT, and DFUUTIL_IMG environment
variables, have the script invocation look like this:
python3 .../zephyr_flash_debug.py dfu-util flash \
[common arguments omitted] \
--pid=8087:0aba --alt=x86_app \
--img=.../build/zephyr/zephyr.bin
Make similar changes for other runners (openocd, etc.) and
targets (debug, debugserver).
To implement this in the scripts:
- have the individual scripts/support/runner/some-runner.py files
register their own command line arguments
- teach them to construct instances from arguments, not the
environment
- have zephyr_flash_debug.py request runners to register command
line argument parsers, and handle arguments
In the build system:
- add a new board_runner_args() extension function that board.cmake
files can use to add to the zephyr_flash_debug.py command line
- adjust cmake/flash/CMakeLists.txt to invoke with arguments
- add new helper include files for each runner (like
boards/common/dfu-util.board.cmake, etc.), which add default
options as needed and then add on overrides from
board_runner_args() calls
- update board.cmake files to use the new includes and extension
This implied some tweaking when using openocd to make the CMake string
escaping and unescaping work properly.
Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
2017-11-16 17:45:38 -05:00
|
|
|
if args.img is None:
|
2019-01-10 10:13:16 -07:00
|
|
|
args.img = cfg.bin_file
|
2017-12-14 16:52:59 -05:00
|
|
|
|
|
|
|
if args.dfuse:
|
|
|
|
args.dt_flash = True # --dfuse implies --dt-flash.
|
2018-05-10 15:28:17 -04:00
|
|
|
build_conf = BuildConfiguration(cfg.build_dir)
|
2017-12-14 16:52:59 -05:00
|
|
|
dcfg = DfuSeConfig(address=cls.get_flash_address(args, build_conf),
|
2017-12-14 16:55:45 -05:00
|
|
|
options=args.dfuse_modifiers)
|
2017-12-14 16:52:59 -05:00
|
|
|
else:
|
|
|
|
dcfg = None
|
|
|
|
|
2018-05-10 00:58:03 -04:00
|
|
|
return DfuUtilBinaryRunner(cfg, args.pid, args.alt, args.img,
|
|
|
|
exe=args.dfu_util, dfuse_config=dcfg)
|
2017-10-24 12:29:03 -04:00
|
|
|
|
|
|
|
def find_device(self):
|
|
|
|
cmd = list(self.cmd) + ['-l']
|
|
|
|
output = self.check_output(cmd)
|
|
|
|
output = output.decode(sys.getdefaultencoding())
|
|
|
|
return self.list_pattern in output
|
|
|
|
|
2017-11-16 10:41:39 -05:00
|
|
|
def do_run(self, command, **kwargs):
|
2017-12-14 16:52:59 -05:00
|
|
|
reset = False
|
2017-10-24 12:29:03 -04:00
|
|
|
if not self.find_device():
|
2017-12-14 16:52:59 -05:00
|
|
|
reset = True
|
2018-05-09 22:31:28 -04:00
|
|
|
log.dbg('Device not found, waiting for it',
|
|
|
|
level=log.VERBOSE_EXTREME)
|
|
|
|
# Use of print() here is advised. We don't want to lose
|
|
|
|
# this information in a separate log -- this is
|
|
|
|
# interactive and requires a terminal.
|
2017-10-24 12:29:03 -04:00
|
|
|
print('Please reset your board to switch to DFU mode...')
|
|
|
|
while not self.find_device():
|
|
|
|
time.sleep(0.1)
|
|
|
|
|
|
|
|
cmd = list(self.cmd)
|
2017-12-14 16:52:59 -05:00
|
|
|
if self.dfuse:
|
|
|
|
# http://dfu-util.sourceforge.net/dfuse.html
|
|
|
|
dcfg = self.dfuse_config
|
|
|
|
addr_opts = hex(dcfg.address) + ':' + dcfg.options
|
|
|
|
cmd.extend(['-s', addr_opts])
|
2017-10-24 12:29:03 -04:00
|
|
|
cmd.extend(['-a', self.alt, '-D', self.img])
|
|
|
|
self.check_call(cmd)
|
2017-12-14 16:52:59 -05:00
|
|
|
|
|
|
|
if self.dfuse and 'leave' in dcfg.options.split(':'):
|
|
|
|
# Normal DFU devices generally need to be reset to switch
|
|
|
|
# back to the flashed program.
|
|
|
|
#
|
|
|
|
# DfuSe targets do as well, except when 'leave' is given
|
|
|
|
# as an option.
|
|
|
|
reset = False
|
2017-10-24 12:29:03 -04:00
|
|
|
if reset:
|
|
|
|
print('Now reset your board again to switch back to runtime mode.')
|