Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

100 lines
3.4 KiB

# Copyright (c) 2022 Renesas Electronics Corporation
#
# SPDX-License-Identifier: Apache-2.0
'''Runner for flashing with ezFlashCLI.'''
import shlex
from runners.core import RunnerCaps, ZephyrBinaryRunner
DEFAULT_EZFLASHCLI = "ezFlashCLI"
class EzFlashCliBinaryRunner(ZephyrBinaryRunner):
'''Runner front-end for ezFlashCLI'''
def __init__(self, cfg, tool, dev_id=None, tool_opt=None, erase=False, reset=True):
super().__init__(cfg)
self.bin_ = cfg.bin_file
self.tool = tool
self.dev_id = dev_id
self.erase = bool(erase)
self.reset = bool(reset)
self.tool_opt = []
if tool_opt is not None:
for opts in [shlex.split(opt) for opt in tool_opt]:
self.tool_opt += opts
@classmethod
def name(cls):
return 'ezflashcli'
@classmethod
def capabilities(cls):
return RunnerCaps(commands={'flash'}, dev_id=True, tool_opt=True, erase=True, reset=True)
@classmethod
def dev_id_help(cls) -> str:
return '''Device identifier. Use it to select the J-Link Serial Number
of the device connected over USB.'''
@classmethod
def tool_opt_help(cls) -> str:
return "Additional options for ezFlashCLI e.g. '--verbose'"
@classmethod
def do_add_parser(cls, parser):
parser.add_argument('--tool', default=DEFAULT_EZFLASHCLI,
help='ezFlashCLI path, default is '
f'{DEFAULT_EZFLASHCLI}')
parser.set_defaults(reset=True)
@classmethod
def do_create(cls, cfg, args):
return EzFlashCliBinaryRunner(cfg, tool=args.tool, dev_id=args.dev_id,
tool_opt=args.tool_opt, erase=args.erase)
def needs_product_header(self):
# Applications linked to code partition are meant to be run by MCUboot
# and do not require product header. Other applications and MCUboot itself
# are run by internal bootloader and thus require valid product header.
is_mcuboot = self.build_conf.getboolean('CONFIG_MCUBOOT')
uses_code_partition = self.build_conf.getboolean('CONFIG_USE_DT_CODE_PARTITION')
return is_mcuboot or not uses_code_partition
def get_options(self):
device_args = []
if self.dev_id is not None:
device_args = ['-j', f'{self.dev_id}']
return device_args + self.tool_opt
def program_bin(self):
options = self.get_options()
if self.erase:
self.logger.info("Erasing flash...")
self.check_call([self.tool] + options + ["erase_flash"])
self.logger.info(f"Flashing {self.bin_}...")
if self.needs_product_header():
# Write product header and application image at fixed offset as required
# by internal bootloader.
self.check_call([self.tool] + options + ["image_flash", self.bin_])
else:
load_offset = self.build_conf['CONFIG_FLASH_LOAD_OFFSET']
self.check_call([self.tool] + options + ["write_flash", f'0x{load_offset:x}', self.bin_])
def reset_device(self):
self.logger.info("Resetting...")
options = self.get_options()
self.check_call([self.tool] + options + ["go"])
def do_run(self, command, **kwargs):
self.require(self.tool)
self.ensure_output('bin')
self.program_bin()
if self.reset:
self.reset_device()