Some configuration options or device tree nodes affect the way that runners ought to behave, but there's no good way for them to report whether they can handle them. One motivating example is CONFIG_FLASH_LOAD_OFFSET, as influenced by the zephyr,code-partition chosen node in the DT for architectures where CONFIG_HAS_FLASH_LOAD_OFFSET=y. If CONFIG_FLASH_LOAD_OFFSET is nonzero, the 'flash' command ought to place the kernel at that address offset from the device flash's start address. Runners don't support this right now, which should be fixed. However, we don't want to mandate support for this feature, since not all targets need it. We need to let runners declare what their capabilities are. Make it so by adding a RunnerCaps class to the runner core. This currently just states which commands a runner can handle, but can be generalized to implement the above use case. Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
80 lines
2.4 KiB
Python
80 lines
2.4 KiB
Python
# Copyright (c) 2017 Linaro Limited.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
'''Runner for flashing with dfu-util.'''
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
|
|
from .core import ZephyrBinaryRunner, RunnerCaps, get_env_or_bail
|
|
|
|
|
|
class DfuUtilBinaryRunner(ZephyrBinaryRunner):
|
|
'''Runner front-end for dfu-util.'''
|
|
|
|
def __init__(self, pid, alt, img, dfuse=None, exe='dfu-util', 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)
|
|
|
|
@classmethod
|
|
def name(cls):
|
|
return 'dfu-util'
|
|
|
|
@classmethod
|
|
def capabilities(cls):
|
|
return RunnerCaps(commands={'flash'})
|
|
|
|
def create_from_env(command, debug):
|
|
'''Create flasher from environment.
|
|
|
|
Required:
|
|
|
|
- DFUUTIL_PID: USB VID:PID of the board
|
|
- DFUUTIL_ALT: interface alternate setting number or name
|
|
- DFUUTIL_IMG: binary to flash
|
|
|
|
Optional:
|
|
|
|
- DFUUTIL_DFUSE_ADDR: target address if the board is a
|
|
DfuSe device. Ignored if not present.
|
|
- DFUUTIL: dfu-util executable, defaults to dfu-util.
|
|
'''
|
|
pid = get_env_or_bail('DFUUTIL_PID')
|
|
alt = get_env_or_bail('DFUUTIL_ALT')
|
|
img = get_env_or_bail('DFUUTIL_IMG')
|
|
dfuse = os.environ.get('DFUUTIL_DFUSE_ADDR', None)
|
|
exe = os.environ.get('DFUUTIL', 'dfu-util')
|
|
|
|
return DfuUtilBinaryRunner(pid, alt, img, dfuse=dfuse, exe=exe,
|
|
debug=debug)
|
|
|
|
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
|
|
|
|
def do_run(self, command, **kwargs):
|
|
reset = 0
|
|
if not self.find_device():
|
|
reset = 1
|
|
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)])
|
|
cmd.extend(['-a', self.alt, '-D', self.img])
|
|
self.check_call(cmd)
|
|
if reset:
|
|
print('Now reset your board again to switch back to runtime mode.')
|