scripts: runner: dfu-util: support DT-based flashing for DfuSe

Enable DT support in the dfu-util flasher when the target is a
DfuSe (DFU + ST extensions) device.

Untangling DfuSe-specific options (currently, the default is 'leave',
to immediately start running after the flashing is done) from the
actual address makes this cleaner, and sets up a subsequent patch to
let callers set DfuSe options.

It also lets us fix an unnecessary printline when flashing DfuSe
devices. There's no need to reset those, since the 'leave' modifier
starts execution immediately.

Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
This commit is contained in:
Marti Bolivar 2017-12-14 16:52:59 -05:00 committed by Anas Nashif
commit 3ebc2e46b2
2 changed files with 44 additions and 14 deletions

View file

@ -1,4 +1,3 @@
board_runner_args(dfu-util "--pid=0483:df11" "--alt=0")
board_runner_args(dfu-util "--dfuse-addr=${CONFIG_FLASH_BASE_ADDRESS}")
board_runner_args(dfu-util "--pid=0483:df11" "--alt=0" "--dfuse")
include($ENV{ZEPHYR_BASE}/boards/common/dfu-util.board.cmake)

View file

@ -4,33 +4,44 @@
'''Runner for flashing with dfu-util.'''
from collections import namedtuple
import os
import sys
import time
from .core import ZephyrBinaryRunner, RunnerCaps
from .core import ZephyrBinaryRunner, RunnerCaps, BuildConfiguration
DfuSeConfig = namedtuple('DfuSeConfig', ['address', 'options'])
class DfuUtilBinaryRunner(ZephyrBinaryRunner):
'''Runner front-end for dfu-util.'''
def __init__(self, pid, alt, img, dfuse=None, exe='dfu-util', debug=False):
def __init__(self, pid, alt, img, exe='dfu-util',
dfuse_config=None, debug=False):
super(DfuUtilBinaryRunner, self).__init__(debug=debug)
self.alt = alt
self.img = img
self.dfuse = dfuse
self.cmd = [exe, '-d,{}'.format(pid)]
try:
self.list_pattern = ', alt={},'.format(int(self.alt))
except ValueError:
self.list_pattern = ', name="{}",'.format(self.alt)
if dfuse_config is None:
self.dfuse = False
else:
self.dfuse = True
self.dfuse_config = dfuse_config
@classmethod
def name(cls):
return 'dfu-util'
@classmethod
def capabilities(cls):
return RunnerCaps(commands={'flash'})
return RunnerCaps(commands={'flash'}, flash_addr=True)
@classmethod
def do_add_parser(cls, parser):
@ -43,9 +54,9 @@ class DfuUtilBinaryRunner(ZephyrBinaryRunner):
# Optional:
parser.add_argument("--img",
help="binary to flash, default is --kernel-bin")
parser.add_argument("--dfuse-addr", default=None,
help='''target address if the board is a DfuSe
device; ignored it not present''')
parser.add_argument("--dfuse", default=False, action='store_true',
help='''set if target is a DfuSe device;
implies --dt-flash.''')
parser.add_argument('--dfu-util', default='dfu-util',
help='dfu-util executable; defaults to "dfu-util"')
@ -53,8 +64,17 @@ class DfuUtilBinaryRunner(ZephyrBinaryRunner):
def create_from_args(cls, args):
if args.img is None:
args.img = args.kernel_bin
if args.dfuse:
args.dt_flash = True # --dfuse implies --dt-flash.
build_conf = BuildConfiguration(os.getcwd())
dcfg = DfuSeConfig(address=cls.get_flash_address(args, build_conf),
options="leave")
else:
dcfg = None
return DfuUtilBinaryRunner(args.pid, args.alt, args.img,
dfuse=args.dfuse_addr, exe=args.dfu_util,
exe=args.dfu_util, dfuse_config=dcfg,
debug=args.verbose)
def find_device(self):
@ -64,17 +84,28 @@ class DfuUtilBinaryRunner(ZephyrBinaryRunner):
return self.list_pattern in output
def do_run(self, command, **kwargs):
reset = 0
reset = False
if not self.find_device():
reset = 1
reset = True
print('Please reset your board to switch to DFU mode...')
while not self.find_device():
time.sleep(0.1)
cmd = list(self.cmd)
if self.dfuse is not None:
cmd.extend(['-s', '{}:leave'.format(self.dfuse)])
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])
cmd.extend(['-a', self.alt, '-D', self.img])
self.check_call(cmd)
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
if reset:
print('Now reset your board again to switch back to runtime mode.')